From b510ee5c1e5352624bd67af97f4ff6f858d8c7b1 Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Sat, 8 Oct 2022 18:05:24 +0800 Subject: [PATCH] KeyHandler // Stop generating candidate states with emply container. --- .../KeyHandler_HandleComposition.swift | 34 ++++++++++--------- Source/Modules/KeyHandler_HandleInput.swift | 14 ++++++-- Source/Modules/KeyHandler_States.swift | 29 ++++++++-------- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/Source/Modules/KeyHandler_HandleComposition.swift b/Source/Modules/KeyHandler_HandleComposition.swift index 03e0f2e5..571d3f59 100644 --- a/Source/Modules/KeyHandler_HandleComposition.swift +++ b/Source/Modules/KeyHandler_HandleComposition.swift @@ -126,23 +126,25 @@ extension KeyHandler { /// 逐字選字模式的處理。 if prefs.useSCPCTypingMode { - let candidateState: IMEState = buildCandidate(state: inputting) - if candidateState.candidates.count == 1, let firstCandidate = candidateState.candidates.first { - let reading: String = firstCandidate.0 - let text: String = firstCandidate.1 - stateCallback(IMEState.ofCommitting(textToCommit: text)) + let candidateState: IMEStateProtocol = buildCandidate(state: inputting) + switch candidateState.candidates.count { + case 2...: stateCallback(candidateState) + case 1: + let firstCandidate = candidateState.candidates.first! // 一定會有,所以強制拆包也無妨。 + let reading: String = firstCandidate.0 + let text: String = firstCandidate.1 + stateCallback(IMEState.ofCommitting(textToCommit: text)) - if !prefs.associatedPhrasesEnabled { - stateCallback(IMEState.ofEmpty()) - } else { - let associatedPhrases = - buildAssociatePhraseState( - withPair: .init(key: reading, value: text) - ) - stateCallback(associatedPhrases.candidates.isEmpty ? IMEState.ofEmpty() : associatedPhrases) - } - } else { - stateCallback(candidateState) + if !prefs.associatedPhrasesEnabled { + stateCallback(IMEState.ofEmpty()) + } else { + let associatedPhrases = + buildAssociatePhraseState( + withPair: .init(key: reading, value: text) + ) + stateCallback(associatedPhrases.candidates.isEmpty ? IMEState.ofEmpty() : associatedPhrases) + } + default: break } } // 將「這個按鍵訊號已經被輸入法攔截處理了」的結果藉由 SessionCtl 回報給 IMK。 diff --git a/Source/Modules/KeyHandler_HandleInput.swift b/Source/Modules/KeyHandler_HandleInput.swift index 2469fd80..1026d7ef 100644 --- a/Source/Modules/KeyHandler_HandleInput.swift +++ b/Source/Modules/KeyHandler_HandleInput.swift @@ -176,7 +176,12 @@ extension KeyHandler { ) } } - stateCallback(buildCandidate(state: state)) + let candidateState: IMEStateProtocol = buildCandidate(state: state) + if candidateState.candidates.isEmpty { + errorCallback("3572F238") + } else { + stateCallback(candidateState) + } return true } @@ -289,7 +294,12 @@ extension KeyHandler { var inputting = buildInputtingState inputting.textToCommit = textToCommit stateCallback(inputting) - stateCallback(buildCandidate(state: inputting)) + let candidateState = buildCandidate(state: inputting) + if candidateState.candidates.isEmpty { + errorCallback("B5127D8A") + } else { + stateCallback(candidateState) + } } else { // 不要在注音沒敲完整的情況下叫出統合符號選單。 errorCallback("17446655") } diff --git a/Source/Modules/KeyHandler_States.swift b/Source/Modules/KeyHandler_States.swift index 15db2a02..3661f1eb 100644 --- a/Source/Modules/KeyHandler_States.swift +++ b/Source/Modules/KeyHandler_States.swift @@ -18,7 +18,7 @@ extension KeyHandler { // MARK: - 構築狀態(State Building) /// 生成「正在輸入」狀態。相關的內容會被拿給狀態機械用來處理在電腦螢幕上顯示的內容。 - public var buildInputtingState: IMEState { + public var buildInputtingState: IMEStateProtocol { /// 「更新內文組字區 (Update the composing buffer)」是指要求客體軟體將組字緩衝區的內容 /// 換成由此處重新生成的組字字串(NSAttributeString,否則會不顯示)。 var displayTextSegments: [String] = compositor.walkedNodes.values @@ -85,11 +85,10 @@ extension KeyHandler { /// 拿著給定的候選字詞陣列資料內容,切換至選字狀態。 /// - Parameters: /// - currentState: 當前狀態。 - /// - isTypingVertical: 是否縱排輸入? /// - Returns: 回呼一個新的選詞狀態,來就給定的候選字詞陣列資料內容顯示選字窗。 func buildCandidate( state currentState: IMEStateProtocol - ) -> IMEState { + ) -> IMEStateProtocol { IMEState.ofCandidates( candidates: getCandidatesArray(fixOrder: prefs.useFixecCandidateOrderOnSelection), displayTextSegments: compositor.walkedNodes.values, @@ -113,7 +112,7 @@ extension KeyHandler { /// - Returns: 回呼一個新的聯想詞狀態,來就給定的聯想詞陣列資料內容顯示選字窗。 func buildAssociatePhraseState( withPair pair: Megrez.Compositor.KeyValuePaired - ) -> IMEState { + ) -> IMEStateProtocol { IMEState.ofAssociates( candidates: buildAssociatePhraseArray(withPair: pair)) } @@ -232,7 +231,6 @@ extension KeyHandler { /// 標點輸入的處理。 /// - Parameters: /// - customPunctuation: 自訂標點索引鍵頭。 - /// - isTypingVertical: 是否縱排輸入? /// - stateCallback: 狀態回呼。 /// - errorCallback: 錯誤回呼。 /// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。 @@ -265,16 +263,17 @@ extension KeyHandler { guard prefs.useSCPCTypingMode, composer.isEmpty else { return true } let candidateState = buildCandidate(state: inputting) - if candidateState.candidates.count == 1 { - clear() // 這句不要砍,因為下文可能會回呼 candidateState。 - if let candidateToCommit: (String, String) = candidateState.candidates.first, !candidateToCommit.1.isEmpty { - stateCallback(IMEState.ofCommitting(textToCommit: candidateToCommit.1)) - stateCallback(IMEState.ofEmpty()) - } else { - stateCallback(candidateState) - } - } else { - stateCallback(candidateState) + switch candidateState.candidates.count { + case 2...: stateCallback(candidateState) + case 1: + clear() // 這句不要砍,因為下文可能會回呼 candidateState。 + if let candidateToCommit: (String, String) = candidateState.candidates.first, !candidateToCommit.1.isEmpty { + stateCallback(IMEState.ofCommitting(textToCommit: candidateToCommit.1)) + stateCallback(IMEState.ofEmpty()) + } else { + stateCallback(candidateState) + } + default: errorCallback("8DA4096E") } return true }