Reset // Bind SCPC Mode to Pref in lieu of IME Instance Mode.

- Names of Lang Models and Input Modes are also fixed in this commit.
This commit is contained in:
ShikiSuen 2022-02-06 20:14:58 +08:00
parent aadc4c25e9
commit e6e48bda7e
6 changed files with 69 additions and 77 deletions

View File

@ -7,8 +7,8 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
typedef NSString *const InputMode NS_TYPED_ENUM; typedef NSString *const InputMode NS_TYPED_ENUM;
extern InputMode InputModeBopomofo; extern InputMode imeModeCHT;
extern InputMode InputModePlainBopomofo; extern InputMode imeModeCHS;
@class KeyHandler; @class KeyHandler;

View File

@ -14,8 +14,8 @@ using namespace Taiyan::Mandarin;
using namespace Taiyan::Gramambular; using namespace Taiyan::Gramambular;
using namespace vChewing; using namespace vChewing;
InputMode InputModeBopomofo = @"org.atelierInmu.inputmethod.vChewing.IMECHT"; InputMode imeModeCHT = @"org.atelierInmu.inputmethod.vChewing.IMECHT";
InputMode InputModePlainBopomofo = @"org.atelierInmu.inputmethod.vChewing.IMECHS"; InputMode imeModeCHS = @"org.atelierInmu.inputmethod.vChewing.IMECHS";
static const double kEpsilon = 0.000001; static const double kEpsilon = 0.000001;
@ -79,13 +79,13 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
NSString *newInputMode; NSString *newInputMode;
vChewingLM *newLanguageModel; vChewingLM *newLanguageModel;
if ([value isKindOfClass:[NSString class]] && [value isEqual:InputModePlainBopomofo]) { if ([value isKindOfClass:[NSString class]] && [value isEqual:imeModeCHS]) {
newInputMode = InputModePlainBopomofo; newInputMode = imeModeCHS;
newLanguageModel = [mgrLangModel languageModelPlainBopomofo]; newLanguageModel = [mgrLangModel lmCHS];
newLanguageModel->setPhraseReplacementEnabled(false); newLanguageModel->setPhraseReplacementEnabled(false);
} else { } else {
newInputMode = InputModeBopomofo; newInputMode = imeModeCHT;
newLanguageModel = [mgrLangModel languageModelvChewing]; newLanguageModel = [mgrLangModel lmCHT];
newLanguageModel->setPhraseReplacementEnabled(Preferences.phraseReplacementEnabled); newLanguageModel->setPhraseReplacementEnabled(Preferences.phraseReplacementEnabled);
} }
@ -125,7 +125,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
_bpmfReadingBuffer = new BopomofoReadingBuffer(BopomofoKeyboardLayout::StandardLayout()); _bpmfReadingBuffer = new BopomofoReadingBuffer(BopomofoKeyboardLayout::StandardLayout());
// create the lattice builder // create the lattice builder
_languageModel = [mgrLangModel languageModelvChewing]; _languageModel = [mgrLangModel lmCHT];
_languageModel->setPhraseReplacementEnabled(Preferences.phraseReplacementEnabled); _languageModel->setPhraseReplacementEnabled(Preferences.phraseReplacementEnabled);
_userOverrideModel = [mgrLangModel userOverrideModel]; _userOverrideModel = [mgrLangModel userOverrideModel];
@ -133,7 +133,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
// each Mandarin syllable is separated by a hyphen // each Mandarin syllable is separated by a hyphen
_builder->setJoinSeparator("-"); _builder->setJoinSeparator("-");
_inputMode = InputModeBopomofo; _inputMode = imeModeCHT;
} }
return self; return self;
} }
@ -171,7 +171,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
size_t cursorIndex = [self _actualCandidateCursorIndex]; size_t cursorIndex = [self _actualCandidateCursorIndex];
string stringValue = [value UTF8String]; string stringValue = [value UTF8String];
_builder->grid().fixNodeSelectedCandidate(cursorIndex, stringValue); _builder->grid().fixNodeSelectedCandidate(cursorIndex, stringValue);
if (_inputMode != InputModePlainBopomofo) { if (_inputMode != imeModeCHS) {
_userOverrideModel->observe(_walkedNodes, cursorIndex, stringValue, [[NSDate date] timeIntervalSince1970]); _userOverrideModel->observe(_walkedNodes, cursorIndex, stringValue, [[NSDate date] timeIntervalSince1970]);
} }
[self _walk]; [self _walk];
@ -329,7 +329,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
NSString *poppedText = [self _popOverflowComposingTextAndWalk]; NSString *poppedText = [self _popOverflowComposingTextAndWalk];
// get user override model suggestion // get user override model suggestion
string overrideValue = (_inputMode == InputModePlainBopomofo) ? "" : string overrideValue = (Preferences.useSCPCTypingMode) ? "" :
_userOverrideModel->suggest(_walkedNodes, _builder->cursorIndex(), [[NSDate date] timeIntervalSince1970]); _userOverrideModel->suggest(_walkedNodes, _builder->cursorIndex(), [[NSDate date] timeIntervalSince1970]);
if (!overrideValue.empty()) { if (!overrideValue.empty()) {
@ -346,7 +346,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
inputting.poppedText = poppedText; inputting.poppedText = poppedText;
stateCallback(inputting); stateCallback(inputting);
if (_inputMode == InputModePlainBopomofo) { if (Preferences.useSCPCTypingMode) {
InputStateChoosingCandidate *choosingCandidates = [self _buildCandidateState:inputting useVerticalMode:input.useVerticalMode]; InputStateChoosingCandidate *choosingCandidates = [self _buildCandidateState:inputting useVerticalMode:input.useVerticalMode];
if (choosingCandidates.candidates.count == 1) { if (choosingCandidates.candidates.count == 1) {
[self clear]; [self clear];
@ -759,16 +759,6 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
return NO; return NO;
} }
// Actually the lines would not be reached. When there is BMPF reading and
// a user input enter, we just send the readings to the client app.
// if (_inputMode == InputModePlainBopomofo) {
// if (!_bpmfReadingBuffer->isEmpty()) {
// errorCallback();
// }
// return YES;
// }
[self clear]; [self clear];
InputStateInputting *current = (InputStateInputting *) state; InputStateInputting *current = (InputStateInputting *) state;
@ -800,7 +790,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
inputting.poppedText = poppedText; inputting.poppedText = poppedText;
stateCallback(inputting); stateCallback(inputting);
if (_inputMode == InputModePlainBopomofo && _bpmfReadingBuffer->isEmpty()) { if (Preferences.useSCPCTypingMode && _bpmfReadingBuffer->isEmpty()) {
InputStateChoosingCandidate *candidateState = [self _buildCandidateState:inputting useVerticalMode:useVerticalMode]; InputStateChoosingCandidate *candidateState = [self _buildCandidateState:inputting useVerticalMode:useVerticalMode];
if ([candidateState.candidates count] == 1) { if ([candidateState.candidates count] == 1) {
@ -904,7 +894,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
InputStateEmptyIgnoringPreviousState *empty = [[InputStateEmptyIgnoringPreviousState alloc] init]; InputStateEmptyIgnoringPreviousState *empty = [[InputStateEmptyIgnoringPreviousState alloc] init];
stateCallback(empty); stateCallback(empty);
} }
else if (_inputMode == InputModePlainBopomofo) { else if (Preferences.useSCPCTypingMode) {
[self clear]; [self clear];
InputStateEmptyIgnoringPreviousState *empty = [[InputStateEmptyIgnoringPreviousState alloc] init]; InputStateEmptyIgnoringPreviousState *empty = [[InputStateEmptyIgnoringPreviousState alloc] init];
stateCallback(empty); stateCallback(empty);
@ -1083,7 +1073,7 @@ static NSString *const kGraphVizOutputfile = @"/tmp/vChewing-visualization.dot";
return NO; return NO;
} }
if (_inputMode == InputModePlainBopomofo) { if (Preferences.useSCPCTypingMode) {
string layout = [self _currentLayout]; string layout = [self _currentLayout];
string punctuationNamePrefix; string punctuationNamePrefix;
if ([input isControlHold]) { if ([input isControlHold]) {

View File

@ -35,6 +35,8 @@ class ctlInputMethod: IMKInputController {
} }
override func menu() -> NSMenu! { override func menu() -> NSMenu! {
let optionKeyPressed = NSEvent.modifierFlags.contains(.option)
let menu = NSMenu(title: "Input Method Menu") let menu = NSMenu(title: "Input Method Menu")
menu.addItem(withTitle: NSLocalizedString("vChewing Preferences", comment: ""), action: #selector(showPreferences(_:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("vChewing Preferences", comment: ""), action: #selector(showPreferences(_:)), keyEquivalent: "")
@ -46,15 +48,12 @@ class ctlInputMethod: IMKInputController {
halfWidthPunctuationItem.keyEquivalentModifierMask = [.command, .control] halfWidthPunctuationItem.keyEquivalentModifierMask = [.command, .control]
halfWidthPunctuationItem.state = Preferences.halfWidthPunctuationEnabled.state halfWidthPunctuationItem.state = Preferences.halfWidthPunctuationEnabled.state
let inputMode = keyHandler.inputMode if Preferences.useSCPCTypingMode {
let optionKeyPressed = NSEvent.modifierFlags.contains(.option)
if inputMode == .plainBopomofo {
let associatedPhrasesItem = menu.addItem(withTitle: NSLocalizedString("Associated Phrases", comment: ""), action: #selector(toggleAssociatedPhrasesEnabled(_:)), keyEquivalent: "") let associatedPhrasesItem = menu.addItem(withTitle: NSLocalizedString("Associated Phrases", comment: ""), action: #selector(toggleAssociatedPhrasesEnabled(_:)), keyEquivalent: "")
associatedPhrasesItem.state = Preferences.associatedPhrasesEnabled.state associatedPhrasesItem.state = Preferences.associatedPhrasesEnabled.state
} }
if inputMode == .bopomofo && optionKeyPressed { if keyHandler.inputMode == .imeModeCHT && optionKeyPressed {
let phaseReplacementItem = menu.addItem(withTitle: NSLocalizedString("Use Phrase Replacement", comment: ""), action: #selector(togglePhraseReplacement(_:)), keyEquivalent: "") let phaseReplacementItem = menu.addItem(withTitle: NSLocalizedString("Use Phrase Replacement", comment: ""), action: #selector(togglePhraseReplacement(_:)), keyEquivalent: "")
phaseReplacementItem.state = Preferences.phraseReplacementEnabled.state phaseReplacementItem.state = Preferences.phraseReplacementEnabled.state
} }
@ -62,16 +61,14 @@ class ctlInputMethod: IMKInputController {
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
menu.addItem(withTitle: NSLocalizedString("User Phrases", comment: ""), action: nil, keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("User Phrases", comment: ""), action: nil, keyEquivalent: "")
if inputMode == .plainBopomofo {
menu.addItem(withTitle: NSLocalizedString("Edit Excluded Phrases", comment: ""), action: #selector(openExcludedPhrasesPlainBopomofo(_:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("Edit User Phrases", comment: ""), action: #selector(openUserPhrases(_:)), keyEquivalent: "")
} else { menu.addItem(withTitle: NSLocalizedString("Edit Excluded Phrases", comment: ""), action: #selector(openExcludedPhrases(_:)), keyEquivalent: "")
menu.addItem(withTitle: NSLocalizedString("Edit User Phrases", comment: ""), action: #selector(openUserPhrases(_:)), keyEquivalent: "") if optionKeyPressed {
menu.addItem(withTitle: NSLocalizedString("Edit Excluded Phrases", comment: ""), action: #selector(openExcludedPhrasesvChewing(_:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("Edit Phrase Replacement Table", comment: ""), action: #selector(openPhraseReplacement(_:)), keyEquivalent: "")
if optionKeyPressed {
menu.addItem(withTitle: NSLocalizedString("Edit Phrase Replacement Table", comment: ""), action: #selector(openPhraseReplacementvChewing(_:)), keyEquivalent: "")
}
} }
menu.addItem(withTitle: NSLocalizedString("Reload User Phrases", comment: ""), action: #selector(reloadUserPhrases(_:)), keyEquivalent: "") menu.addItem(withTitle: NSLocalizedString("Reload User Phrases", comment: ""), action: #selector(reloadUserPhrases(_:)), keyEquivalent: "")
menu.addItem(NSMenuItem.separator()) menu.addItem(NSMenuItem.separator())
@ -104,7 +101,7 @@ class ctlInputMethod: IMKInputController {
} }
override func setValue(_ value: Any!, forTag tag: Int, client: Any!) { override func setValue(_ value: Any!, forTag tag: Int, client: Any!) {
let newInputMode = InputMode(rawValue: value as? String ?? InputMode.bopomofo.rawValue) let newInputMode = InputMode(rawValue: value as? String ?? InputMode.imeModeCHT.rawValue)
mgrLangModel.loadDataModel(newInputMode) mgrLangModel.loadDataModel(newInputMode)
if keyHandler.inputMode != newInputMode { if keyHandler.inputMode != newInputMode {
UserDefaults.standard.synchronize() UserDefaults.standard.synchronize()
@ -209,19 +206,15 @@ class ctlInputMethod: IMKInputController {
} }
@objc func openUserPhrases(_ sender: Any?) { @objc func openUserPhrases(_ sender: Any?) {
open(userFileAt: mgrLangModel.userPhrasesDataPathvChewing) open(userFileAt: mgrLangModel.userPhrasesDataPathCHT)
} }
@objc func openExcludedPhrasesPlainBopomofo(_ sender: Any?) { @objc func openExcludedPhrases(_ sender: Any?) {
open(userFileAt: mgrLangModel.excludedPhrasesDataPathPlainBopomofo) open(userFileAt: mgrLangModel.excludedPhrasesDataPathCHT)
} }
@objc func openExcludedPhrasesvChewing(_ sender: Any?) { @objc func openPhraseReplacement(_ sender: Any?) {
open(userFileAt: mgrLangModel.excludedPhrasesDataPathvChewing) open(userFileAt: mgrLangModel.phraseReplacementDataPathCHT)
}
@objc func openPhraseReplacementvChewing(_ sender: Any?) {
open(userFileAt: mgrLangModel.phraseReplacementDataPathvChewing)
} }
@objc func reloadUserPhrases(_ sender: Any?) { @objc func reloadUserPhrases(_ sender: Any?) {
@ -562,7 +555,7 @@ extension ctlInputMethod: CandidateControllerDelegate {
return return
} }
if keyHandler.inputMode == .plainBopomofo { if Preferences.useSCPCTypingMode {
keyHandler.clear() keyHandler.clear()
let composingBuffer = inputting.composingBuffer let composingBuffer = inputting.composingBuffer
handle(state: .Committing(poppedText: composingBuffer), client: client) handle(state: .Committing(poppedText: composingBuffer), client: client)

View File

@ -16,10 +16,12 @@ NS_ASSUME_NONNULL_BEGIN
+ (BOOL)writeUserPhrase:(NSString *)userPhrase; + (BOOL)writeUserPhrase:(NSString *)userPhrase;
@property (class, readonly, nonatomic) NSString *dataFolderPath; @property (class, readonly, nonatomic) NSString *dataFolderPath;
@property (class, readonly, nonatomic) NSString *userPhrasesDataPathvChewing; @property (class, readonly, nonatomic) NSString *userPhrasesDataPathCHT;
@property (class, readonly, nonatomic) NSString *excludedPhrasesDataPathvChewing; @property (class, readonly, nonatomic) NSString *userPhrasesDataPathCHS;
@property (class, readonly, nonatomic) NSString *excludedPhrasesDataPathPlainBopomofo; @property (class, readonly, nonatomic) NSString *excludedPhrasesDataPathCHT;
@property (class, readonly, nonatomic) NSString *phraseReplacementDataPathvChewing; @property (class, readonly, nonatomic) NSString *excludedPhrasesDataPathCHS;
@property (class, readonly, nonatomic) NSString *phraseReplacementDataPathCHT;
@property (class, readonly, nonatomic) NSString *phraseReplacementDataPathCHS;
@property (class, assign, nonatomic) BOOL phraseReplacementEnabled; @property (class, assign, nonatomic) BOOL phraseReplacementEnabled;
@end @end

View File

@ -15,7 +15,6 @@ static UserOverrideModel gUserOverrideModel(kUserOverrideModelCapacity, kObserve
static NSString *const kUserDataTemplateName = @"template-data"; static NSString *const kUserDataTemplateName = @"template-data";
static NSString *const kExcludedPhrasesvChewingTemplateName = @"template-exclude-phrases"; static NSString *const kExcludedPhrasesvChewingTemplateName = @"template-exclude-phrases";
static NSString *const kExcludedPhrasesPlainBopomofoTemplateName = @"template-exclude-phrases-plain-bpmf";
static NSString *const kPhraseReplacementTemplateName = @"template-phrases-replacement"; static NSString *const kPhraseReplacementTemplateName = @"template-phrases-replacement";
static NSString *const kTemplateExtension = @".txt"; static NSString *const kTemplateExtension = @".txt";
@ -50,13 +49,13 @@ static void LTLoadAssociatedPhrases(vChewingLM &lm)
+ (void)loadDataModel:(InputMode)mode + (void)loadDataModel:(InputMode)mode
{ {
if ([mode isEqualToString:InputModeBopomofo]) { if ([mode isEqualToString:imeModeCHT]) {
if (!gLangModelCHT.isDataModelLoaded()) { if (!gLangModelCHT.isDataModelLoaded()) {
LTLoadLanguageModelFile(@"data-cht", gLangModelCHT); LTLoadLanguageModelFile(@"data-cht", gLangModelCHT);
} }
} }
if ([mode isEqualToString:InputModePlainBopomofo]) { if ([mode isEqualToString:imeModeCHS]) {
if (!gLangModelCHS.isDataModelLoaded()) { if (!gLangModelCHS.isDataModelLoaded()) {
LTLoadLanguageModelFile(@"data-chs", gLangModelCHS); LTLoadLanguageModelFile(@"data-chs", gLangModelCHS);
} }
@ -68,13 +67,13 @@ static void LTLoadAssociatedPhrases(vChewingLM &lm)
+ (void)loadUserPhrases + (void)loadUserPhrases
{ {
gLangModelCHT.loadUserPhrases([[self userPhrasesDataPathvChewing] UTF8String], [[self excludedPhrasesDataPathvChewing] UTF8String]); gLangModelCHT.loadUserPhrases([[self userPhrasesDataPathCHT] UTF8String], [[self excludedPhrasesDataPathCHT] UTF8String]);
gLangModelCHS.loadUserPhrases(NULL, [[self excludedPhrasesDataPathPlainBopomofo] UTF8String]); gLangModelCHS.loadUserPhrases([[self userPhrasesDataPathCHS] UTF8String], [[self excludedPhrasesDataPathCHS] UTF8String]);
} }
+ (void)loadUserPhraseReplacement + (void)loadUserPhraseReplacement
{ {
gLangModelCHT.loadPhraseReplacementMap([[self phraseReplacementDataPathvChewing] UTF8String]); gLangModelCHT.loadPhraseReplacementMap([[self phraseReplacementDataPathCHT] UTF8String]);
} }
+ (void)setupDataModelValueConverter + (void)setupDataModelValueConverter
@ -154,16 +153,13 @@ static void LTLoadAssociatedPhrases(vChewingLM &lm)
if (![self checkIfUserDataFolderExists]) { if (![self checkIfUserDataFolderExists]) {
return NO; return NO;
} }
if (![self ensureFileExists:[self userPhrasesDataPathvChewing] populateWithTemplate:kUserDataTemplateName extension:kTemplateExtension]) { if (![self ensureFileExists:[self userPhrasesDataPathCHT] populateWithTemplate:kUserDataTemplateName extension:kTemplateExtension]) {
return NO; return NO;
} }
if (![self ensureFileExists:[self excludedPhrasesDataPathvChewing] populateWithTemplate:kExcludedPhrasesvChewingTemplateName extension:kTemplateExtension]) { if (![self ensureFileExists:[self excludedPhrasesDataPathCHT] populateWithTemplate:kExcludedPhrasesvChewingTemplateName extension:kTemplateExtension]) {
return NO; return NO;
} }
if (![self ensureFileExists:[self excludedPhrasesDataPathPlainBopomofo] populateWithTemplate:kExcludedPhrasesPlainBopomofoTemplateName extension:kTemplateExtension]) { if (![self ensureFileExists:[self phraseReplacementDataPathCHT] populateWithTemplate:kPhraseReplacementTemplateName extension:kTemplateExtension]) {
return NO;
}
if (![self ensureFileExists:[self phraseReplacementDataPathvChewing] populateWithTemplate:kPhraseReplacementTemplateName extension:kTemplateExtension]) {
return NO; return NO;
} }
return YES; return YES;
@ -189,7 +185,7 @@ static void LTLoadAssociatedPhrases(vChewingLM &lm)
} }
BOOL addLineBreakAtFront = NO; BOOL addLineBreakAtFront = NO;
NSString *path = [self userPhrasesDataPathvChewing]; NSString *path = [self userPhrasesDataPathCHT];
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) { if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
NSError *error = nil; NSError *error = nil;
@ -239,32 +235,42 @@ static void LTLoadAssociatedPhrases(vChewingLM &lm)
return userDictPath; return userDictPath;
} }
+ (NSString *)userPhrasesDataPathvChewing + (NSString *)userPhrasesDataPathCHT
{ {
return [[self dataFolderPath] stringByAppendingPathComponent:@"userdata-cht.txt"]; return [[self dataFolderPath] stringByAppendingPathComponent:@"userdata-cht.txt"];
} }
+ (NSString *)excludedPhrasesDataPathvChewing + (NSString *)userPhrasesDataPathCHS
{
return [[self dataFolderPath] stringByAppendingPathComponent:@"userdata-chs.txt"];
}
+ (NSString *)excludedPhrasesDataPathCHT
{ {
return [[self dataFolderPath] stringByAppendingPathComponent:@"exclude-phrases-cht.txt"]; return [[self dataFolderPath] stringByAppendingPathComponent:@"exclude-phrases-cht.txt"];
} }
+ (NSString *)excludedPhrasesDataPathPlainBopomofo + (NSString *)excludedPhrasesDataPathCHS
{ {
return [[self dataFolderPath] stringByAppendingPathComponent:@"exclude-phrases-chs.txt"]; return [[self dataFolderPath] stringByAppendingPathComponent:@"exclude-phrases-chs.txt"];
} }
+ (NSString *)phraseReplacementDataPathvChewing + (NSString *)phraseReplacementDataPathCHT
{ {
return [[self dataFolderPath] stringByAppendingPathComponent:@"phrases-replacement-cht.txt"]; return [[self dataFolderPath] stringByAppendingPathComponent:@"phrases-replacement-cht.txt"];
} }
+ (vChewingLM *)languageModelvChewing + (NSString *)phraseReplacementDataPathCHS
{
return [[self dataFolderPath] stringByAppendingPathComponent:@"phrases-replacement-chs.txt"];
}
+ (vChewingLM *)lmCHT
{ {
return &gLangModelCHT; return &gLangModelCHT;
} }
+ (vChewingLM *)languageModelPlainBopomofo + (vChewingLM *)lmCHS
{ {
return &gLangModelCHS; return &gLangModelCHS;
} }

View File

@ -6,9 +6,10 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface mgrLangModel () @interface mgrLangModel ()
@property (class, readonly, nonatomic) vChewing::vChewingLM *languageModelvChewing; @property (class, readonly, nonatomic) vChewing::vChewingLM *lmCHT;
@property (class, readonly, nonatomic) vChewing::vChewingLM *languageModelPlainBopomofo; @property (class, readonly, nonatomic) vChewing::vChewingLM *lmCHS;
@property (class, readonly, nonatomic) vChewing::UserOverrideModel *userOverrideModel; @property (class, readonly, nonatomic) vChewing::UserOverrideModel *userOverrideModelCHT;
@property (class, readonly, nonatomic) vChewing::UserOverrideModel *userOverrideModelCHS;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END