KeyHandler // Refactoring with modern Swift expressions.
This commit is contained in:
parent
e77d67370b
commit
45c877b3f9
|
@ -289,7 +289,7 @@ class InputState {
|
|||
"<InputState.Marking, composingBuffer:\(composingBuffer), cursorIndex:\(cursorIndex), markedRange:\(markedRange)>"
|
||||
}
|
||||
|
||||
func convertToInputting() -> Inputting {
|
||||
var convertedToInputting: Inputting {
|
||||
let state = Inputting(composingBuffer: composingBuffer, cursorIndex: cursorIndex)
|
||||
state.tooltip = tooltipForInputting
|
||||
return state
|
||||
|
|
|
@ -68,13 +68,35 @@ class KeyHandler {
|
|||
return InputMode.imeModeNULL
|
||||
}
|
||||
}
|
||||
set { setInputMode(newValue.rawValue) }
|
||||
set {
|
||||
let isCHS: Bool = (newValue == InputMode.imeModeCHS)
|
||||
|
||||
// 緊接著將新的簡繁輸入模式提報給 ctlInputMethod:
|
||||
ctlInputMethod.currentInputMode = isCHS ? InputMode.imeModeCHS.rawValue : InputMode.imeModeCHT.rawValue
|
||||
mgrPrefs.mostRecentInputMode = ctlInputMethod.currentInputMode
|
||||
|
||||
// 拿當前的 _inputMode 與 ctlInputMethod 的提報結果對比,不同的話則套用新設定:
|
||||
if _inputMode != ctlInputMethod.currentInputMode {
|
||||
// Reinitiate language models if necessary
|
||||
_languageModel = isCHS ? mgrLangModel.lmCHS : mgrLangModel.lmCHT
|
||||
_userOverrideModel = isCHS ? mgrLangModel.uomCHS : mgrLangModel.uomCHT
|
||||
|
||||
// Synchronize the sub-languageModel state settings to the new LM.
|
||||
syncBaseLMPrefs()
|
||||
|
||||
// Create new grid builder and clear the composer.
|
||||
createNewBuilder()
|
||||
_composer.clear()
|
||||
}
|
||||
// 直接寫到衛星模組內,省得類型轉換
|
||||
_inputMode = ctlInputMethod.currentInputMode
|
||||
}
|
||||
}
|
||||
|
||||
public init() {
|
||||
_builder = Megrez.BlockReadingBuilder(lm: _languageModel, separator: "-")
|
||||
ensureParser()
|
||||
setInputMode(ctlInputMethod.currentInputMode)
|
||||
inputMode = InputMode(rawValue: ctlInputMethod.currentInputMode) ?? InputMode.imeModeNULL
|
||||
}
|
||||
|
||||
func clear() {
|
||||
|
@ -83,34 +105,6 @@ class KeyHandler {
|
|||
_walkedNodes.removeAll()
|
||||
}
|
||||
|
||||
func setInputMode(_ value: String) {
|
||||
// 下面這句的「isKindOfClass」是做類型檢查,
|
||||
// 為了應對出現輸入法 plist 被改壞掉這樣的極端情況。
|
||||
let isCHS: Bool = (value == InputMode.imeModeCHS.rawValue)
|
||||
|
||||
// 緊接著將新的簡繁輸入模式提報給 ctlInputMethod:
|
||||
ctlInputMethod.currentInputMode = isCHS ? InputMode.imeModeCHS.rawValue : InputMode.imeModeCHT.rawValue
|
||||
mgrPrefs.mostRecentInputMode = ctlInputMethod.currentInputMode
|
||||
|
||||
// 拿當前的 _inputMode 與 ctlInputMethod 的提報結果對比,不同的話則套用新設定:
|
||||
if _inputMode != ctlInputMethod.currentInputMode {
|
||||
// Reinitiate language models if necessary
|
||||
setInputModesToLM(isCHS: isCHS)
|
||||
|
||||
// Synchronize the sub-languageModel state settings to the new LM.
|
||||
syncBaseLMPrefs()
|
||||
|
||||
// Create new grid builder.
|
||||
createNewBuilder()
|
||||
|
||||
if !_composer.isEmpty {
|
||||
_composer.clear()
|
||||
}
|
||||
}
|
||||
// 直接寫到衛星模組內,省得類型轉換
|
||||
_inputMode = ctlInputMethod.currentInputMode
|
||||
}
|
||||
|
||||
// MARK: - Functions dealing with Megrez.
|
||||
|
||||
func walk() {
|
||||
|
@ -121,7 +115,7 @@ class KeyHandler {
|
|||
_walkedNodes = _builder.walk(at: _builder.grid.width, nodesLimit: 10, balanced: true)
|
||||
}
|
||||
|
||||
func popOverflowComposingTextAndWalk() -> String {
|
||||
var popOverflowComposingTextAndWalk: String {
|
||||
// In ideal situations we can allow users to type infinitely in a buffer.
|
||||
// However, Viberti algorithm has a complexity of O(N^2), the walk will
|
||||
// become slower as the number of nodes increase. Therefore, we need to
|
||||
|
@ -153,7 +147,7 @@ class KeyHandler {
|
|||
}
|
||||
|
||||
func fixNode(value: String) {
|
||||
let cursorIndex: Int = getActualCandidateCursorIndex()
|
||||
let cursorIndex: Int = actualCandidateCursorIndex
|
||||
let selectedNode: Megrez.NodeAnchor = _builder.grid.fixNodeSelectedCandidate(
|
||||
location: cursorIndex, value: value
|
||||
)
|
||||
|
@ -192,16 +186,16 @@ class KeyHandler {
|
|||
if nextPosition >= cursorIndex { break }
|
||||
nextPosition += node.spanningLength
|
||||
}
|
||||
if nextPosition <= getBuilderLength() {
|
||||
setBuilderCursorIndex(value: nextPosition)
|
||||
if nextPosition <= builderLength {
|
||||
builderCursorIndex = nextPosition
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func getCandidatesArray() -> [String] {
|
||||
var candidatesArray: [String] {
|
||||
var arrCandidates: [String] = []
|
||||
var arrNodes: [Megrez.NodeAnchor] = []
|
||||
arrNodes.append(contentsOf: getRawNodes())
|
||||
arrNodes.append(contentsOf: rawNodes)
|
||||
|
||||
/// 原理:nodes 這個回饋結果包含一堆子陣列,分別對應不同詞長的候選字。
|
||||
/// 這裡先對陣列排序、讓最長候選字的子陣列的優先權最高。
|
||||
|
@ -228,7 +222,7 @@ class KeyHandler {
|
|||
mgrPrefs.useSCPCTypingMode
|
||||
? ""
|
||||
: _userOverrideModel.suggest(
|
||||
walkedNodes: _walkedNodes, cursorIndex: getBuilderCursorIndex(),
|
||||
walkedNodes: _walkedNodes, cursorIndex: builderCursorIndex,
|
||||
timestamp: NSDate().timeIntervalSince1970
|
||||
)
|
||||
|
||||
|
@ -236,9 +230,9 @@ class KeyHandler {
|
|||
IME.prtDebugIntel(
|
||||
"UOM: Suggestion retrieved, overriding the node score of the selected candidate.")
|
||||
_builder.grid.overrideNodeScoreForSelectedCandidate(
|
||||
location: getActualCandidateCursorIndex(),
|
||||
location: actualCandidateCursorIndex,
|
||||
value: overrideValue,
|
||||
overridingScore: findHighestScore(nodes: getRawNodes(), epsilon: kEpsilon)
|
||||
overridingScore: findHighestScore(nodes: rawNodes, epsilon: kEpsilon)
|
||||
)
|
||||
} else {
|
||||
IME.prtDebugIntel("UOM: Blank suggestion retrieved, dismissing.")
|
||||
|
@ -258,69 +252,6 @@ class KeyHandler {
|
|||
return highestScore + epsilon
|
||||
}
|
||||
|
||||
// MARK: - Extracted methods and functions (Megrez).
|
||||
|
||||
func isBuilderEmpty() -> Bool { _builder.grid.width == 0 }
|
||||
|
||||
func getRawNodes() -> [Megrez.NodeAnchor] {
|
||||
/// 警告:不要對游標前置風格使用 nodesCrossing,否則會導致游標行為與 macOS 內建注音輸入法不一致。
|
||||
/// 微軟新注音輸入法的游標後置風格也是不允許 nodeCrossing 的,但目前 Megrez 暫時缺乏對該特性的支援。
|
||||
/// 所以暫時只能將威注音的游標後置風格描述成「跟 Windows 版雅虎奇摩注音一致」。
|
||||
mgrPrefs.setRearCursorMode
|
||||
? _builder.grid.nodesCrossingOrEndingAt(location: getActualCandidateCursorIndex())
|
||||
: _builder.grid.nodesEndingAt(location: getActualCandidateCursorIndex())
|
||||
}
|
||||
|
||||
func setInputModesToLM(isCHS: Bool) {
|
||||
_languageModel = isCHS ? mgrLangModel.lmCHS : mgrLangModel.lmCHT
|
||||
_userOverrideModel = isCHS ? mgrLangModel.uomCHS : mgrLangModel.uomCHT
|
||||
}
|
||||
|
||||
func syncBaseLMPrefs() {
|
||||
_languageModel.isPhraseReplacementEnabled = mgrPrefs.phraseReplacementEnabled
|
||||
_languageModel.isCNSEnabled = mgrPrefs.cns11643Enabled
|
||||
_languageModel.isSymbolEnabled = mgrPrefs.symbolInputEnabled
|
||||
}
|
||||
|
||||
func createNewBuilder() {
|
||||
// Each Mandarin syllable is separated by a hyphen.
|
||||
_builder = Megrez.BlockReadingBuilder(lm: _languageModel, separator: "-")
|
||||
}
|
||||
|
||||
func currentReadings() -> [String] { _builder.readings }
|
||||
|
||||
func ifLangModelHasUnigrams(forKey reading: String) -> Bool {
|
||||
_languageModel.hasUnigramsFor(key: reading)
|
||||
}
|
||||
|
||||
func insertReadingToBuilderAtCursor(reading: String) {
|
||||
_builder.insertReadingAtCursor(reading: reading)
|
||||
}
|
||||
|
||||
func setBuilderCursorIndex(value: Int) {
|
||||
_builder.cursorIndex = value
|
||||
}
|
||||
|
||||
func getBuilderCursorIndex() -> Int {
|
||||
_builder.cursorIndex
|
||||
}
|
||||
|
||||
func getBuilderLength() -> Int {
|
||||
_builder.length
|
||||
}
|
||||
|
||||
func deleteBuilderReadingInFrontOfCursor() {
|
||||
_builder.deleteReadingAtTheRearOfCursor()
|
||||
}
|
||||
|
||||
func deleteBuilderReadingToTheFrontOfCursor() {
|
||||
_builder.deleteReadingToTheFrontOfCursor()
|
||||
}
|
||||
|
||||
func getKeyLengthAtIndexZero() -> Int {
|
||||
_walkedNodes[0].node?.currentKeyValue.value.count ?? 0
|
||||
}
|
||||
|
||||
// MARK: - Extracted methods and functions (Tekkon).
|
||||
|
||||
func ensureParser() {
|
||||
|
@ -357,4 +288,59 @@ class KeyHandler {
|
|||
}
|
||||
_composer.clear()
|
||||
}
|
||||
|
||||
// MARK: - Extracted methods and functions (Megrez).
|
||||
|
||||
var isBuilderEmpty: Bool { _builder.grid.width == 0 }
|
||||
|
||||
var rawNodes: [Megrez.NodeAnchor] {
|
||||
/// 警告:不要對游標前置風格使用 nodesCrossing,否則會導致游標行為與 macOS 內建注音輸入法不一致。
|
||||
/// 微軟新注音輸入法的游標後置風格也是不允許 nodeCrossing 的,但目前 Megrez 暫時缺乏對該特性的支援。
|
||||
/// 所以暫時只能將威注音的游標後置風格描述成「跟 Windows 版雅虎奇摩注音一致」。
|
||||
mgrPrefs.setRearCursorMode
|
||||
? _builder.grid.nodesCrossingOrEndingAt(location: actualCandidateCursorIndex)
|
||||
: _builder.grid.nodesEndingAt(location: actualCandidateCursorIndex)
|
||||
}
|
||||
|
||||
func syncBaseLMPrefs() {
|
||||
_languageModel.isPhraseReplacementEnabled = mgrPrefs.phraseReplacementEnabled
|
||||
_languageModel.isCNSEnabled = mgrPrefs.cns11643Enabled
|
||||
_languageModel.isSymbolEnabled = mgrPrefs.symbolInputEnabled
|
||||
}
|
||||
|
||||
func createNewBuilder() {
|
||||
// Each Mandarin syllable is separated by a hyphen.
|
||||
_builder = Megrez.BlockReadingBuilder(lm: _languageModel, separator: "-")
|
||||
}
|
||||
|
||||
var currentReadings: [String] { _builder.readings }
|
||||
|
||||
func ifLangModelHasUnigrams(forKey reading: String) -> Bool {
|
||||
_languageModel.hasUnigramsFor(key: reading)
|
||||
}
|
||||
|
||||
func insertReadingToBuilderAtCursor(reading: String) {
|
||||
_builder.insertReadingAtCursor(reading: reading)
|
||||
}
|
||||
|
||||
var builderCursorIndex: Int {
|
||||
get { _builder.cursorIndex }
|
||||
set { _builder.cursorIndex = newValue }
|
||||
}
|
||||
|
||||
var builderLength: Int {
|
||||
_builder.length
|
||||
}
|
||||
|
||||
func deleteBuilderReadingInFrontOfCursor() {
|
||||
_builder.deleteReadingAtTheRearOfCursor()
|
||||
}
|
||||
|
||||
func deleteBuilderReadingToTheFrontOfCursor() {
|
||||
_builder.deleteReadingToTheFrontOfCursor()
|
||||
}
|
||||
|
||||
var keyLengthAtIndexZero: Int {
|
||||
_walkedNodes[0].node?.currentKeyValue.value.count ?? 0
|
||||
}
|
||||
}
|
||||
|
|
|
@ -47,16 +47,16 @@ extension KeyHandler {
|
|||
if cancelCandidateKey {
|
||||
if (state is InputState.AssociatedPhrases)
|
||||
|| mgrPrefs.useSCPCTypingMode
|
||||
|| isBuilderEmpty()
|
||||
|| isBuilderEmpty
|
||||
{
|
||||
// 如果此時發現當前組字緩衝區為真空的情況的話,
|
||||
// 就將當前的組字緩衝區析構處理、強制重設輸入狀態。
|
||||
// 否則,一個本不該出現的真空組字緩衝區會使前後方向鍵與 BackSpace 鍵失靈。
|
||||
// 所以這裡需要對 isBuilderEmpty() 做判定。
|
||||
// 所以這裡需要對 isBuilderEmpty 做判定。
|
||||
clear()
|
||||
stateCallback(InputState.EmptyIgnoringPreviousState())
|
||||
} else {
|
||||
stateCallback(buildInputtingState())
|
||||
stateCallback(buildInputtingState)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ extension KeyHandler {
|
|||
punctuationNamePrefix = "_punctuation_"
|
||||
}
|
||||
|
||||
let parser = getCurrentMandarinParser()
|
||||
let parser = currentMandarinParser
|
||||
|
||||
let arrCustomPunctuations: [String] = [
|
||||
punctuationNamePrefix, parser, String(format: "%c", CChar(charCode)),
|
||||
|
|
|
@ -135,7 +135,7 @@ extension KeyHandler {
|
|||
) {
|
||||
return true
|
||||
}
|
||||
state = marking.convertToInputting()
|
||||
state = marking.convertedToInputting
|
||||
stateCallback(state)
|
||||
}
|
||||
|
||||
|
@ -154,7 +154,7 @@ extension KeyHandler {
|
|||
// update the composing buffer.
|
||||
let composeReading = _composer.hasToneMarker()
|
||||
if !composeReading {
|
||||
stateCallback(buildInputtingState())
|
||||
stateCallback(buildInputtingState)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -166,7 +166,7 @@ extension KeyHandler {
|
|||
// However, Swift does not support "|=".
|
||||
composeReading = composeReading || (!_composer.isEmpty && (input.isSpace || input.isEnter))
|
||||
if composeReading {
|
||||
if input.isSpace && !_composer.hasToneMarker() {
|
||||
if input.isSpace, !_composer.hasToneMarker() {
|
||||
_composer.receiveKey(fromString: " ") // 補上空格。
|
||||
}
|
||||
let reading = _composer.getComposition()
|
||||
|
@ -176,7 +176,7 @@ extension KeyHandler {
|
|||
IME.prtDebugIntel("B49C0979:語彙庫內無「\(reading)」的匹配記錄。")
|
||||
errorCallback()
|
||||
_composer.clear()
|
||||
stateCallback((getBuilderLength() == 0) ? InputState.EmptyIgnoringPreviousState() : buildInputtingState())
|
||||
stateCallback((builderLength == 0) ? InputState.EmptyIgnoringPreviousState() : buildInputtingState)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -184,7 +184,7 @@ extension KeyHandler {
|
|||
insertReadingToBuilderAtCursor(reading: reading)
|
||||
|
||||
// ... then walk the grid...
|
||||
let poppedText = popOverflowComposingTextAndWalk()
|
||||
let poppedText = popOverflowComposingTextAndWalk
|
||||
|
||||
// ... get and tweak override model suggestion if possible...
|
||||
dealWithOverrideModelSuggestions()
|
||||
|
@ -192,7 +192,7 @@ extension KeyHandler {
|
|||
// ... then update the text.
|
||||
_composer.clear()
|
||||
|
||||
let inputting = buildInputtingState()
|
||||
let inputting = buildInputtingState
|
||||
inputting.poppedText = poppedText
|
||||
stateCallback(inputting)
|
||||
|
||||
|
@ -233,7 +233,7 @@ extension KeyHandler {
|
|||
// but does not compose. Only sequences such as "ㄧˊ", "ˊㄧˊ", "ˊㄧˇ", or "ˊㄧ "
|
||||
// would compose.
|
||||
if keyConsumedByReading {
|
||||
stateCallback(buildInputtingState())
|
||||
stateCallback(buildInputtingState)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -247,7 +247,7 @@ extension KeyHandler {
|
|||
if input.isSpace {
|
||||
// If the Space key is NOT set to be a selection key
|
||||
if input.isShiftHold || !mgrPrefs.chooseCandidateUsingSpace {
|
||||
if getBuilderCursorIndex() >= getBuilderLength() {
|
||||
if builderCursorIndex >= builderLength {
|
||||
let composingBuffer = currentState.composingBuffer
|
||||
if !composingBuffer.isEmpty {
|
||||
stateCallback(InputState.Committing(poppedText: composingBuffer))
|
||||
|
@ -257,8 +257,8 @@ extension KeyHandler {
|
|||
stateCallback(InputState.Empty())
|
||||
} else if ifLangModelHasUnigrams(forKey: " ") {
|
||||
insertReadingToBuilderAtCursor(reading: " ")
|
||||
let poppedText = popOverflowComposingTextAndWalk()
|
||||
let inputting = buildInputtingState()
|
||||
let poppedText = popOverflowComposingTextAndWalk
|
||||
let inputting = buildInputtingState
|
||||
inputting.poppedText = poppedText
|
||||
stateCallback(inputting)
|
||||
}
|
||||
|
@ -355,8 +355,8 @@ extension KeyHandler {
|
|||
if ifLangModelHasUnigrams(forKey: "_punctuation_list") {
|
||||
if _composer.isEmpty {
|
||||
insertReadingToBuilderAtCursor(reading: "_punctuation_list")
|
||||
let poppedText: String! = popOverflowComposingTextAndWalk()
|
||||
let inputting = buildInputtingState()
|
||||
let poppedText: String! = popOverflowComposingTextAndWalk
|
||||
let inputting = buildInputtingState
|
||||
inputting.poppedText = poppedText
|
||||
stateCallback(inputting)
|
||||
stateCallback(buildCandidate(state: inputting, useVerticalMode: input.useVerticalMode))
|
||||
|
@ -392,7 +392,7 @@ extension KeyHandler {
|
|||
punctuationNamePrefix = "_punctuation_"
|
||||
}
|
||||
|
||||
let parser = getCurrentMandarinParser()
|
||||
let parser = currentMandarinParser
|
||||
let arrCustomPunctuations: [String] = [
|
||||
punctuationNamePrefix, parser, String(format: "%c", CChar(charCode)),
|
||||
]
|
||||
|
|
|
@ -29,22 +29,22 @@ import Cocoa
|
|||
// MARK: - § Misc functions.
|
||||
|
||||
extension KeyHandler {
|
||||
func getCurrentMandarinParser() -> String {
|
||||
var currentMandarinParser: String {
|
||||
mgrPrefs.mandarinParserName + "_"
|
||||
}
|
||||
|
||||
func getActualCandidateCursorIndex() -> Int {
|
||||
var cursorIndex = getBuilderCursorIndex()
|
||||
var actualCandidateCursorIndex: Int {
|
||||
var cursorIndex = builderCursorIndex
|
||||
// Windows Yahoo Kimo IME style, phrase is *at the rear of* the cursor.
|
||||
// (i.e. the cursor is always *before* the phrase.)
|
||||
// This is different from MS Phonetics IME style ...
|
||||
// ... since Windows Yahoo Kimo allows "node crossing".
|
||||
if (mgrPrefs.setRearCursorMode
|
||||
&& (cursorIndex < getBuilderLength()))
|
||||
&& (cursorIndex < builderLength))
|
||||
|| cursorIndex == 0
|
||||
{
|
||||
if cursorIndex == 0, !mgrPrefs.setRearCursorMode {
|
||||
cursorIndex += getKeyLengthAtIndexZero()
|
||||
cursorIndex += keyLengthAtIndexZero
|
||||
} else {
|
||||
cursorIndex += 1
|
||||
}
|
||||
|
|
|
@ -31,14 +31,14 @@ import Cocoa
|
|||
extension KeyHandler {
|
||||
// MARK: - 構築狀態(State Building)
|
||||
|
||||
func buildInputtingState() -> InputState.Inputting {
|
||||
var buildInputtingState: InputState.Inputting {
|
||||
// "Updating the composing buffer" means to request the client
|
||||
// to "refresh" the text input buffer with our "composing text"
|
||||
var composingBuffer = ""
|
||||
var composedStringCursorIndex = 0
|
||||
|
||||
var readingCursorIndex = 0
|
||||
let builderCursorIndex = getBuilderCursorIndex()
|
||||
let builderCursorIndex = builderCursorIndex
|
||||
|
||||
for theAnchor in _walkedNodes {
|
||||
guard let node = theAnchor.node else {
|
||||
|
@ -106,7 +106,7 @@ extension KeyHandler {
|
|||
InputState.ChoosingCandidate(
|
||||
composingBuffer: currentState.composingBuffer,
|
||||
cursorIndex: currentState.cursorIndex,
|
||||
candidates: getCandidatesArray(),
|
||||
candidates: candidatesArray,
|
||||
useVerticalMode: useVerticalMode
|
||||
)
|
||||
}
|
||||
|
@ -115,7 +115,7 @@ extension KeyHandler {
|
|||
|
||||
// 這次重寫時,針對「buildAssociatePhraseStateWithKey」這個(用以生成帶有
|
||||
// 聯想詞候選清單的結果的狀態回呼的)函數進行了小幅度的重構處理,使其始終
|
||||
// 可以從 ObjC 部分的「buildAssociatePhraseArray」函數獲取到一個內容類型
|
||||
// 可以從 Core 部分的「buildAssociatePhraseArray」函數獲取到一個內容類型
|
||||
// 為「String」的標準 Swift 陣列。這樣一來,該聯想詞狀態回呼函數將始終能
|
||||
// 夠傳回正確的結果形態、永遠也無法傳回 nil。於是,所有在用到該函數時以
|
||||
// 回傳結果類型判斷作為合法性判斷依據的函數,全都將依據改為檢查傳回的陣列
|
||||
|
@ -139,7 +139,7 @@ extension KeyHandler {
|
|||
errorCallback: @escaping () -> Void
|
||||
) -> Bool {
|
||||
if input.isESC {
|
||||
stateCallback(buildInputtingState())
|
||||
stateCallback(buildInputtingState)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -152,7 +152,7 @@ extension KeyHandler {
|
|||
return true
|
||||
}
|
||||
}
|
||||
stateCallback(buildInputtingState())
|
||||
stateCallback(buildInputtingState)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -168,7 +168,7 @@ extension KeyHandler {
|
|||
readings: state.readings
|
||||
)
|
||||
marking.tooltipForInputting = state.tooltipForInputting
|
||||
stateCallback(marking.markedRange.length == 0 ? marking.convertToInputting() : marking)
|
||||
stateCallback(marking.markedRange.length == 0 ? marking.convertedToInputting : marking)
|
||||
} else {
|
||||
IME.prtDebugIntel("1149908D")
|
||||
errorCallback()
|
||||
|
@ -191,7 +191,7 @@ extension KeyHandler {
|
|||
readings: state.readings
|
||||
)
|
||||
marking.tooltipForInputting = state.tooltipForInputting
|
||||
stateCallback(marking.markedRange.length == 0 ? marking.convertToInputting() : marking)
|
||||
stateCallback(marking.markedRange.length == 0 ? marking.convertedToInputting : marking)
|
||||
} else {
|
||||
IME.prtDebugIntel("9B51408D")
|
||||
errorCallback()
|
||||
|
@ -217,8 +217,8 @@ extension KeyHandler {
|
|||
|
||||
if _composer.isEmpty {
|
||||
insertReadingToBuilderAtCursor(reading: customPunctuation)
|
||||
let poppedText = popOverflowComposingTextAndWalk()
|
||||
let inputting = buildInputtingState()
|
||||
let poppedText = popOverflowComposingTextAndWalk
|
||||
let inputting = buildInputtingState
|
||||
inputting.poppedText = poppedText
|
||||
stateCallback(inputting)
|
||||
|
||||
|
@ -273,7 +273,7 @@ extension KeyHandler {
|
|||
) -> Bool {
|
||||
guard state is InputState.Inputting else { return false }
|
||||
|
||||
var composingBuffer = currentReadings().joined(separator: "-")
|
||||
var composingBuffer = currentReadings.joined(separator: "-")
|
||||
if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin {
|
||||
composingBuffer = restoreToneOneInZhuyinKey(target: composingBuffer) // 恢復陰平標記
|
||||
composingBuffer = Tekkon.cnvPhonaToHanyuPinyin(target: composingBuffer) // 注音轉拼音
|
||||
|
@ -341,7 +341,7 @@ extension KeyHandler {
|
|||
if _composer.hasToneMarker(withNothingElse: true) {
|
||||
_composer.clear()
|
||||
} else if _composer.isEmpty {
|
||||
if getBuilderCursorIndex() >= 0 {
|
||||
if builderCursorIndex >= 0 {
|
||||
deleteBuilderReadingInFrontOfCursor()
|
||||
walk()
|
||||
} else {
|
||||
|
@ -354,10 +354,10 @@ extension KeyHandler {
|
|||
_composer.doBackSpace()
|
||||
}
|
||||
|
||||
if _composer.isEmpty, getBuilderLength() == 0 {
|
||||
if _composer.isEmpty, builderLength == 0 {
|
||||
stateCallback(InputState.EmptyIgnoringPreviousState())
|
||||
} else {
|
||||
stateCallback(buildInputtingState())
|
||||
stateCallback(buildInputtingState)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
@ -372,10 +372,10 @@ extension KeyHandler {
|
|||
guard state is InputState.Inputting else { return false }
|
||||
|
||||
if _composer.isEmpty {
|
||||
if getBuilderCursorIndex() != getBuilderLength() {
|
||||
if builderCursorIndex != builderLength {
|
||||
deleteBuilderReadingToTheFrontOfCursor()
|
||||
walk()
|
||||
let inputting = buildInputtingState()
|
||||
let inputting = buildInputtingState
|
||||
// 這裡不用「count > 0」,因為該整數變數只要「!isEmpty」那就必定滿足這個條件。
|
||||
if inputting.composingBuffer.isEmpty {
|
||||
stateCallback(InputState.EmptyIgnoringPreviousState())
|
||||
|
@ -428,9 +428,9 @@ extension KeyHandler {
|
|||
return true
|
||||
}
|
||||
|
||||
if getBuilderCursorIndex() != 0 {
|
||||
setBuilderCursorIndex(value: 0)
|
||||
stateCallback(buildInputtingState())
|
||||
if builderCursorIndex != 0 {
|
||||
builderCursorIndex = 0
|
||||
stateCallback(buildInputtingState)
|
||||
} else {
|
||||
IME.prtDebugIntel("66D97F90")
|
||||
errorCallback()
|
||||
|
@ -456,9 +456,9 @@ extension KeyHandler {
|
|||
return true
|
||||
}
|
||||
|
||||
if getBuilderCursorIndex() != getBuilderLength() {
|
||||
setBuilderCursorIndex(value: getBuilderLength())
|
||||
stateCallback(buildInputtingState())
|
||||
if builderCursorIndex != builderLength {
|
||||
builderCursorIndex = builderLength
|
||||
stateCallback(buildInputtingState)
|
||||
} else {
|
||||
IME.prtDebugIntel("9B69908E")
|
||||
errorCallback()
|
||||
|
@ -490,10 +490,10 @@ extension KeyHandler {
|
|||
// If reading is not empty, we cancel the reading.
|
||||
if !_composer.isEmpty {
|
||||
_composer.clear()
|
||||
if getBuilderLength() == 0 {
|
||||
if builderLength == 0 {
|
||||
stateCallback(InputState.EmptyIgnoringPreviousState())
|
||||
} else {
|
||||
stateCallback(buildInputtingState())
|
||||
stateCallback(buildInputtingState)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -526,7 +526,7 @@ extension KeyHandler {
|
|||
composingBuffer: currentState.composingBuffer,
|
||||
cursorIndex: currentState.cursorIndex,
|
||||
markerIndex: UInt(nextPosition),
|
||||
readings: currentReadings()
|
||||
readings: currentReadings
|
||||
)
|
||||
marking.tooltipForInputting = currentState.tooltip
|
||||
stateCallback(marking)
|
||||
|
@ -536,9 +536,9 @@ extension KeyHandler {
|
|||
stateCallback(state)
|
||||
}
|
||||
} else {
|
||||
if getBuilderCursorIndex() < getBuilderLength() {
|
||||
setBuilderCursorIndex(value: getBuilderCursorIndex() + 1)
|
||||
stateCallback(buildInputtingState())
|
||||
if builderCursorIndex < builderLength {
|
||||
builderCursorIndex += 1
|
||||
stateCallback(buildInputtingState)
|
||||
} else {
|
||||
IME.prtDebugIntel("A96AAD58")
|
||||
errorCallback()
|
||||
|
@ -575,7 +575,7 @@ extension KeyHandler {
|
|||
composingBuffer: currentState.composingBuffer,
|
||||
cursorIndex: currentState.cursorIndex,
|
||||
markerIndex: UInt(previousPosition),
|
||||
readings: currentReadings()
|
||||
readings: currentReadings
|
||||
)
|
||||
marking.tooltipForInputting = currentState.tooltip
|
||||
stateCallback(marking)
|
||||
|
@ -585,9 +585,9 @@ extension KeyHandler {
|
|||
stateCallback(state)
|
||||
}
|
||||
} else {
|
||||
if getBuilderCursorIndex() > 0 {
|
||||
setBuilderCursorIndex(value: getBuilderCursorIndex() - 1)
|
||||
stateCallback(buildInputtingState())
|
||||
if builderCursorIndex > 0 {
|
||||
builderCursorIndex -= 1
|
||||
stateCallback(buildInputtingState)
|
||||
} else {
|
||||
IME.prtDebugIntel("7045E6F3")
|
||||
errorCallback()
|
||||
|
|
|
@ -648,7 +648,7 @@ extension ctlInputMethod: ctlCandidateDelegate {
|
|||
let selectedValue = state.candidates[Int(index)]
|
||||
keyHandler.fixNode(value: selectedValue)
|
||||
|
||||
let inputting = keyHandler.buildInputtingState()
|
||||
let inputting = keyHandler.buildInputtingState
|
||||
|
||||
if mgrPrefs.useSCPCTypingMode {
|
||||
keyHandler.clear()
|
||||
|
|
Loading…
Reference in New Issue