InputHandler // Further simplification, etc.
- Removing certain useless cases of delegate.switchState(IMEState.ofEmpty()) right after ofCommitting(). - Divide handleComposition() for future purposes.
This commit is contained in:
parent
4860b52306
commit
19b0b138f2
|
@ -320,7 +320,7 @@ public class InputHandler: InputHandlerProtocol {
|
|||
key: newestSuggestedCandidate.0, value: newestSuggestedCandidate.1.value
|
||||
)
|
||||
vCLog(
|
||||
"UOM: Suggestion retrieved, overriding the node score of the selected candidate: \(suggestedPair.toNGramKey)")
|
||||
"UOM: Suggestion received, overriding the node score of the selected candidate: \(suggestedPair.toNGramKey)")
|
||||
if !compositor.overrideCandidate(suggestedPair, at: cursorForCandidate, overrideType: overrideBehavior) {
|
||||
compositor.overrideCandidateLiteral(
|
||||
newestSuggestedCandidate.1.value, at: cursorForCandidate, overrideType: overrideBehavior
|
||||
|
@ -336,13 +336,8 @@ public class InputHandler: InputHandlerProtocol {
|
|||
// MARK: - Extracted methods and functions (Tekkon).
|
||||
|
||||
/// 獲取與當前注音排列或拼音輸入種類有關的標點索引鍵,以英數下畫線「_」結尾。
|
||||
var currentKeyboardParser: String {
|
||||
currentKeyboardParserType.name + "_"
|
||||
}
|
||||
|
||||
var currentKeyboardParserType: KeyboardParser {
|
||||
.init(rawValue: prefs.keyboardParser) ?? .ofStandard
|
||||
}
|
||||
var currentKeyboardParser: String { currentKeyboardParserType.name + "_" }
|
||||
var currentKeyboardParserType: KeyboardParser { .init(rawValue: prefs.keyboardParser) ?? .ofStandard }
|
||||
|
||||
/// 給注拼槽指定注音排列或拼音輸入種類之後,將注拼槽內容清空。
|
||||
public func ensureKeyboardParser() {
|
||||
|
@ -400,9 +395,7 @@ public class InputHandler: InputHandlerProtocol {
|
|||
/// - Parameter input: 輸入的按鍵訊號。
|
||||
/// - Returns: 生成的標點符號索引鍵。
|
||||
func generatePunctuationNamePrefix(withKeyCondition input: InputSignalProtocol) -> String {
|
||||
if prefs.halfWidthPunctuationEnabled {
|
||||
return "_half_punctuation_"
|
||||
}
|
||||
if prefs.halfWidthPunctuationEnabled { return "_half_punctuation_" }
|
||||
switch (input.isControlHold, input.isOptionHold) {
|
||||
case (true, true): return "_alt_ctrl_punctuation_"
|
||||
case (true, false): return "_ctrl_punctuation_"
|
||||
|
@ -430,9 +423,7 @@ extension InputHandler {
|
|||
compositor.width > compositorWidthLimit,
|
||||
let identifier = delegate?.clientBundleIdentifier,
|
||||
prefs.clientsIMKTextInputIncapable.contains(identifier)
|
||||
else {
|
||||
return ""
|
||||
}
|
||||
else { return "" }
|
||||
// 回頭在這裡插上對 Steam 的 Client Identifier 的要求。
|
||||
var textToCommit = ""
|
||||
while compositor.width > compositorWidthLimit {
|
||||
|
@ -447,13 +438,9 @@ extension InputHandler {
|
|||
}
|
||||
let newCursor = max(compositor.cursor - delta, 0)
|
||||
compositor.cursor = 0
|
||||
if !node.isReadingMismatched {
|
||||
consolidateCursorContext(with: node.currentPair)
|
||||
}
|
||||
if !node.isReadingMismatched { consolidateCursorContext(with: node.currentPair) }
|
||||
// 威注音不支援 Bigram,所以無須考慮前後節點「是否需要鞏固」。
|
||||
for _ in 0..<delta {
|
||||
compositor.dropKey(direction: .front)
|
||||
}
|
||||
for _ in 0..<delta { compositor.dropKey(direction: .front) }
|
||||
compositor.cursor = newCursor
|
||||
walk()
|
||||
}
|
||||
|
|
|
@ -193,9 +193,7 @@ extension InputHandler {
|
|||
if input.isSymbolMenuPhysicalKey {
|
||||
var updated = true
|
||||
updated = input.isShiftHold ? ctlCandidate.showPreviousLine() : ctlCandidate.showNextLine()
|
||||
if !updated {
|
||||
delegate.callError("66F3477B")
|
||||
}
|
||||
if !updated { delegate.callError("66F3477B") }
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,14 @@ extension InputHandler {
|
|||
/// - input: 輸入訊號。
|
||||
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
||||
func handleComposition(input: InputSignalProtocol) -> Bool? {
|
||||
handlePhonabetComposition(input: input)
|
||||
}
|
||||
|
||||
/// 用來處理 InputHandler.HandleInput() 當中的與注音输入有關的組字行為。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入訊號。
|
||||
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
||||
private func handlePhonabetComposition(input: InputSignalProtocol) -> Bool? {
|
||||
guard let delegate = delegate else { return nil }
|
||||
|
||||
// MARK: 注音按鍵輸入處理 (Handle BPMF Keys)
|
||||
|
|
|
@ -68,7 +68,6 @@ extension InputHandler {
|
|||
|
||||
// 將整個組字區的內容遞交給客體應用。
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: inputText.lowercased()))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -79,21 +78,15 @@ extension InputHandler {
|
|||
// 不然、使用 Cocoa 內建的 flags 的話,會誤傷到在主鍵盤區域的功能鍵。
|
||||
// 我們先規定允許小鍵盤區域操縱選字窗,其餘場合一律直接放行。
|
||||
if input.isNumericPadKey {
|
||||
if !(state.type == .ofCandidates || state.type == .ofAssociates
|
||||
|| state.type == .ofSymbolTable)
|
||||
{
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
if ![.ofCandidates, .ofAssociates, .ofSymbolTable].contains(state.type) {
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: inputText.lowercased()))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: 處理候選字詞 (Handle Candidates)
|
||||
|
||||
if [.ofCandidates, .ofSymbolTable].contains(state.type) {
|
||||
return handleCandidate(input: input)
|
||||
}
|
||||
if [.ofCandidates, .ofSymbolTable].contains(state.type) { return handleCandidate(input: input) }
|
||||
|
||||
// MARK: 處理聯想詞 (Handle Associated Phrases)
|
||||
|
||||
|
@ -132,7 +125,6 @@ extension InputHandler {
|
|||
delegate.switchState(IMEState.ofCommitting(textToCommit: displayedText))
|
||||
}
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: " "))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
} else if currentLM.hasUnigramsFor(key: " ") {
|
||||
compositor.insertKey(" ")
|
||||
walk()
|
||||
|
@ -147,12 +139,9 @@ extension InputHandler {
|
|||
return handleInlineCandidateRotation(reverseOrder: input.isCommandHold)
|
||||
}
|
||||
}
|
||||
// 開始決定是否切換至選字狀態。
|
||||
let candidateState: IMEStateProtocol = generateStateOfCandidates()
|
||||
if candidateState.candidates.isEmpty {
|
||||
delegate.callError("3572F238")
|
||||
} else {
|
||||
delegate.switchState(candidateState)
|
||||
}
|
||||
_ = candidateState.candidates.isEmpty ? delegate.callError("3572F238") : delegate.switchState(candidateState)
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -199,12 +188,9 @@ extension InputHandler {
|
|||
var inputting = generateStateOfInputting()
|
||||
inputting.textToCommit = textToCommit
|
||||
delegate.switchState(inputting)
|
||||
let candidateState = generateStateOfCandidates()
|
||||
if candidateState.candidates.isEmpty {
|
||||
delegate.callError("B5127D8A")
|
||||
} else {
|
||||
delegate.switchState(candidateState)
|
||||
}
|
||||
// 開始決定是否切換至選字狀態。
|
||||
let newState = generateStateOfCandidates()
|
||||
_ = newState.candidates.isEmpty ? delegate.callError("B5127D8A") : delegate.switchState(newState)
|
||||
} else { // 不要在注音沒敲完整的情況下叫出統合符號選單。
|
||||
delegate.callError("17446655")
|
||||
}
|
||||
|
@ -212,9 +198,7 @@ extension InputHandler {
|
|||
}
|
||||
} else {
|
||||
// 得在這裡先 commit buffer,不然會導致「在摁 ESC 離開符號選單時會重複輸入上一次的組字區的內容」的不當行為。
|
||||
// 於是這裡用「模擬一次 Enter 鍵的操作」使其代為執行這個 commit buffer 的動作。
|
||||
// 這裡不需要該函式所傳回的 bool 結果,所以用「_ =」解消掉。
|
||||
_ = handleEnter()
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: state.displayedText))
|
||||
delegate.switchState(IMEState.ofSymbolTable(node: CandidateNode.root))
|
||||
return true
|
||||
}
|
||||
|
@ -224,13 +208,10 @@ extension InputHandler {
|
|||
|
||||
if state.type == .ofEmpty {
|
||||
if input.isMainAreaNumKey, input.modifierFlags == [.shift, .option] {
|
||||
guard let stringRAW = input.mainAreaNumKeyChar else { return false }
|
||||
let newStringFW = stringRAW.applyingTransform(.fullwidthToHalfwidth, reverse: true) ?? stringRAW
|
||||
let newStringHW = stringRAW.applyingTransform(.fullwidthToHalfwidth, reverse: false) ?? stringRAW
|
||||
delegate.switchState(
|
||||
IMEState.ofCommitting(textToCommit: prefs.halfWidthPunctuationEnabled ? newStringHW : newStringFW)
|
||||
)
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
guard let strRAW = input.mainAreaNumKeyChar else { return false }
|
||||
let newString =
|
||||
strRAW.applyingTransform(.fullwidthToHalfwidth, reverse: !prefs.halfWidthPunctuationEnabled) ?? strRAW
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: newString))
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -240,23 +221,15 @@ extension InputHandler {
|
|||
/// 如果仍無匹配結果的話,先看一下:
|
||||
/// - 是否是針對當前注音排列/拼音輸入種類專門提供的標點符號。
|
||||
/// - 是否是需要摁修飾鍵才可以輸入的那種標點符號。
|
||||
|
||||
let punctuationNamePrefix: String = generatePunctuationNamePrefix(withKeyCondition: input)
|
||||
let parser = currentKeyboardParser
|
||||
let arrCustomPunctuations: [String] = [punctuationNamePrefix, parser, input.text]
|
||||
let customPunctuation: String = arrCustomPunctuations.joined()
|
||||
if handlePunctuation(customPunctuation) {
|
||||
return true
|
||||
}
|
||||
|
||||
if handlePunctuation(customPunctuation) { return true }
|
||||
/// 如果仍無匹配結果的話,看看這個輸入是否是不需要修飾鍵的那種標點鍵輸入。
|
||||
|
||||
let arrPunctuations: [String] = [punctuationNamePrefix, input.text]
|
||||
let punctuation: String = arrPunctuations.joined()
|
||||
|
||||
if handlePunctuation(punctuation) {
|
||||
return true
|
||||
}
|
||||
if handlePunctuation(punctuation) { return true }
|
||||
|
||||
// MARK: 全形/半形空白 (Full-Width / Half-Width Space)
|
||||
|
||||
|
@ -264,7 +237,6 @@ extension InputHandler {
|
|||
if state.type == .ofEmpty {
|
||||
if input.isSpace, !input.isOptionHold, !input.isControlHold, !input.isCommandHold {
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: input.isShiftHold ? " " : " "))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@ -275,15 +247,10 @@ extension InputHandler {
|
|||
if input.isShiftHold { // 這裡先不要判斷 isOptionHold。
|
||||
switch prefs.upperCaseLetterKeyBehavior {
|
||||
case 1:
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: inputText.lowercased()))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
return true
|
||||
|
||||
case 2:
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: inputText.uppercased()))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
return true
|
||||
default: // 包括 case 0,直接塞給組字區。
|
||||
let letter = "_letter_\(inputText)"
|
||||
|
@ -301,8 +268,7 @@ extension InputHandler {
|
|||
/// 砍掉這一段會導致「F1-F12 按鍵干擾組字區」的問題。
|
||||
/// 暫時只能先恢復這段,且補上偵錯彙報機制,方便今後排查故障。
|
||||
if state.hasComposition || !composer.isEmpty {
|
||||
delegate.callError(
|
||||
"Blocked data: charCode: \(input.charCode), keyCode: \(input.keyCode)")
|
||||
delegate.callError("Blocked data: charCode: \(input.charCode), keyCode: \(input.keyCode)")
|
||||
delegate.callError("A9BFF20E")
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
|
|
|
@ -252,7 +252,6 @@ extension InputHandler {
|
|||
clear() // 這句不要砍,因為下文可能會回呼 candidateState。
|
||||
if let candidateToCommit: (String, String) = candidateState.candidates.first, !candidateToCommit.1.isEmpty {
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: candidateToCommit.1))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
} else {
|
||||
delegate.switchState(candidateState)
|
||||
}
|
||||
|
@ -265,13 +264,12 @@ extension InputHandler {
|
|||
|
||||
/// Enter 鍵的處理。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleEnter() -> Bool {
|
||||
@discardableResult func handleEnter() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: state.displayedText))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -295,7 +293,6 @@ extension InputHandler {
|
|||
}
|
||||
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: displayedText))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -327,7 +324,6 @@ extension InputHandler {
|
|||
}
|
||||
|
||||
delegate.switchState(IMEState.ofCommitting(textToCommit: composed))
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -432,9 +428,7 @@ extension InputHandler {
|
|||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
if !composer.isEmpty {
|
||||
delegate.callError("9B6F908D")
|
||||
}
|
||||
if !composer.isEmpty { delegate.callError("9B6F908D") }
|
||||
delegate.switchState(state)
|
||||
return true
|
||||
}
|
||||
|
@ -616,9 +610,7 @@ extension InputHandler {
|
|||
delegate.switchState(state)
|
||||
}
|
||||
} else if input.isOptionHold {
|
||||
if input.isControlHold {
|
||||
return handleHome()
|
||||
}
|
||||
if input.isControlHold { return handleHome() }
|
||||
// 游標跳轉動作無論怎樣都會執行,但如果出了執行失敗的結果的話則觸發報錯流程。
|
||||
if !compositor.jumpCursorBySpan(to: .rear) {
|
||||
delegate.callError("8D50DD9E")
|
||||
|
|
Loading…
Reference in New Issue