diff --git a/Source/Modules/ControllerModules/KeyHandler_Core.swift b/Source/Modules/ControllerModules/KeyHandler_Core.swift index aa85b107..d1147792 100644 --- a/Source/Modules/ControllerModules/KeyHandler_Core.swift +++ b/Source/Modules/ControllerModules/KeyHandler_Core.swift @@ -103,7 +103,7 @@ class KeyHandler { /// /// 威注音對游標前置與游標後置模式採取的候選字節點陣列抓取方法是分離的,且不使用 Node Crossing。 var actualCandidateCursor: Int { - mgrPrefs.useRearCursorMode ? min(compositorCursorIndex, compositorLength - 1) : max(compositorCursorIndex, 1) + mgrPrefs.useRearCursorMode ? min(compositor.cursor, compositor.length - 1) : max(compositor.cursor, 1) } /// 利用給定的讀音鏈來試圖爬取最接近的組字結果(最大相似度估算)。 @@ -164,7 +164,7 @@ class KeyHandler { /// - respectCursorPushing: 若該選項為 true,則會在選字之後始終將游標推送至選字後的節錨的前方。 func fixNode(candidate: (String, String), respectCursorPushing: Bool = true) { let theCandidate: Megrez.KeyValuePaired = .init(key: candidate.0, value: candidate.1) - let adjustedCursor = max(0, min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositorLength)) + let adjustedCursor = max(0, min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length)) // 開始讓半衰模組觀察目前的狀況。 let selectedNode: Megrez.NodeAnchor = compositor.fixNodeWithCandidate(theCandidate, at: adjustedCursor) // 不要針對逐字選字模式啟用臨時半衰記憶模型。 @@ -254,7 +254,7 @@ class KeyHandler { /// 向半衰引擎詢問可能的選字建議。拿到的結果會是一個單元圖陣列。 func fetchSuggestedCandidates() -> [Megrez.Unigram] { currentUOM.suggest( - walkedAnchors: walkedAnchors, cursorIndex: compositorCursorIndex, + walkedAnchors: walkedAnchors, cursorIndex: compositor.cursor, timestamp: NSDate().timeIntervalSince1970 ) } @@ -273,7 +273,7 @@ class KeyHandler { IME.prtDebugIntel( "UOM: Suggestion retrieved, overriding the node score of the selected candidate.") compositor.overrideNodeScoreForSelectedCandidate( - location: min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositorLength), + location: min(actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length), value: overrideValue, overridingScore: findHighestScore(nodeAnchors: rawAnchorsOfNodes, epsilon: kEpsilon) ) @@ -337,9 +337,6 @@ class KeyHandler { // MARK: - Extracted methods and functions (Megrez). - /// 組字器是否為空。 - var isCompositorEmpty: Bool { compositor.isEmpty } - /// 獲取原始節錨資料陣列。 var rawAnchorsOfNodes: [Megrez.NodeAnchor] { /// 警告:不要對游標前置風格使用 nodesCrossing,否則會導致游標行為與 macOS 內建注音輸入法不一致。 @@ -362,44 +359,6 @@ class KeyHandler { compositor = Megrez.Compositor(lm: currentLM, separator: "-") } - /// 自組字器獲取目前的讀音陣列。 - var currentReadings: [String] { compositor.readings } - - /// 以給定的(讀音)索引鍵,來檢測當前主語言模型內是否有對應的資料在庫。 - func ifLangModelHasUnigrams(forKey reading: String) -> Bool { - currentLM.hasUnigramsFor(key: reading) - } - - /// 在組字器的給定游標位置內插入讀音。 - func insertToCompositorAtCursor(reading: String) { - compositor.insertReading(reading) - } - - /// 組字器的游標位置。 - var compositorCursorIndex: Int { - get { compositor.cursor } - set { compositor.cursor = newValue } - } - - /// 組字器的目前的長度。 - var compositorLength: Int { - compositor.length - } - - /// 在組字器內,朝著與文字輸入方向相反的方向、砍掉一個與游標相鄰的讀音。 - /// - /// 在威注音的術語體系當中,「與文字輸入方向相反的方向」為向後(Rear)。 - func deleteCompositorReadingAtTheRearOfCursor() { - compositor.dropReading(direction: .rear) - } - - /// 在組字器內,朝著往文字輸入方向、砍掉一個與游標相鄰的讀音。 - /// - /// 在威注音的術語體系當中,「文字輸入方向」為向前(Front)。 - func deleteCompositorReadingToTheFrontOfCursor() { - compositor.dropReading(direction: .front) - } - /// 生成標點符號索引鍵。 /// - Parameter input: 輸入的按鍵訊號。 /// - Returns: 生成的標點符號索引鍵。 diff --git a/Source/Modules/ControllerModules/KeyHandler_HandleCandidate.swift b/Source/Modules/ControllerModules/KeyHandler_HandleCandidate.swift index f9bb3236..0b512e4b 100644 --- a/Source/Modules/ControllerModules/KeyHandler_HandleCandidate.swift +++ b/Source/Modules/ControllerModules/KeyHandler_HandleCandidate.swift @@ -61,12 +61,12 @@ extension KeyHandler { if cancelCandidateKey { if (state is InputState.AssociatedPhrases) || mgrPrefs.useSCPCTypingMode - || isCompositorEmpty + || compositor.isEmpty { // 如果此時發現當前組字緩衝區為真空的情況的話, // 就將當前的組字緩衝區析構處理、強制重設輸入狀態。 // 否則,一個本不該出現的真空組字緩衝區會使前後方向鍵與 BackSpace 鍵失靈。 - // 所以這裡需要對 isCompositorEmpty 做判定。 + // 所以這裡需要對 compositor.isEmpty 做判定。 clear() stateCallback(InputState.EmptyIgnoringPreviousState()) } else { @@ -326,12 +326,12 @@ extension KeyHandler { let punctuation: String = arrPunctuations.joined(separator: "") var shouldAutoSelectCandidate: Bool = - composer.inputValidityCheck(key: charCode) || ifLangModelHasUnigrams(forKey: customPunctuation) - || ifLangModelHasUnigrams(forKey: punctuation) + composer.inputValidityCheck(key: charCode) || currentLM.hasUnigramsFor(key: customPunctuation) + || currentLM.hasUnigramsFor(key: punctuation) if !shouldAutoSelectCandidate, input.isUpperCaseASCIILetterKey { let letter: String! = String(format: "%@%c", "_letter_", CChar(charCode)) - if ifLangModelHasUnigrams(forKey: letter) { shouldAutoSelectCandidate = true } + if currentLM.hasUnigramsFor(key: letter) { shouldAutoSelectCandidate = true } } if shouldAutoSelectCandidate { diff --git a/Source/Modules/ControllerModules/KeyHandler_HandleInput.swift b/Source/Modules/ControllerModules/KeyHandler_HandleInput.swift index f7c0cd59..25fbf97f 100644 --- a/Source/Modules/ControllerModules/KeyHandler_HandleInput.swift +++ b/Source/Modules/ControllerModules/KeyHandler_HandleInput.swift @@ -188,7 +188,7 @@ extension KeyHandler { // 如果輸入法的辭典索引是漢語拼音的話,要注意上一行拿到的內容得是漢語拼音。 // 向語言模型詢問是否有對應的記錄。 - if !ifLangModelHasUnigrams(forKey: reading) { + if !currentLM.hasUnigramsFor(key: reading) { IME.prtDebugIntel("B49C0979:語彙庫內無「\(reading)」的匹配記錄。") errorCallback() composer.clear() @@ -198,7 +198,7 @@ extension KeyHandler { } // 將該讀音插入至組字器內的軌格當中。 - insertToCompositorAtCursor(reading: reading) + compositor.insertReading(reading) // 讓組字器反爬軌格。 let textToCommit = commitOverflownCompositionAndWalk @@ -270,7 +270,7 @@ extension KeyHandler { if input.isSpace { /// 倘若沒有在偏好設定內將 Space 空格鍵設為選字窗呼叫用鍵的話……… if !mgrPrefs.chooseCandidateUsingSpace { - if compositorCursorIndex >= compositorLength { + if compositor.cursor >= compositor.length { let composingBuffer = currentState.composingBuffer if !composingBuffer.isEmpty { stateCallback(InputState.Committing(textToCommit: composingBuffer)) @@ -278,8 +278,8 @@ extension KeyHandler { clear() stateCallback(InputState.Committing(textToCommit: " ")) stateCallback(InputState.Empty()) - } else if ifLangModelHasUnigrams(forKey: " ") { - insertToCompositorAtCursor(reading: " ") + } else if currentLM.hasUnigramsFor(key: " ") { + compositor.insertReading(" ") let textToCommit = commitOverflownCompositionAndWalk let inputting = buildInputtingState inputting.textToCommit = textToCommit @@ -396,9 +396,9 @@ extension KeyHandler { if input.isSymbolMenuPhysicalKey && !input.isShiftHold { if input.isOptionHold { - if ifLangModelHasUnigrams(forKey: "_punctuation_list") { + if currentLM.hasUnigramsFor(key: "_punctuation_list") { if composer.isEmpty { - insertToCompositorAtCursor(reading: "_punctuation_list") + compositor.insertReading("_punctuation_list") let textToCommit: String! = commitOverflownCompositionAndWalk let inputting = buildInputtingState inputting.textToCommit = textToCommit diff --git a/Source/Modules/ControllerModules/KeyHandler_States.swift b/Source/Modules/ControllerModules/KeyHandler_States.swift index 60268fcc..6ed1b3e1 100644 --- a/Source/Modules/ControllerModules/KeyHandler_States.swift +++ b/Source/Modules/ControllerModules/KeyHandler_States.swift @@ -54,35 +54,35 @@ extension KeyHandler { /// 每個節錨(NodeAnchor)都有自身的幅位長度(spanningLength),可以用來 /// 累加、以此為依據,來校正「可見游標位置」。 let spanningLength: Int = theAnchor.spanLength - if readingCursorIndex + spanningLength <= compositorCursorIndex { + if readingCursorIndex + spanningLength <= compositor.cursor { composedStringCursorIndex += strNodeValue.utf16.count readingCursorIndex += spanningLength } else { if codepointCount == spanningLength { var i = 0 - while i < codepointCount, readingCursorIndex < compositorCursorIndex { + while i < codepointCount, readingCursorIndex < compositor.cursor { composedStringCursorIndex += arrSplit[i].utf16.count readingCursorIndex += 1 i += 1 } } else { - if readingCursorIndex < compositorCursorIndex { + if readingCursorIndex < compositor.cursor { composedStringCursorIndex += strNodeValue.utf16.count readingCursorIndex += spanningLength - readingCursorIndex = min(readingCursorIndex, compositorCursorIndex) + readingCursorIndex = min(readingCursorIndex, compositor.cursor) /// 接下來再處理這麼一種情況: /// 某些錨點內的當前候選字詞長度與讀音長度不相等。 /// 但此時游標還是按照每個讀音單位來移動的, /// 所以需要上下文工具提示來顯示游標的相對位置。 /// 這裡先計算一下要用在工具提示當中的顯示參數的內容。 - switch compositorCursorIndex { + switch compositor.cursor { case compositor.readings.count...: - tooltipParameterRef[0] = compositor.readings[compositorCursorIndex - 1] + tooltipParameterRef[0] = compositor.readings[compositor.cursor - 1] case 0: - tooltipParameterRef[1] = compositor.readings[compositorCursorIndex] + tooltipParameterRef[1] = compositor.readings[compositor.cursor] default: - tooltipParameterRef[0] = compositor.readings[compositorCursorIndex - 1] - tooltipParameterRef[1] = compositor.readings[compositorCursorIndex] + tooltipParameterRef[0] = compositor.readings[compositor.cursor - 1] + tooltipParameterRef[1] = compositor.readings[compositor.cursor] } /// 注音轉拼音 for (i, _) in tooltipParameterRef.enumerated() { @@ -301,7 +301,7 @@ extension KeyHandler { stateCallback: @escaping (InputStateProtocol) -> Void, errorCallback: @escaping () -> Void ) -> Bool { - if !ifLangModelHasUnigrams(forKey: customPunctuation) { + if !currentLM.hasUnigramsFor(key: customPunctuation) { return false } @@ -313,7 +313,7 @@ extension KeyHandler { return true } - insertToCompositorAtCursor(reading: customPunctuation) + compositor.insertReading(customPunctuation) let textToCommit = commitOverflownCompositionAndWalk let inputting = buildInputtingState inputting.textToCommit = textToCommit @@ -372,7 +372,7 @@ extension KeyHandler { ) -> Bool { guard state is InputState.Inputting else { return false } - var composingBuffer = currentReadings.joined(separator: "-") + var composingBuffer = compositor.readings.joined(separator: "-") if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin { composingBuffer = Tekkon.restoreToneOneInZhuyinKey(target: composingBuffer) // 恢復陰平標記 composingBuffer = Tekkon.cnvPhonaToHanyuPinyin(target: composingBuffer) // 注音轉拼音 @@ -445,8 +445,8 @@ extension KeyHandler { if composer.hasToneMarker(withNothingElse: true) { composer.clear() } else if composer.isEmpty { - if compositorCursorIndex > 0 { - deleteCompositorReadingAtTheRearOfCursor() + if compositor.cursor > 0 { + compositor.dropReading(direction: .rear) walk() } else { IME.prtDebugIntel("9D69908D") @@ -485,14 +485,14 @@ extension KeyHandler { return true } - guard compositorCursorIndex != compositorLength else { + guard compositor.cursor != compositor.length else { IME.prtDebugIntel("9B69938D") errorCallback() stateCallback(state) return true } - deleteCompositorReadingToTheFrontOfCursor() + compositor.dropReading(direction: .front) walk() let inputting = buildInputtingState // 這裡不用「count > 0」,因為該整數變數只要「!isEmpty」那就必定滿足這個條件。 @@ -544,8 +544,8 @@ extension KeyHandler { return true } - if compositorCursorIndex != 0 { - compositorCursorIndex = 0 + if compositor.cursor != 0 { + compositor.cursor = 0 stateCallback(buildInputtingState) } else { IME.prtDebugIntel("66D97F90") @@ -578,8 +578,8 @@ extension KeyHandler { return true } - if compositorCursorIndex != compositorLength { - compositorCursorIndex = compositorLength + if compositor.cursor != compositor.length { + compositor.cursor = compositor.length stateCallback(buildInputtingState) } else { IME.prtDebugIntel("9B69908E") @@ -650,7 +650,7 @@ extension KeyHandler { composingBuffer: currentState.composingBuffer, cursorIndex: currentState.cursorIndex, markerIndex: nextPosition, - readings: currentReadings + readings: compositor.readings ) marking.tooltipForInputting = currentState.tooltip stateCallback(marking) @@ -672,8 +672,8 @@ extension KeyHandler { } stateCallback(buildInputtingState) } else { - if compositorCursorIndex < compositorLength { - compositorCursorIndex += 1 + if compositor.cursor < compositor.length { + compositor.cursor += 1 stateCallback(buildInputtingState) } else { IME.prtDebugIntel("A96AAD58") @@ -718,7 +718,7 @@ extension KeyHandler { composingBuffer: currentState.composingBuffer, cursorIndex: currentState.cursorIndex, markerIndex: previousPosition, - readings: currentReadings + readings: compositor.readings ) marking.tooltipForInputting = currentState.tooltip stateCallback(marking) @@ -740,8 +740,8 @@ extension KeyHandler { } stateCallback(buildInputtingState) } else { - if compositorCursorIndex > 0 { - compositorCursorIndex -= 1 + if compositor.cursor > 0 { + compositor.cursor -= 1 stateCallback(buildInputtingState) } else { IME.prtDebugIntel("7045E6F3") @@ -795,7 +795,7 @@ extension KeyHandler { var length = 0 var currentAnchor = Megrez.NodeAnchor() let cursorIndex = min( - actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositorLength + actualCandidateCursor + (mgrPrefs.useRearCursorMode ? 1 : 0), compositor.length ) for anchor in walkedAnchors { length += anchor.spanLength