KeyHandler // Say goodbye to ObjCpp.
This commit is contained in:
parent
62961c44f7
commit
25b3a1b766
|
@ -26,37 +26,18 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
@class InputHandler;
|
|
||||||
@class InputState;
|
|
||||||
@class KeyHandlerSputnik;
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@class KeyHandler;
|
@interface Composer : NSObject
|
||||||
|
+ (BOOL)chkKeyValidity:(UniChar)charCode;
|
||||||
@protocol KeyHandlerDelegate <NSObject>
|
+ (BOOL)isBufferEmpty;
|
||||||
- (id)ctlCandidateForKeyHandler:(KeyHandler *)keyHandler;
|
+ (void)clearBuffer;
|
||||||
- (void)keyHandler:(KeyHandler *)keyHandler didSelectCandidateAtIndex:(NSInteger)index ctlCandidate:(id)controller;
|
+ (void)combineReadingKey:(UniChar)charCode;
|
||||||
- (BOOL)keyHandler:(KeyHandler *)keyHandler didRequestWriteUserPhraseWithState:(InputState *)state;
|
+ (BOOL)checkWhetherToneMarkerConfirms;
|
||||||
@end
|
+ (NSString *)getSyllableComposition;
|
||||||
|
+ (void)doBackSpaceToBuffer;
|
||||||
@interface KeyHandler : NSObject
|
+ (NSString *)getComposition;
|
||||||
|
+ (void)ensureParser;
|
||||||
@property(weak, nonatomic) id<KeyHandlerDelegate> delegate;
|
|
||||||
|
|
||||||
// The following items need to be exposed to Swift:
|
|
||||||
|
|
||||||
- (BOOL)checkWhetherToneMarkerConfirmsPhoneticReadingBuffer;
|
|
||||||
- (BOOL)chkKeyValidity:(UniChar)value;
|
|
||||||
- (BOOL)isPhoneticReadingBufferEmpty;
|
|
||||||
- (BOOL)isPrintable:(UniChar)charCode;
|
|
||||||
- (NSString *)getCompositionFromPhoneticReadingBuffer;
|
|
||||||
- (NSString *)getSyllableCompositionFromPhoneticReadingBuffer;
|
|
||||||
- (void)clearPhoneticReadingBuffer;
|
|
||||||
- (void)combinePhoneticReadingBufferKey:(UniChar)charCode;
|
|
||||||
- (void)doBackSpaceToPhoneticReadingBuffer;
|
|
||||||
- (void)ensurePhoneticParser;
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,116 @@
|
||||||
|
// Copyright (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
||||||
|
// All possible vChewing-specific modifications are of:
|
||||||
|
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
1. The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
2. No trademark license is granted to use the trade names, trademarks, service
|
||||||
|
marks, or product names of Contributor, except as required to fulfill notice
|
||||||
|
requirements above.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "Composer.hh"
|
||||||
|
#import "Mandarin.h"
|
||||||
|
#import "vChewing-Swift.h"
|
||||||
|
|
||||||
|
static Mandarin::BopomofoReadingBuffer *PhoneticBuffer;
|
||||||
|
|
||||||
|
@implementation Composer
|
||||||
|
|
||||||
|
+ (BOOL)chkKeyValidity:(UniChar)charCode
|
||||||
|
{
|
||||||
|
return PhoneticBuffer->isValidKey((char)charCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (BOOL)isBufferEmpty
|
||||||
|
{
|
||||||
|
return PhoneticBuffer->isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)clearBuffer
|
||||||
|
{
|
||||||
|
PhoneticBuffer->clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)combineReadingKey:(UniChar)charCode
|
||||||
|
{
|
||||||
|
PhoneticBuffer->combineKey((char)charCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (BOOL)checkWhetherToneMarkerConfirms
|
||||||
|
{
|
||||||
|
return PhoneticBuffer->hasToneMarker();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSString *)getSyllableComposition
|
||||||
|
{
|
||||||
|
return [NSString stringWithUTF8String:PhoneticBuffer->syllable().composedString().c_str()];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)doBackSpaceToBuffer
|
||||||
|
{
|
||||||
|
PhoneticBuffer->backspace();
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSString *)getComposition
|
||||||
|
{
|
||||||
|
return [NSString stringWithUTF8String:PhoneticBuffer->composedString().c_str()];
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (void)ensureParser
|
||||||
|
{
|
||||||
|
if (PhoneticBuffer)
|
||||||
|
{
|
||||||
|
switch (mgrPrefs.mandarinParser)
|
||||||
|
{
|
||||||
|
case MandarinParserOfStandard:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
|
break;
|
||||||
|
case MandarinParserOfEten:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::ETenLayout());
|
||||||
|
break;
|
||||||
|
case MandarinParserOfHsu:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::HsuLayout());
|
||||||
|
break;
|
||||||
|
case MandarinParserOfEen26:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::ETen26Layout());
|
||||||
|
break;
|
||||||
|
case MandarinParserOfIBM:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::IBMLayout());
|
||||||
|
break;
|
||||||
|
case MandarinParserOfMiTAC:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::MiTACLayout());
|
||||||
|
break;
|
||||||
|
case MandarinParserOfFakeSeigyou:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::FakeSeigyouLayout());
|
||||||
|
break;
|
||||||
|
case MandarinParserOfHanyuPinyin:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::HanyuPinyinLayout());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
PhoneticBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
|
mgrPrefs.mandarinParser = MandarinParserOfStandard;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PhoneticBuffer = new Mandarin::BopomofoReadingBuffer(Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
|
@ -30,4 +30,5 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
@import Foundation;
|
@import Foundation;
|
||||||
|
|
||||||
#import "KeyHandler.h"
|
#import "CTools.h"
|
||||||
|
#import "Composer.hh"
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
// Refactored from the ObjCpp-version of this class by:
|
|
||||||
// (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
|
||||||
/*
|
/*
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
@ -24,19 +22,12 @@ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Cocoa
|
#import <Foundation/Foundation.h>
|
||||||
|
|
||||||
// MARK: - KeyHandler Sputnik.
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
// Swift Extension 不允許直接存放這些變數,所以就寫了這個衛星型別。
|
@interface CTools : NSObject
|
||||||
// 一旦 Mandarin 模組被 Swift 化,整個 KeyHandler 就可以都用 Swift。
|
+ (BOOL)isPrintable:(UniChar)charCode;
|
||||||
// 屆時會考慮將該衛星型別內的變數與常數都挪回 KeyHandler_Kernel 內。
|
@end
|
||||||
|
|
||||||
class KeyHandlerSputnik: NSObject {
|
NS_ASSUME_NONNULL_END
|
||||||
static let kEpsilon: Double = 0.000001
|
|
||||||
static var inputMode: String = ""
|
|
||||||
static var languageModel: vChewing.LMInstantiator = .init()
|
|
||||||
static var userOverrideModel: vChewing.LMUserOverride = .init()
|
|
||||||
static var builder: Megrez.BlockReadingBuilder = .init(lm: languageModel)
|
|
||||||
static var walkedNodes: [Megrez.NodeAnchor] = []
|
|
||||||
}
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
||||||
|
/*
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||||
|
this software and associated documentation files (the "Software"), to deal in
|
||||||
|
the Software without restriction, including without limitation the rights to
|
||||||
|
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software is furnished to do so,
|
||||||
|
subject to the following conditions:
|
||||||
|
|
||||||
|
1. The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
2. No trademark license is granted to use the trade names, trademarks, service
|
||||||
|
marks, or product names of Contributor, except as required to fulfill notice
|
||||||
|
requirements above.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
||||||
|
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
||||||
|
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
||||||
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import "CTools.h"
|
||||||
|
|
||||||
|
@implementation CTools
|
||||||
|
+ (BOOL)isPrintable:(UniChar)charCode
|
||||||
|
{
|
||||||
|
return isprint(charCode);
|
||||||
|
}
|
||||||
|
@end
|
|
@ -1,155 +0,0 @@
|
||||||
// Copyright (c) 2011 and onwards The OpenVanilla Project (MIT License).
|
|
||||||
// All possible vChewing-specific modifications are of:
|
|
||||||
// (c) 2021 and onwards The vChewing Project (MIT-NTL License).
|
|
||||||
/*
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software is furnished to do so,
|
|
||||||
subject to the following conditions:
|
|
||||||
|
|
||||||
1. The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
2. No trademark license is granted to use the trade names, trademarks, service
|
|
||||||
marks, or product names of Contributor, except as required to fulfill notice
|
|
||||||
requirements above.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
|
||||||
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
|
||||||
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
||||||
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#import "KeyHandler.h"
|
|
||||||
#import "Mandarin.h"
|
|
||||||
#import "vChewing-Swift.h"
|
|
||||||
#import <string>
|
|
||||||
|
|
||||||
typedef Mandarin::BopomofoReadingBuffer PhoneticBuffer;
|
|
||||||
|
|
||||||
// NON-SWIFTIFIABLE
|
|
||||||
@implementation KeyHandler
|
|
||||||
{
|
|
||||||
// the reading buffer that takes user input
|
|
||||||
PhoneticBuffer *_bpmfReadingBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
@synthesize delegate = _delegate;
|
|
||||||
|
|
||||||
// Not migrable as long as there's still ObjC++ components needed.
|
|
||||||
// Will deprecate this once Mandarin gets Swiftified.
|
|
||||||
- (instancetype)init
|
|
||||||
{
|
|
||||||
self = [super init];
|
|
||||||
if (self)
|
|
||||||
{
|
|
||||||
[self ensurePhoneticParser];
|
|
||||||
[self setInputMode:ctlInputMethod.currentInputMode];
|
|
||||||
}
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NON-SWIFTIFIABLE: Mandarin
|
|
||||||
- (void)dealloc
|
|
||||||
{ // clean up everything
|
|
||||||
if (_bpmfReadingBuffer)
|
|
||||||
delete _bpmfReadingBuffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - 目前到這裡了
|
|
||||||
|
|
||||||
#pragma mark - 必須用 ObjCpp 處理的部分: Mandarin
|
|
||||||
|
|
||||||
- (BOOL)chkKeyValidity:(UniChar)charCode
|
|
||||||
{
|
|
||||||
return _bpmfReadingBuffer->isValidKey((char)charCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)isPhoneticReadingBufferEmpty
|
|
||||||
{
|
|
||||||
return _bpmfReadingBuffer->isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)clearPhoneticReadingBuffer
|
|
||||||
{
|
|
||||||
_bpmfReadingBuffer->clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)combinePhoneticReadingBufferKey:(UniChar)charCode
|
|
||||||
{
|
|
||||||
_bpmfReadingBuffer->combineKey((char)charCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
- (BOOL)checkWhetherToneMarkerConfirmsPhoneticReadingBuffer
|
|
||||||
{
|
|
||||||
return _bpmfReadingBuffer->hasToneMarker();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)getSyllableCompositionFromPhoneticReadingBuffer
|
|
||||||
{
|
|
||||||
return [NSString stringWithUTF8String:_bpmfReadingBuffer->syllable().composedString().c_str()];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)doBackSpaceToPhoneticReadingBuffer
|
|
||||||
{
|
|
||||||
_bpmfReadingBuffer->backspace();
|
|
||||||
}
|
|
||||||
|
|
||||||
- (NSString *)getCompositionFromPhoneticReadingBuffer
|
|
||||||
{
|
|
||||||
return [NSString stringWithUTF8String:_bpmfReadingBuffer->composedString().c_str()];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)ensurePhoneticParser
|
|
||||||
{
|
|
||||||
if (_bpmfReadingBuffer)
|
|
||||||
{
|
|
||||||
switch (mgrPrefs.mandarinParser)
|
|
||||||
{
|
|
||||||
case MandarinParserOfStandard:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
|
||||||
break;
|
|
||||||
case MandarinParserOfEten:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::ETenLayout());
|
|
||||||
break;
|
|
||||||
case MandarinParserOfHsu:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::HsuLayout());
|
|
||||||
break;
|
|
||||||
case MandarinParserOfEen26:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::ETen26Layout());
|
|
||||||
break;
|
|
||||||
case MandarinParserOfIBM:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::IBMLayout());
|
|
||||||
break;
|
|
||||||
case MandarinParserOfMiTAC:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::MiTACLayout());
|
|
||||||
break;
|
|
||||||
case MandarinParserOfFakeSeigyou:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::FakeSeigyouLayout());
|
|
||||||
break;
|
|
||||||
case MandarinParserOfHanyuPinyin:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::HanyuPinyinLayout());
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
_bpmfReadingBuffer->setKeyboardLayout(Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
|
||||||
mgrPrefs.mandarinParser = MandarinParserOfStandard;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_bpmfReadingBuffer = new Mandarin::BopomofoReadingBuffer(Mandarin::BopomofoKeyboardLayout::StandardLayout());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - 威注音認為有必要單獨拿出來處理的部分,交給 Swift 則有些困難。
|
|
||||||
|
|
||||||
- (BOOL)isPrintable:(UniChar)charCode
|
|
||||||
{
|
|
||||||
return isprint(charCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
|
@ -34,16 +34,31 @@ public enum InputMode: String {
|
||||||
|
|
||||||
// MARK: - Delegate.
|
// MARK: - Delegate.
|
||||||
|
|
||||||
|
protocol KeyHandlerDelegate: NSObjectProtocol {
|
||||||
|
func ctlCandidate(for _: KeyHandler) -> Any
|
||||||
|
func keyHandler(
|
||||||
|
_: KeyHandler, didSelectCandidateAt index: Int,
|
||||||
|
ctlCandidate controller: Any
|
||||||
|
)
|
||||||
|
func keyHandler(_ keyHandler: KeyHandler, didRequestWriteUserPhraseWith state: InputState)
|
||||||
|
-> Bool
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Kernel.
|
// MARK: - Kernel.
|
||||||
|
|
||||||
extension KeyHandler {
|
class KeyHandler: NSObject {
|
||||||
var kEpsilon: Double {
|
let kEpsilon: Double = 0.000001
|
||||||
KeyHandlerSputnik.kEpsilon
|
var _inputMode: String = ""
|
||||||
}
|
var _languageModel: vChewing.LMInstantiator = .init()
|
||||||
|
var _userOverrideModel: vChewing.LMUserOverride = .init()
|
||||||
|
var _builder: Megrez.BlockReadingBuilder
|
||||||
|
var _walkedNodes: [Megrez.NodeAnchor] = []
|
||||||
|
|
||||||
|
weak var delegate: KeyHandlerDelegate?
|
||||||
|
|
||||||
var inputMode: InputMode {
|
var inputMode: InputMode {
|
||||||
get {
|
get {
|
||||||
switch KeyHandlerSputnik.inputMode {
|
switch _inputMode {
|
||||||
case "org.atelierInmu.inputmethod.vChewing.IMECHS":
|
case "org.atelierInmu.inputmethod.vChewing.IMECHS":
|
||||||
return InputMode.imeModeCHS
|
return InputMode.imeModeCHS
|
||||||
case "org.atelierInmu.inputmethod.vChewing.IMECHT":
|
case "org.atelierInmu.inputmethod.vChewing.IMECHT":
|
||||||
|
@ -55,17 +70,17 @@ extension KeyHandler {
|
||||||
set { setInputMode(newValue.rawValue) }
|
set { setInputMode(newValue.rawValue) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Will reenable this once Mandarin gets Swiftified.
|
override init() {
|
||||||
// override public init() {
|
_builder = Megrez.BlockReadingBuilder(lm: _languageModel)
|
||||||
// self.ensurePhoneticParser()
|
super.init()
|
||||||
// self.setInputMode(ctlInputMethod.currentInputMode)
|
Composer.ensureParser()
|
||||||
// super.init()
|
setInputMode(ctlInputMethod.currentInputMode)
|
||||||
// }
|
}
|
||||||
|
|
||||||
func clear() {
|
func clear() {
|
||||||
clearPhoneticReadingBuffer()
|
Composer.clearBuffer()
|
||||||
KeyHandlerSputnik.builder.clear()
|
_builder.clear()
|
||||||
KeyHandlerSputnik.walkedNodes.removeAll()
|
_walkedNodes.removeAll()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 這個函數得獨立出來給 ObjC 使用。
|
// 這個函數得獨立出來給 ObjC 使用。
|
||||||
|
@ -79,7 +94,7 @@ extension KeyHandler {
|
||||||
mgrPrefs.mostRecentInputMode = ctlInputMethod.currentInputMode
|
mgrPrefs.mostRecentInputMode = ctlInputMethod.currentInputMode
|
||||||
|
|
||||||
// 拿當前的 _inputMode 與 ctlInputMethod 的提報結果對比,不同的話則套用新設定:
|
// 拿當前的 _inputMode 與 ctlInputMethod 的提報結果對比,不同的話則套用新設定:
|
||||||
if KeyHandlerSputnik.inputMode != ctlInputMethod.currentInputMode {
|
if _inputMode != ctlInputMethod.currentInputMode {
|
||||||
// Reinitiate language models if necessary
|
// Reinitiate language models if necessary
|
||||||
setInputModesToLM(isCHS: isCHS)
|
setInputModesToLM(isCHS: isCHS)
|
||||||
|
|
||||||
|
@ -89,12 +104,12 @@ extension KeyHandler {
|
||||||
// Create new grid builder.
|
// Create new grid builder.
|
||||||
createNewBuilder()
|
createNewBuilder()
|
||||||
|
|
||||||
if !isPhoneticReadingBufferEmpty() {
|
if !Composer.isBufferEmpty() {
|
||||||
clearPhoneticReadingBuffer()
|
Composer.clearBuffer()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 直接寫到衛星模組內,省得類型轉換
|
// 直接寫到衛星模組內,省得類型轉換
|
||||||
KeyHandlerSputnik.inputMode = ctlInputMethod.currentInputMode
|
_inputMode = ctlInputMethod.currentInputMode
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Functions dealing with Megrez.
|
// MARK: - Functions dealing with Megrez.
|
||||||
|
@ -103,14 +118,14 @@ extension KeyHandler {
|
||||||
// Retrieve the most likely trellis, i.e. a Maximum Likelihood Estimation
|
// Retrieve the most likely trellis, i.e. a Maximum Likelihood Estimation
|
||||||
// of the best possible Mandarin characters given the input syllables,
|
// of the best possible Mandarin characters given the input syllables,
|
||||||
// using the Viterbi algorithm implemented in the Gramambular library
|
// using the Viterbi algorithm implemented in the Gramambular library
|
||||||
let walker = Megrez.Walker(grid: KeyHandlerSputnik.builder.grid())
|
let walker = Megrez.Walker(grid: _builder.grid())
|
||||||
|
|
||||||
// the reverse walk traces the trellis from the end
|
// the reverse walk traces the trellis from the end
|
||||||
let walked: [Megrez.NodeAnchor] = walker.reverseWalk(at: KeyHandlerSputnik.builder.grid().width())
|
let walked: [Megrez.NodeAnchor] = walker.reverseWalk(at: _builder.grid().width())
|
||||||
|
|
||||||
// then we use ".reversed()" to reverse the nodes so that we get the forward-walked nodes
|
// then we use ".reversed()" to reverse the nodes so that we get the forward-walked nodes
|
||||||
KeyHandlerSputnik.walkedNodes.removeAll()
|
_walkedNodes.removeAll()
|
||||||
KeyHandlerSputnik.walkedNodes.append(contentsOf: walked.reversed())
|
_walkedNodes.append(contentsOf: walked.reversed())
|
||||||
}
|
}
|
||||||
|
|
||||||
func popOverflowComposingTextAndWalk() -> String {
|
func popOverflowComposingTextAndWalk() -> String {
|
||||||
|
@ -123,13 +138,13 @@ extension KeyHandler {
|
||||||
// (i.e. popped out.)
|
// (i.e. popped out.)
|
||||||
|
|
||||||
var poppedText = ""
|
var poppedText = ""
|
||||||
if KeyHandlerSputnik.builder.grid().width() > mgrPrefs.composingBufferSize {
|
if _builder.grid().width() > mgrPrefs.composingBufferSize {
|
||||||
if KeyHandlerSputnik.walkedNodes.count > 0 {
|
if _walkedNodes.count > 0 {
|
||||||
let anchor: Megrez.NodeAnchor = KeyHandlerSputnik.walkedNodes[0]
|
let anchor: Megrez.NodeAnchor = _walkedNodes[0]
|
||||||
if let theNode = anchor.node {
|
if let theNode = anchor.node {
|
||||||
poppedText = theNode.currentKeyValue().value
|
poppedText = theNode.currentKeyValue().value
|
||||||
}
|
}
|
||||||
KeyHandlerSputnik.builder.removeHeadReadings(count: anchor.spanningLength)
|
_builder.removeHeadReadings(count: anchor.spanningLength)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
walk()
|
walk()
|
||||||
|
@ -138,15 +153,15 @@ extension KeyHandler {
|
||||||
|
|
||||||
func buildAssociatePhraseArray(withKey key: String) -> [String] {
|
func buildAssociatePhraseArray(withKey key: String) -> [String] {
|
||||||
var arrResult: [String] = []
|
var arrResult: [String] = []
|
||||||
if KeyHandlerSputnik.languageModel.hasAssociatedPhrasesForKey(key) {
|
if _languageModel.hasAssociatedPhrasesForKey(key) {
|
||||||
arrResult.append(contentsOf: KeyHandlerSputnik.languageModel.associatedPhrasesForKey(key))
|
arrResult.append(contentsOf: _languageModel.associatedPhrasesForKey(key))
|
||||||
}
|
}
|
||||||
return arrResult
|
return arrResult
|
||||||
}
|
}
|
||||||
|
|
||||||
func fixNode(value: String) {
|
func fixNode(value: String) {
|
||||||
let cursorIndex: Int = getActualCandidateCursorIndex()
|
let cursorIndex: Int = getActualCandidateCursorIndex()
|
||||||
let selectedNode: Megrez.NodeAnchor = KeyHandlerSputnik.builder.grid().fixNodeSelectedCandidate(
|
let selectedNode: Megrez.NodeAnchor = _builder.grid().fixNodeSelectedCandidate(
|
||||||
location: cursorIndex, value: value
|
location: cursorIndex, value: value
|
||||||
)
|
)
|
||||||
// 不要針對逐字選字模式啟用臨時半衰記憶模型。
|
// 不要針對逐字選字模式啟用臨時半衰記憶模型。
|
||||||
|
@ -167,8 +182,8 @@ extension KeyHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if addToUserOverrideModel {
|
if addToUserOverrideModel {
|
||||||
KeyHandlerSputnik.userOverrideModel.observe(
|
_userOverrideModel.observe(
|
||||||
walkedNodes: KeyHandlerSputnik.walkedNodes, cursorIndex: cursorIndex, candidate: value,
|
walkedNodes: _walkedNodes, cursorIndex: cursorIndex, candidate: value,
|
||||||
timestamp: NSDate().timeIntervalSince1970
|
timestamp: NSDate().timeIntervalSince1970
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -177,7 +192,7 @@ extension KeyHandler {
|
||||||
|
|
||||||
if mgrPrefs.moveCursorAfterSelectingCandidate {
|
if mgrPrefs.moveCursorAfterSelectingCandidate {
|
||||||
var nextPosition = 0
|
var nextPosition = 0
|
||||||
for node in KeyHandlerSputnik.walkedNodes {
|
for node in _walkedNodes {
|
||||||
if nextPosition >= cursorIndex { break }
|
if nextPosition >= cursorIndex { break }
|
||||||
nextPosition += node.spanningLength
|
nextPosition += node.spanningLength
|
||||||
}
|
}
|
||||||
|
@ -216,13 +231,13 @@ extension KeyHandler {
|
||||||
var overrideValue =
|
var overrideValue =
|
||||||
mgrPrefs.useSCPCTypingMode
|
mgrPrefs.useSCPCTypingMode
|
||||||
? ""
|
? ""
|
||||||
: KeyHandlerSputnik.userOverrideModel.suggest(
|
: _userOverrideModel.suggest(
|
||||||
walkedNodes: KeyHandlerSputnik.walkedNodes, cursorIndex: getBuilderCursorIndex(),
|
walkedNodes: _walkedNodes, cursorIndex: getBuilderCursorIndex(),
|
||||||
timestamp: NSDate().timeIntervalSince1970
|
timestamp: NSDate().timeIntervalSince1970
|
||||||
)
|
)
|
||||||
|
|
||||||
if !overrideValue.isEmpty {
|
if !overrideValue.isEmpty {
|
||||||
KeyHandlerSputnik.builder.grid().overrideNodeScoreForSelectedCandidate(
|
_builder.grid().overrideNodeScoreForSelectedCandidate(
|
||||||
location: getActualCandidateCursorIndex(),
|
location: getActualCandidateCursorIndex(),
|
||||||
value: &overrideValue,
|
value: &overrideValue,
|
||||||
overridingScore: findHighestScore(nodes: getRawNodes(), epsilon: kEpsilon)
|
overridingScore: findHighestScore(nodes: getRawNodes(), epsilon: kEpsilon)
|
||||||
|
@ -245,65 +260,65 @@ extension KeyHandler {
|
||||||
|
|
||||||
// MARK: - Extracted methods and functions.
|
// MARK: - Extracted methods and functions.
|
||||||
|
|
||||||
func isBuilderEmpty() -> Bool { KeyHandlerSputnik.builder.grid().width() == 0 }
|
func isBuilderEmpty() -> Bool { _builder.grid().width() == 0 }
|
||||||
|
|
||||||
func getRawNodes() -> [Megrez.NodeAnchor] {
|
func getRawNodes() -> [Megrez.NodeAnchor] {
|
||||||
/// 警告:不要對游標前置風格使用 nodesCrossing,否則會導致游標行為與 macOS 內建注音輸入法不一致。
|
/// 警告:不要對游標前置風格使用 nodesCrossing,否則會導致游標行為與 macOS 內建注音輸入法不一致。
|
||||||
/// 微軟新注音輸入法的游標後置風格也是不允許 nodeCrossing 的,但目前 Megrez 暫時缺乏對該特性的支援。
|
/// 微軟新注音輸入法的游標後置風格也是不允許 nodeCrossing 的,但目前 Megrez 暫時缺乏對該特性的支援。
|
||||||
/// 所以暫時只能將威注音的游標後置風格描述成「跟 Windows 版雅虎奇摩注音一致」。
|
/// 所以暫時只能將威注音的游標後置風格描述成「跟 Windows 版雅虎奇摩注音一致」。
|
||||||
mgrPrefs.setRearCursorMode
|
mgrPrefs.setRearCursorMode
|
||||||
? KeyHandlerSputnik.builder.grid().nodesCrossingOrEndingAt(location: getActualCandidateCursorIndex())
|
? _builder.grid().nodesCrossingOrEndingAt(location: getActualCandidateCursorIndex())
|
||||||
: KeyHandlerSputnik.builder.grid().nodesEndingAt(location: getActualCandidateCursorIndex())
|
: _builder.grid().nodesEndingAt(location: getActualCandidateCursorIndex())
|
||||||
}
|
}
|
||||||
|
|
||||||
func setInputModesToLM(isCHS: Bool) {
|
func setInputModesToLM(isCHS: Bool) {
|
||||||
KeyHandlerSputnik.languageModel = isCHS ? mgrLangModel.lmCHS : mgrLangModel.lmCHT
|
_languageModel = isCHS ? mgrLangModel.lmCHS : mgrLangModel.lmCHT
|
||||||
KeyHandlerSputnik.userOverrideModel = isCHS ? mgrLangModel.uomCHS : mgrLangModel.uomCHT
|
_userOverrideModel = isCHS ? mgrLangModel.uomCHS : mgrLangModel.uomCHT
|
||||||
}
|
}
|
||||||
|
|
||||||
func syncBaseLMPrefs() {
|
func syncBaseLMPrefs() {
|
||||||
KeyHandlerSputnik.languageModel.isPhraseReplacementEnabled = mgrPrefs.phraseReplacementEnabled
|
_languageModel.isPhraseReplacementEnabled = mgrPrefs.phraseReplacementEnabled
|
||||||
KeyHandlerSputnik.languageModel.isCNSEnabled = mgrPrefs.cns11643Enabled
|
_languageModel.isCNSEnabled = mgrPrefs.cns11643Enabled
|
||||||
KeyHandlerSputnik.languageModel.isSymbolEnabled = mgrPrefs.symbolInputEnabled
|
_languageModel.isSymbolEnabled = mgrPrefs.symbolInputEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func createNewBuilder() {
|
func createNewBuilder() {
|
||||||
KeyHandlerSputnik.builder = Megrez.BlockReadingBuilder(lm: KeyHandlerSputnik.languageModel)
|
_builder = Megrez.BlockReadingBuilder(lm: _languageModel)
|
||||||
// Each Mandarin syllable is separated by a hyphen.
|
// Each Mandarin syllable is separated by a hyphen.
|
||||||
KeyHandlerSputnik.builder.setJoinSeparator(separator: "-")
|
_builder.setJoinSeparator(separator: "-")
|
||||||
}
|
}
|
||||||
|
|
||||||
func currentReadings() -> [String] { KeyHandlerSputnik.builder.readings() }
|
func currentReadings() -> [String] { _builder.readings() }
|
||||||
|
|
||||||
func ifLangModelHasUnigrams(forKey reading: String) -> Bool {
|
func ifLangModelHasUnigrams(forKey reading: String) -> Bool {
|
||||||
KeyHandlerSputnik.languageModel.hasUnigramsFor(key: reading)
|
_languageModel.hasUnigramsFor(key: reading)
|
||||||
}
|
}
|
||||||
|
|
||||||
func insertReadingToBuilderAtCursor(reading: String) {
|
func insertReadingToBuilderAtCursor(reading: String) {
|
||||||
KeyHandlerSputnik.builder.insertReadingAtCursor(reading: reading)
|
_builder.insertReadingAtCursor(reading: reading)
|
||||||
}
|
}
|
||||||
|
|
||||||
func setBuilderCursorIndex(value: Int) {
|
func setBuilderCursorIndex(value: Int) {
|
||||||
KeyHandlerSputnik.builder.setCursorIndex(newIndex: value)
|
_builder.setCursorIndex(newIndex: value)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBuilderCursorIndex() -> Int {
|
func getBuilderCursorIndex() -> Int {
|
||||||
KeyHandlerSputnik.builder.cursorIndex()
|
_builder.cursorIndex()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBuilderLength() -> Int {
|
func getBuilderLength() -> Int {
|
||||||
KeyHandlerSputnik.builder.length()
|
_builder.length()
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteBuilderReadingInFrontOfCursor() {
|
func deleteBuilderReadingInFrontOfCursor() {
|
||||||
KeyHandlerSputnik.builder.deleteReadingBeforeCursor()
|
_builder.deleteReadingBeforeCursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteBuilderReadingAfterCursor() {
|
func deleteBuilderReadingAfterCursor() {
|
||||||
KeyHandlerSputnik.builder.deleteReadingAfterCursor()
|
_builder.deleteReadingAfterCursor()
|
||||||
}
|
}
|
||||||
|
|
||||||
func getKeyLengthAtIndexZero() -> Int {
|
func getKeyLengthAtIndexZero() -> Int {
|
||||||
KeyHandlerSputnik.walkedNodes[0].node?.currentKeyValue().value.count ?? 0
|
_walkedNodes[0].node?.currentKeyValue().value.count ?? 0
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,7 +28,7 @@ import Cocoa
|
||||||
|
|
||||||
// MARK: - § Handle Candidate State.
|
// MARK: - § Handle Candidate State.
|
||||||
|
|
||||||
@objc extension KeyHandler {
|
extension KeyHandler {
|
||||||
func handleCandidate(
|
func handleCandidate(
|
||||||
state: InputState,
|
state: InputState,
|
||||||
input: InputHandler,
|
input: InputHandler,
|
||||||
|
@ -331,7 +331,7 @@ import Cocoa
|
||||||
let punctuation: String = arrPunctuations.joined(separator: "")
|
let punctuation: String = arrPunctuations.joined(separator: "")
|
||||||
|
|
||||||
var shouldAutoSelectCandidate: Bool =
|
var shouldAutoSelectCandidate: Bool =
|
||||||
chkKeyValidity(charCode) || ifLangModelHasUnigrams(forKey: customPunctuation)
|
Composer.chkKeyValidity(charCode) || ifLangModelHasUnigrams(forKey: customPunctuation)
|
||||||
|| ifLangModelHasUnigrams(forKey: punctuation)
|
|| ifLangModelHasUnigrams(forKey: punctuation)
|
||||||
|
|
||||||
if !shouldAutoSelectCandidate, input.isUpperCaseASCIILetterKey {
|
if !shouldAutoSelectCandidate, input.isUpperCaseASCIILetterKey {
|
||||||
|
|
|
@ -28,7 +28,7 @@ import Cocoa
|
||||||
|
|
||||||
// MARK: - § Handle Input with States.
|
// MARK: - § Handle Input with States.
|
||||||
|
|
||||||
@objc extension KeyHandler {
|
extension KeyHandler {
|
||||||
func handle(
|
func handle(
|
||||||
input: InputHandler,
|
input: InputHandler,
|
||||||
state: InputState,
|
state: InputState,
|
||||||
|
@ -75,7 +75,7 @@ import Cocoa
|
||||||
|
|
||||||
// If ASCII but not printable, don't use insertText:replacementRange:
|
// If ASCII but not printable, don't use insertText:replacementRange:
|
||||||
// Certain apps don't handle non-ASCII char insertions.
|
// Certain apps don't handle non-ASCII char insertions.
|
||||||
if charCode < 0x80, !isPrintable(charCode) {
|
if charCode < 0x80, !CTools.isPrintable(charCode) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ import Cocoa
|
||||||
|
|
||||||
if input.isNumericPad {
|
if input.isNumericPad {
|
||||||
if !input.isLeft, !input.isRight, !input.isDown,
|
if !input.isLeft, !input.isRight, !input.isDown,
|
||||||
!input.isUp, !input.isSpace, isPrintable(charCode)
|
!input.isUp, !input.isSpace, CTools.isPrintable(charCode)
|
||||||
{
|
{
|
||||||
clear()
|
clear()
|
||||||
stateCallback(InputState.Empty())
|
stateCallback(InputState.Empty())
|
||||||
|
@ -139,13 +139,13 @@ import Cocoa
|
||||||
let skipPhoneticHandling = input.isReservedKey || input.isControlHold || input.isOptionHold
|
let skipPhoneticHandling = input.isReservedKey || input.isControlHold || input.isOptionHold
|
||||||
|
|
||||||
// See if Phonetic reading is valid.
|
// See if Phonetic reading is valid.
|
||||||
if !skipPhoneticHandling && chkKeyValidity(charCode) {
|
if !skipPhoneticHandling && Composer.chkKeyValidity(charCode) {
|
||||||
combinePhoneticReadingBufferKey(charCode)
|
Composer.combineReadingKey(charCode)
|
||||||
|
|
||||||
// If we have a tone marker, we have to insert the reading to the
|
// If we have a tone marker, we have to insert the reading to the
|
||||||
// builder in other words, if we don't have a tone marker, we just
|
// builder in other words, if we don't have a tone marker, we just
|
||||||
// update the composing buffer.
|
// update the composing buffer.
|
||||||
composeReading = checkWhetherToneMarkerConfirmsPhoneticReadingBuffer()
|
composeReading = Composer.checkWhetherToneMarkerConfirms()
|
||||||
if !composeReading {
|
if !composeReading {
|
||||||
stateCallback(buildInputtingState())
|
stateCallback(buildInputtingState())
|
||||||
return true
|
return true
|
||||||
|
@ -155,9 +155,9 @@ import Cocoa
|
||||||
// See if we have composition if Enter/Space is hit and buffer is not empty.
|
// See if we have composition if Enter/Space is hit and buffer is not empty.
|
||||||
// We use "|=" conditioning so that the tone marker key is also taken into account.
|
// We use "|=" conditioning so that the tone marker key is also taken into account.
|
||||||
// However, Swift does not support "|=".
|
// However, Swift does not support "|=".
|
||||||
composeReading = composeReading || (!isPhoneticReadingBufferEmpty() && (input.isSpace || input.isEnter))
|
composeReading = composeReading || (!Composer.isBufferEmpty() && (input.isSpace || input.isEnter))
|
||||||
if composeReading {
|
if composeReading {
|
||||||
let reading = getSyllableCompositionFromPhoneticReadingBuffer()
|
let reading = Composer.getSyllableComposition()
|
||||||
|
|
||||||
if !ifLangModelHasUnigrams(forKey: reading) {
|
if !ifLangModelHasUnigrams(forKey: reading) {
|
||||||
IME.prtDebugIntel("B49C0979:語彙庫內無「\(reading)」的匹配記錄。")
|
IME.prtDebugIntel("B49C0979:語彙庫內無「\(reading)」的匹配記錄。")
|
||||||
|
@ -176,7 +176,7 @@ import Cocoa
|
||||||
dealWithOverrideModelSuggestions()
|
dealWithOverrideModelSuggestions()
|
||||||
|
|
||||||
// ... then update the text.
|
// ... then update the text.
|
||||||
clearPhoneticReadingBuffer()
|
Composer.clearBuffer()
|
||||||
|
|
||||||
let inputting = buildInputtingState()
|
let inputting = buildInputtingState()
|
||||||
inputting.poppedText = poppedText
|
inputting.poppedText = poppedText
|
||||||
|
@ -216,7 +216,7 @@ import Cocoa
|
||||||
// MARK: Calling candidate window using Space or Down or PageUp / PageDn.
|
// MARK: Calling candidate window using Space or Down or PageUp / PageDn.
|
||||||
|
|
||||||
if let currentState = state as? InputState.NotEmpty {
|
if let currentState = state as? InputState.NotEmpty {
|
||||||
if isPhoneticReadingBufferEmpty(),
|
if Composer.isBufferEmpty(),
|
||||||
input.isExtraChooseCandidateKey || input.isExtraChooseCandidateKeyReverse || input.isSpace
|
input.isExtraChooseCandidateKey || input.isExtraChooseCandidateKeyReverse || input.isSpace
|
||||||
|| input.isPageDown || input.isPageUp || input.isTab
|
|| input.isPageDown || input.isPageUp || input.isTab
|
||||||
|| (input.useVerticalMode && (input.isVerticalModeOnlyChooseCandidateKey))
|
|| (input.useVerticalMode && (input.isVerticalModeOnlyChooseCandidateKey))
|
||||||
|
@ -329,7 +329,7 @@ import Cocoa
|
||||||
if input.isSymbolMenuPhysicalKey && !input.isShiftHold {
|
if input.isSymbolMenuPhysicalKey && !input.isShiftHold {
|
||||||
if !input.isOptionHold {
|
if !input.isOptionHold {
|
||||||
if ifLangModelHasUnigrams(forKey: "_punctuation_list") {
|
if ifLangModelHasUnigrams(forKey: "_punctuation_list") {
|
||||||
if isPhoneticReadingBufferEmpty() {
|
if Composer.isBufferEmpty() {
|
||||||
insertReadingToBuilderAtCursor(reading: "_punctuation_list")
|
insertReadingToBuilderAtCursor(reading: "_punctuation_list")
|
||||||
let poppedText: String! = popOverflowComposingTextAndWalk()
|
let poppedText: String! = popOverflowComposingTextAndWalk()
|
||||||
let inputting = buildInputtingState()
|
let inputting = buildInputtingState()
|
||||||
|
@ -418,7 +418,7 @@ import Cocoa
|
||||||
// "thinking" that the key is not actually consumed.
|
// "thinking" that the key is not actually consumed.
|
||||||
// 砍掉這一段會導致「F1-F12 按鍵干擾組字區」的問題。
|
// 砍掉這一段會導致「F1-F12 按鍵干擾組字區」的問題。
|
||||||
// 暫時只能先恢復這段,且補上偵錯彙報機制,方便今後排查故障。
|
// 暫時只能先恢復這段,且補上偵錯彙報機制,方便今後排查故障。
|
||||||
if (state is InputState.NotEmpty) || !isPhoneticReadingBufferEmpty() {
|
if (state is InputState.NotEmpty) || !Composer.isBufferEmpty() {
|
||||||
IME.prtDebugIntel(
|
IME.prtDebugIntel(
|
||||||
"Blocked data: charCode: \(charCode), keyCode: \(input.keyCode)")
|
"Blocked data: charCode: \(charCode), keyCode: \(input.keyCode)")
|
||||||
IME.prtDebugIntel("A9BFF20E")
|
IME.prtDebugIntel("A9BFF20E")
|
||||||
|
|
|
@ -28,7 +28,7 @@ import Cocoa
|
||||||
|
|
||||||
// MARK: - § Misc functions.
|
// MARK: - § Misc functions.
|
||||||
|
|
||||||
@objc extension KeyHandler {
|
extension KeyHandler {
|
||||||
func getCurrentMandarinParser() -> String {
|
func getCurrentMandarinParser() -> String {
|
||||||
mgrPrefs.mandarinParserName + "_"
|
mgrPrefs.mandarinParserName + "_"
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ import Cocoa
|
||||||
|
|
||||||
// MARK: - § State managements.
|
// MARK: - § State managements.
|
||||||
|
|
||||||
@objc extension KeyHandler {
|
extension KeyHandler {
|
||||||
// MARK: - 構築狀態(State Building)
|
// MARK: - 構築狀態(State Building)
|
||||||
|
|
||||||
func buildInputtingState() -> InputState.Inputting {
|
func buildInputtingState() -> InputState.Inputting {
|
||||||
|
@ -44,7 +44,7 @@ import Cocoa
|
||||||
// i.e. we need to take UTF-16 into consideration, for which a surrogate pair takes 2 UniChars
|
// i.e. we need to take UTF-16 into consideration, for which a surrogate pair takes 2 UniChars
|
||||||
// locations. These processes are inherited from the ObjC++ version of this class and might be
|
// locations. These processes are inherited from the ObjC++ version of this class and might be
|
||||||
// unnecessary in Swift, but this deduction requires further experiments.
|
// unnecessary in Swift, but this deduction requires further experiments.
|
||||||
for walkedNode in KeyHandlerSputnik.walkedNodes {
|
for walkedNode in _walkedNodes {
|
||||||
if let theNode = walkedNode.node {
|
if let theNode = walkedNode.node {
|
||||||
let strNodeValue = theNode.currentKeyValue().value
|
let strNodeValue = theNode.currentKeyValue().value
|
||||||
composingBuffer += strNodeValue
|
composingBuffer += strNodeValue
|
||||||
|
@ -87,7 +87,7 @@ import Cocoa
|
||||||
// The reading text is what the user is typing.
|
// The reading text is what the user is typing.
|
||||||
|
|
||||||
let head = String((composingBuffer as NSString).substring(to: composedStringCursorIndex))
|
let head = String((composingBuffer as NSString).substring(to: composedStringCursorIndex))
|
||||||
let reading = getCompositionFromPhoneticReadingBuffer()
|
let reading = Composer.getComposition()
|
||||||
let tail = String((composingBuffer as NSString).substring(from: composedStringCursorIndex))
|
let tail = String((composingBuffer as NSString).substring(from: composedStringCursorIndex))
|
||||||
let composedText = head + reading + tail
|
let composedText = head + reading + tail
|
||||||
let cursorIndex = composedStringCursorIndex + reading.count
|
let cursorIndex = composedStringCursorIndex + reading.count
|
||||||
|
@ -213,14 +213,14 @@ import Cocoa
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPhoneticReadingBufferEmpty() {
|
if Composer.isBufferEmpty() {
|
||||||
insertReadingToBuilderAtCursor(reading: customPunctuation)
|
insertReadingToBuilderAtCursor(reading: customPunctuation)
|
||||||
let poppedText = popOverflowComposingTextAndWalk()
|
let poppedText = popOverflowComposingTextAndWalk()
|
||||||
let inputting = buildInputtingState()
|
let inputting = buildInputtingState()
|
||||||
inputting.poppedText = poppedText
|
inputting.poppedText = poppedText
|
||||||
stateCallback(inputting)
|
stateCallback(inputting)
|
||||||
|
|
||||||
if mgrPrefs.useSCPCTypingMode, isPhoneticReadingBufferEmpty() {
|
if mgrPrefs.useSCPCTypingMode, Composer.isBufferEmpty() {
|
||||||
let candidateState = buildCandidate(
|
let candidateState = buildCandidate(
|
||||||
state: inputting,
|
state: inputting,
|
||||||
useVerticalMode: useVerticalMode
|
useVerticalMode: useVerticalMode
|
||||||
|
@ -303,7 +303,7 @@ import Cocoa
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPhoneticReadingBufferEmpty() {
|
if Composer.isBufferEmpty() {
|
||||||
if getBuilderCursorIndex() >= 0 {
|
if getBuilderCursorIndex() >= 0 {
|
||||||
deleteBuilderReadingInFrontOfCursor()
|
deleteBuilderReadingInFrontOfCursor()
|
||||||
walk()
|
walk()
|
||||||
|
@ -314,10 +314,10 @@ import Cocoa
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
doBackSpaceToPhoneticReadingBuffer()
|
Composer.doBackSpaceToBuffer()
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPhoneticReadingBufferEmpty(), getBuilderLength() == 0 {
|
if Composer.isBufferEmpty(), getBuilderLength() == 0 {
|
||||||
stateCallback(InputState.EmptyIgnoringPreviousState())
|
stateCallback(InputState.EmptyIgnoringPreviousState())
|
||||||
} else {
|
} else {
|
||||||
stateCallback(buildInputtingState())
|
stateCallback(buildInputtingState())
|
||||||
|
@ -336,7 +336,7 @@ import Cocoa
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if isPhoneticReadingBufferEmpty() {
|
if Composer.isBufferEmpty() {
|
||||||
if getBuilderCursorIndex() != getBuilderLength() {
|
if getBuilderCursorIndex() != getBuilderLength() {
|
||||||
deleteBuilderReadingAfterCursor()
|
deleteBuilderReadingAfterCursor()
|
||||||
walk()
|
walk()
|
||||||
|
@ -371,7 +371,7 @@ import Cocoa
|
||||||
if !(state is InputState.Inputting) {
|
if !(state is InputState.Inputting) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if !isPhoneticReadingBufferEmpty() {
|
if !Composer.isBufferEmpty() {
|
||||||
IME.prtDebugIntel("9B6F908D")
|
IME.prtDebugIntel("9B6F908D")
|
||||||
errorCallback()
|
errorCallback()
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ import Cocoa
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isPhoneticReadingBufferEmpty() {
|
if !Composer.isBufferEmpty() {
|
||||||
IME.prtDebugIntel("ABC44080")
|
IME.prtDebugIntel("ABC44080")
|
||||||
errorCallback()
|
errorCallback()
|
||||||
stateCallback(state)
|
stateCallback(state)
|
||||||
|
@ -420,7 +420,7 @@ import Cocoa
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isPhoneticReadingBufferEmpty() {
|
if !Composer.isBufferEmpty() {
|
||||||
IME.prtDebugIntel("9B69908D")
|
IME.prtDebugIntel("9B69908D")
|
||||||
errorCallback()
|
errorCallback()
|
||||||
stateCallback(state)
|
stateCallback(state)
|
||||||
|
@ -459,8 +459,8 @@ import Cocoa
|
||||||
stateCallback(InputState.EmptyIgnoringPreviousState())
|
stateCallback(InputState.EmptyIgnoringPreviousState())
|
||||||
} else {
|
} else {
|
||||||
// If reading is not empty, we cancel the reading.
|
// If reading is not empty, we cancel the reading.
|
||||||
if !isPhoneticReadingBufferEmpty() {
|
if !Composer.isBufferEmpty() {
|
||||||
clearPhoneticReadingBuffer()
|
Composer.clearBuffer()
|
||||||
if getBuilderLength() == 0 {
|
if getBuilderLength() == 0 {
|
||||||
stateCallback(InputState.Empty())
|
stateCallback(InputState.Empty())
|
||||||
} else {
|
} else {
|
||||||
|
@ -481,7 +481,7 @@ import Cocoa
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
if !(state is InputState.Inputting) { return false }
|
if !(state is InputState.Inputting) { return false }
|
||||||
|
|
||||||
if !isPhoneticReadingBufferEmpty() {
|
if !Composer.isBufferEmpty() {
|
||||||
IME.prtDebugIntel("B3BA5257")
|
IME.prtDebugIntel("B3BA5257")
|
||||||
errorCallback()
|
errorCallback()
|
||||||
stateCallback(state)
|
stateCallback(state)
|
||||||
|
@ -532,7 +532,7 @@ import Cocoa
|
||||||
) -> Bool {
|
) -> Bool {
|
||||||
if !(state is InputState.Inputting) { return false }
|
if !(state is InputState.Inputting) { return false }
|
||||||
|
|
||||||
if !isPhoneticReadingBufferEmpty() {
|
if !Composer.isBufferEmpty() {
|
||||||
IME.prtDebugIntel("6ED95318")
|
IME.prtDebugIntel("6ED95318")
|
||||||
errorCallback()
|
errorCallback()
|
||||||
stateCallback(state)
|
stateCallback(state)
|
||||||
|
|
|
@ -93,7 +93,7 @@ class ctlInputMethod: IMKInputController {
|
||||||
currentClient = client
|
currentClient = client
|
||||||
|
|
||||||
keyHandler.clear()
|
keyHandler.clear()
|
||||||
keyHandler.ensurePhoneticParser()
|
Composer.ensureParser()
|
||||||
if let bundleCheckID = (client as? IMKTextInput)?.bundleIdentifier() {
|
if let bundleCheckID = (client as? IMKTextInput)?.bundleIdentifier() {
|
||||||
if bundleCheckID != Bundle.main.bundleIdentifier {
|
if bundleCheckID != Bundle.main.bundleIdentifier {
|
||||||
// Override the keyboard layout to the basic one.
|
// Override the keyboard layout to the basic one.
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
5B38F5A2281E2E49007D5F5D /* 0_Megrez.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A0D4F1615FC0EB100ABF4B3 /* 0_Megrez.swift */; };
|
5B38F5A2281E2E49007D5F5D /* 0_Megrez.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A0D4F1615FC0EB100ABF4B3 /* 0_Megrez.swift */; };
|
||||||
5B38F5A3281E2E49007D5F5D /* 3_Span.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A0D4F1C15FC0EB100ABF4B3 /* 3_Span.swift */; };
|
5B38F5A3281E2E49007D5F5D /* 3_Span.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A0D4F1C15FC0EB100ABF4B3 /* 3_Span.swift */; };
|
||||||
5B38F5A4281E2E49007D5F5D /* 5_LanguageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A0D4F1915FC0EB100ABF4B3 /* 5_LanguageModel.swift */; };
|
5B38F5A4281E2E49007D5F5D /* 5_LanguageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6A0D4F1915FC0EB100ABF4B3 /* 5_LanguageModel.swift */; };
|
||||||
|
5B407153281F94E6009C24CB /* Composer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5B407152281F94E6009C24CB /* Composer.mm */; };
|
||||||
5B40730C281672610023DFFF /* lmAssociates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B407309281672610023DFFF /* lmAssociates.swift */; };
|
5B40730C281672610023DFFF /* lmAssociates.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B407309281672610023DFFF /* lmAssociates.swift */; };
|
||||||
5B40730D281672610023DFFF /* lmReplacements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B40730A281672610023DFFF /* lmReplacements.swift */; };
|
5B40730D281672610023DFFF /* lmReplacements.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B40730A281672610023DFFF /* lmReplacements.swift */; };
|
||||||
5B5D28AC281EA1E900523D4D /* lmLite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D28AB281EA1E800523D4D /* lmLite.swift */; };
|
5B5D28AC281EA1E900523D4D /* lmLite.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B5D28AB281EA1E800523D4D /* lmLite.swift */; };
|
||||||
|
@ -83,9 +84,8 @@
|
||||||
5BBBB77627AED70B0023B93A /* MenuIcon-TCVIM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB77227AED70B0023B93A /* MenuIcon-TCVIM.png */; };
|
5BBBB77627AED70B0023B93A /* MenuIcon-TCVIM.png in Resources */ = {isa = PBXBuildFile; fileRef = 5BBBB77227AED70B0023B93A /* MenuIcon-TCVIM.png */; };
|
||||||
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BBBB77927AEDC690023B93A /* clsSFX.swift */; };
|
5BBBB77A27AEDC690023B93A /* clsSFX.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BBBB77927AEDC690023B93A /* clsSFX.swift */; };
|
||||||
5BC2652227E04B7E00700291 /* uninstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5BC2652127E04B7B00700291 /* uninstall.sh */; };
|
5BC2652227E04B7E00700291 /* uninstall.sh in Resources */ = {isa = PBXBuildFile; fileRef = 5BC2652127E04B7B00700291 /* uninstall.sh */; };
|
||||||
5BC4F6382819FF4500A2514A /* KeyHandlerSputnik.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BC4F6372819FF4500A2514A /* KeyHandlerSputnik.swift */; };
|
|
||||||
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113A28180D6100609769 /* LMInstantiator.swift */; };
|
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113A28180D6100609769 /* LMInstantiator.swift */; };
|
||||||
5BD0113D2818543900609769 /* KeyHandler_Kernel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113C2818543900609769 /* KeyHandler_Kernel.swift */; };
|
5BD0113D2818543900609769 /* KeyHandler_Core.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5BD0113C2818543900609769 /* KeyHandler_Core.swift */; };
|
||||||
5BD05B8127B22F3C004C4F1D /* char-kanji-cns.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05B8027B22F3C004C4F1D /* char-kanji-cns.txt */; };
|
5BD05B8127B22F3C004C4F1D /* char-kanji-cns.txt in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05B8027B22F3C004C4F1D /* char-kanji-cns.txt */; };
|
||||||
5BD05BCA27B2A43D004C4F1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */; };
|
5BD05BCA27B2A43D004C4F1D /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6A2E40F5253A69DA00D1AE1D /* Images.xcassets */; };
|
||||||
5BD05C5D27B2BBA9004C4F1D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05C5B27B2BBA9004C4F1D /* Main.storyboard */; };
|
5BD05C5D27B2BBA9004C4F1D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5BD05C5B27B2BBA9004C4F1D /* Main.storyboard */; };
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
D4A13D5A27A59F0B003BE359 /* ctlInputMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4A13D5927A59D5C003BE359 /* ctlInputMethod.swift */; };
|
D4A13D5A27A59F0B003BE359 /* ctlInputMethod.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4A13D5927A59D5C003BE359 /* ctlInputMethod.swift */; };
|
||||||
D4E33D8A27A838CF006DB1CF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4E33D8827A838CF006DB1CF /* Localizable.strings */; };
|
D4E33D8A27A838CF006DB1CF /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4E33D8827A838CF006DB1CF /* Localizable.strings */; };
|
||||||
D4E33D8F27A838F0006DB1CF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4E33D8D27A838F0006DB1CF /* InfoPlist.strings */; };
|
D4E33D8F27A838F0006DB1CF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D4E33D8D27A838F0006DB1CF /* InfoPlist.strings */; };
|
||||||
D4E569DC27A34D0E00AC2CEF /* KeyHandler.mm in Sources */ = {isa = PBXBuildFile; fileRef = D4E569DB27A34CC100AC2CEF /* KeyHandler.mm */; };
|
D4E569DC27A34D0E00AC2CEF /* CTools.m in Sources */ = {isa = PBXBuildFile; fileRef = D4E569DB27A34CC100AC2CEF /* CTools.m */; };
|
||||||
D4F0BBDF279AF1AF0071253C /* ArchiveUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F0BBDE279AF1AF0071253C /* ArchiveUtil.swift */; };
|
D4F0BBDF279AF1AF0071253C /* ArchiveUtil.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F0BBDE279AF1AF0071253C /* ArchiveUtil.swift */; };
|
||||||
D4F0BBE1279AF8B30071253C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F0BBE0279AF8B30071253C /* AppDelegate.swift */; };
|
D4F0BBE1279AF8B30071253C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F0BBE0279AF8B30071253C /* AppDelegate.swift */; };
|
||||||
D4F0BBE4279B08900071253C /* Chronosphere.m in Sources */ = {isa = PBXBuildFile; fileRef = D4F0BBE3279B08900071253C /* Chronosphere.m */; };
|
D4F0BBE4279B08900071253C /* Chronosphere.m in Sources */ = {isa = PBXBuildFile; fileRef = D4F0BBE3279B08900071253C /* Chronosphere.m */; };
|
||||||
|
@ -201,6 +201,8 @@
|
||||||
5B2DB17127AF8771006D874E /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Data/Makefile; sourceTree = "<group>"; };
|
5B2DB17127AF8771006D874E /* Makefile */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.make; name = Makefile; path = Data/Makefile; sourceTree = "<group>"; };
|
||||||
5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = vChewingKeyLayout.bundle; sourceTree = "<group>"; };
|
5B30F11227BA568800484E24 /* vChewingKeyLayout.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = vChewingKeyLayout.bundle; sourceTree = "<group>"; };
|
||||||
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_States.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 1; };
|
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = KeyHandler_States.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 1; };
|
||||||
|
5B407151281F94E6009C24CB /* Composer.hh */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Composer.hh; sourceTree = "<group>"; };
|
||||||
|
5B407152281F94E6009C24CB /* Composer.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = Composer.mm; sourceTree = "<group>"; };
|
||||||
5B407309281672610023DFFF /* lmAssociates.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmAssociates.swift; sourceTree = "<group>"; usesTabs = 1; };
|
5B407309281672610023DFFF /* lmAssociates.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmAssociates.swift; sourceTree = "<group>"; usesTabs = 1; };
|
||||||
5B40730A281672610023DFFF /* lmReplacements.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmReplacements.swift; sourceTree = "<group>"; usesTabs = 1; };
|
5B40730A281672610023DFFF /* lmReplacements.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = lmReplacements.swift; sourceTree = "<group>"; usesTabs = 1; };
|
||||||
5B5D28AB281EA1E800523D4D /* lmLite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lmLite.swift; sourceTree = "<group>"; };
|
5B5D28AB281EA1E800523D4D /* lmLite.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = lmLite.swift; sourceTree = "<group>"; };
|
||||||
|
@ -263,9 +265,8 @@
|
||||||
5BC0AAC927F58472002D33E9 /* pkgPreInstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = pkgPreInstall.sh; sourceTree = "<group>"; };
|
5BC0AAC927F58472002D33E9 /* pkgPreInstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = pkgPreInstall.sh; sourceTree = "<group>"; };
|
||||||
5BC0AACA27F58472002D33E9 /* pkgPostInstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = pkgPostInstall.sh; sourceTree = "<group>"; };
|
5BC0AACA27F58472002D33E9 /* pkgPostInstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = pkgPostInstall.sh; sourceTree = "<group>"; };
|
||||||
5BC2652127E04B7B00700291 /* uninstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; lineEnding = 0; path = uninstall.sh; sourceTree = "<group>"; };
|
5BC2652127E04B7B00700291 /* uninstall.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; lineEnding = 0; path = uninstall.sh; sourceTree = "<group>"; };
|
||||||
5BC4F6372819FF4500A2514A /* KeyHandlerSputnik.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = KeyHandlerSputnik.swift; sourceTree = "<group>"; usesTabs = 1; };
|
|
||||||
5BD0113A28180D6100609769 /* LMInstantiator.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = LMInstantiator.swift; sourceTree = "<group>"; usesTabs = 1; };
|
5BD0113A28180D6100609769 /* LMInstantiator.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = LMInstantiator.swift; sourceTree = "<group>"; usesTabs = 1; };
|
||||||
5BD0113C2818543900609769 /* KeyHandler_Kernel.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = KeyHandler_Kernel.swift; sourceTree = "<group>"; usesTabs = 1; };
|
5BD0113C2818543900609769 /* KeyHandler_Core.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; lineEnding = 0; path = KeyHandler_Core.swift; sourceTree = "<group>"; usesTabs = 1; };
|
||||||
5BD05B8027B22F3C004C4F1D /* char-kanji-cns.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "char-kanji-cns.txt"; path = "Data/components/common/char-kanji-cns.txt"; sourceTree = "<group>"; };
|
5BD05B8027B22F3C004C4F1D /* char-kanji-cns.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "char-kanji-cns.txt"; path = "Data/components/common/char-kanji-cns.txt"; sourceTree = "<group>"; };
|
||||||
5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = vChewingPhraseEditor.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
5BD05BB827B2A429004C4F1D /* vChewingPhraseEditor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = vChewingPhraseEditor.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
5BD05BC627B2A42A004C4F1D /* vChewingPhraseEditor.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = vChewingPhraseEditor.entitlements; sourceTree = "<group>"; };
|
5BD05BC627B2A42A004C4F1D /* vChewingPhraseEditor.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = vChewingPhraseEditor.entitlements; sourceTree = "<group>"; };
|
||||||
|
@ -334,8 +335,8 @@
|
||||||
D4A13D5927A59D5C003BE359 /* ctlInputMethod.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlInputMethod.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 1; };
|
D4A13D5927A59D5C003BE359 /* ctlInputMethod.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ctlInputMethod.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 1; };
|
||||||
D4E33D8927A838CF006DB1CF /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
|
D4E33D8927A838CF006DB1CF /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||||
D4E33D8E27A838F0006DB1CF /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
D4E33D8E27A838F0006DB1CF /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = Base; path = Base.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||||
D4E569DA27A34CC100AC2CEF /* KeyHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = KeyHandler.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
|
D4E569DA27A34CC100AC2CEF /* CTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = CTools.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
|
||||||
D4E569DB27A34CC100AC2CEF /* KeyHandler.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = KeyHandler.mm; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
|
D4E569DB27A34CC100AC2CEF /* CTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = CTools.m; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
|
||||||
D4F0BBDE279AF1AF0071253C /* ArchiveUtil.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ArchiveUtil.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 1; };
|
D4F0BBDE279AF1AF0071253C /* ArchiveUtil.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = ArchiveUtil.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 1; };
|
||||||
D4F0BBE0279AF8B30071253C /* AppDelegate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = AppDelegate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 1; };
|
D4F0BBE0279AF8B30071253C /* AppDelegate.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; fileEncoding = 4; indentWidth = 2; lineEnding = 0; path = AppDelegate.swift; sourceTree = "<group>"; tabWidth = 2; usesTabs = 1; };
|
||||||
D4F0BBE2279B08900071253C /* Chronosphere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Chronosphere.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
|
D4F0BBE2279B08900071253C /* Chronosphere.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = Chronosphere.h; sourceTree = "<group>"; tabWidth = 4; usesTabs = 0; };
|
||||||
|
@ -419,6 +420,8 @@
|
||||||
children = (
|
children = (
|
||||||
6A0D4F2015FC0EB100ABF4B3 /* Mandarin.cpp */,
|
6A0D4F2015FC0EB100ABF4B3 /* Mandarin.cpp */,
|
||||||
6A0D4F2115FC0EB100ABF4B3 /* Mandarin.h */,
|
6A0D4F2115FC0EB100ABF4B3 /* Mandarin.h */,
|
||||||
|
5B407151281F94E6009C24CB /* Composer.hh */,
|
||||||
|
5B407152281F94E6009C24CB /* Composer.mm */,
|
||||||
);
|
);
|
||||||
path = OVMandarin;
|
path = OVMandarin;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -435,16 +438,15 @@
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */,
|
5B11328827B94CFB00E58451 /* AppleKeyboardConverter.swift */,
|
||||||
|
D4E569DA27A34CC100AC2CEF /* CTools.h */,
|
||||||
|
D4E569DB27A34CC100AC2CEF /* CTools.m */,
|
||||||
D456576D279E4F7B00DF6BC9 /* InputHandler.swift */,
|
D456576D279E4F7B00DF6BC9 /* InputHandler.swift */,
|
||||||
D461B791279DAC010070E734 /* InputState.swift */,
|
D461B791279DAC010070E734 /* InputState.swift */,
|
||||||
|
5BD0113C2818543900609769 /* KeyHandler_Core.swift */,
|
||||||
5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */,
|
5B782EC3280C243C007276DE /* KeyHandler_HandleCandidate.swift */,
|
||||||
5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */,
|
5B7F225C2808501000DDD3CB /* KeyHandler_HandleInput.swift */,
|
||||||
5BD0113C2818543900609769 /* KeyHandler_Kernel.swift */,
|
|
||||||
5B61B0C9280BEFD4002E3CFA /* KeyHandler_Misc.swift */,
|
5B61B0C9280BEFD4002E3CFA /* KeyHandler_Misc.swift */,
|
||||||
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */,
|
5B3133BE280B229700A4A505 /* KeyHandler_States.swift */,
|
||||||
5BC4F6372819FF4500A2514A /* KeyHandlerSputnik.swift */,
|
|
||||||
D4E569DA27A34CC100AC2CEF /* KeyHandler.h */,
|
|
||||||
D4E569DB27A34CC100AC2CEF /* KeyHandler.mm */,
|
|
||||||
5B62A33727AE79CD00A19448 /* NSStringUtils.swift */,
|
5B62A33727AE79CD00A19448 /* NSStringUtils.swift */,
|
||||||
5BF8423027BAA942008E7E4C /* vChewingKanjiConverter.swift */,
|
5BF8423027BAA942008E7E4C /* vChewingKanjiConverter.swift */,
|
||||||
);
|
);
|
||||||
|
@ -1088,9 +1090,8 @@
|
||||||
D47B92C027972AD100458394 /* main.swift in Sources */,
|
D47B92C027972AD100458394 /* main.swift in Sources */,
|
||||||
D4A13D5A27A59F0B003BE359 /* ctlInputMethod.swift in Sources */,
|
D4A13D5A27A59F0B003BE359 /* ctlInputMethod.swift in Sources */,
|
||||||
5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.swift in Sources */,
|
5BA9FD4827FEF3C9002DE248 /* PreferencesWindowController.swift in Sources */,
|
||||||
5BC4F6382819FF4500A2514A /* KeyHandlerSputnik.swift in Sources */,
|
|
||||||
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
|
5BD0113B28180D6100609769 /* LMInstantiator.swift in Sources */,
|
||||||
D4E569DC27A34D0E00AC2CEF /* KeyHandler.mm in Sources */,
|
D4E569DC27A34D0E00AC2CEF /* CTools.m in Sources */,
|
||||||
5BA9FD4627FEF3C9002DE248 /* Container.swift in Sources */,
|
5BA9FD4627FEF3C9002DE248 /* Container.swift in Sources */,
|
||||||
D47F7DD0278C0897002F9DD7 /* ctlNonModalAlertWindow.swift in Sources */,
|
D47F7DD0278C0897002F9DD7 /* ctlNonModalAlertWindow.swift in Sources */,
|
||||||
5B38F5A2281E2E49007D5F5D /* 0_Megrez.swift in Sources */,
|
5B38F5A2281E2E49007D5F5D /* 0_Megrez.swift in Sources */,
|
||||||
|
@ -1101,7 +1102,7 @@
|
||||||
5BA9FD4327FEF3C8002DE248 /* Preferences.swift in Sources */,
|
5BA9FD4327FEF3C8002DE248 /* Preferences.swift in Sources */,
|
||||||
5BA9FD4427FEF3C8002DE248 /* SegmentedControlStyleViewController.swift in Sources */,
|
5BA9FD4427FEF3C8002DE248 /* SegmentedControlStyleViewController.swift in Sources */,
|
||||||
D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */,
|
D47F7DCE278BFB57002F9DD7 /* ctlPrefWindow.swift in Sources */,
|
||||||
5BD0113D2818543900609769 /* KeyHandler_Kernel.swift in Sources */,
|
5BD0113D2818543900609769 /* KeyHandler_Core.swift in Sources */,
|
||||||
5BA9FD4227FEF3C8002DE248 /* PreferencePane.swift in Sources */,
|
5BA9FD4227FEF3C8002DE248 /* PreferencePane.swift in Sources */,
|
||||||
5BA0DF312817857D009E73BB /* lmUserOverride.swift in Sources */,
|
5BA0DF312817857D009E73BB /* lmUserOverride.swift in Sources */,
|
||||||
5BA9FD8B28006B41002DE248 /* VDKComboBox.swift in Sources */,
|
5BA9FD8B28006B41002DE248 /* VDKComboBox.swift in Sources */,
|
||||||
|
@ -1117,6 +1118,7 @@
|
||||||
5B62A33827AE79CD00A19448 /* NSStringUtils.swift in Sources */,
|
5B62A33827AE79CD00A19448 /* NSStringUtils.swift in Sources */,
|
||||||
5BA9FD0F27FEDB6B002DE248 /* suiPrefPaneGeneral.swift in Sources */,
|
5BA9FD0F27FEDB6B002DE248 /* suiPrefPaneGeneral.swift in Sources */,
|
||||||
5BA9FD4927FEF3C9002DE248 /* Section.swift in Sources */,
|
5BA9FD4927FEF3C9002DE248 /* Section.swift in Sources */,
|
||||||
|
5B407153281F94E6009C24CB /* Composer.mm in Sources */,
|
||||||
5BA9FD3E27FEF3C8002DE248 /* Utilities.swift in Sources */,
|
5BA9FD3E27FEF3C8002DE248 /* Utilities.swift in Sources */,
|
||||||
5BA9FD1127FEDB6B002DE248 /* ctlPrefUI.swift in Sources */,
|
5BA9FD1127FEDB6B002DE248 /* ctlPrefUI.swift in Sources */,
|
||||||
5B38F59C281E2E49007D5F5D /* 2_Grid.swift in Sources */,
|
5B38F59C281E2E49007D5F5D /* 2_Grid.swift in Sources */,
|
||||||
|
|
Loading…
Reference in New Issue