KeyHandler // Refactoring with modern Swift expressions.

This commit is contained in:
ShikiSuen 2022-05-20 23:03:50 +08:00
parent e77d67370b
commit 45c877b3f9
7 changed files with 144 additions and 158 deletions

View File

@ -289,7 +289,7 @@ class InputState {
"<InputState.Marking, composingBuffer:\(composingBuffer), cursorIndex:\(cursorIndex), markedRange:\(markedRange)>" "<InputState.Marking, composingBuffer:\(composingBuffer), cursorIndex:\(cursorIndex), markedRange:\(markedRange)>"
} }
func convertToInputting() -> Inputting { var convertedToInputting: Inputting {
let state = Inputting(composingBuffer: composingBuffer, cursorIndex: cursorIndex) let state = Inputting(composingBuffer: composingBuffer, cursorIndex: cursorIndex)
state.tooltip = tooltipForInputting state.tooltip = tooltipForInputting
return state return state

View File

@ -68,13 +68,35 @@ class KeyHandler {
return InputMode.imeModeNULL 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() { public init() {
_builder = Megrez.BlockReadingBuilder(lm: _languageModel, separator: "-") _builder = Megrez.BlockReadingBuilder(lm: _languageModel, separator: "-")
ensureParser() ensureParser()
setInputMode(ctlInputMethod.currentInputMode) inputMode = InputMode(rawValue: ctlInputMethod.currentInputMode) ?? InputMode.imeModeNULL
} }
func clear() { func clear() {
@ -83,34 +105,6 @@ class KeyHandler {
_walkedNodes.removeAll() _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. // MARK: - Functions dealing with Megrez.
func walk() { func walk() {
@ -121,7 +115,7 @@ class KeyHandler {
_walkedNodes = _builder.walk(at: _builder.grid.width, nodesLimit: 10, balanced: true) _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. // 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 // 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 // become slower as the number of nodes increase. Therefore, we need to
@ -153,7 +147,7 @@ class KeyHandler {
} }
func fixNode(value: String) { func fixNode(value: String) {
let cursorIndex: Int = getActualCandidateCursorIndex() let cursorIndex: Int = actualCandidateCursorIndex
let selectedNode: Megrez.NodeAnchor = _builder.grid.fixNodeSelectedCandidate( let selectedNode: Megrez.NodeAnchor = _builder.grid.fixNodeSelectedCandidate(
location: cursorIndex, value: value location: cursorIndex, value: value
) )
@ -192,16 +186,16 @@ class KeyHandler {
if nextPosition >= cursorIndex { break } if nextPosition >= cursorIndex { break }
nextPosition += node.spanningLength nextPosition += node.spanningLength
} }
if nextPosition <= getBuilderLength() { if nextPosition <= builderLength {
setBuilderCursorIndex(value: nextPosition) builderCursorIndex = nextPosition
} }
} }
} }
func getCandidatesArray() -> [String] { var candidatesArray: [String] {
var arrCandidates: [String] = [] var arrCandidates: [String] = []
var arrNodes: [Megrez.NodeAnchor] = [] var arrNodes: [Megrez.NodeAnchor] = []
arrNodes.append(contentsOf: getRawNodes()) arrNodes.append(contentsOf: rawNodes)
/// nodes /// nodes
/// ///
@ -228,7 +222,7 @@ class KeyHandler {
mgrPrefs.useSCPCTypingMode mgrPrefs.useSCPCTypingMode
? "" ? ""
: _userOverrideModel.suggest( : _userOverrideModel.suggest(
walkedNodes: _walkedNodes, cursorIndex: getBuilderCursorIndex(), walkedNodes: _walkedNodes, cursorIndex: builderCursorIndex,
timestamp: NSDate().timeIntervalSince1970 timestamp: NSDate().timeIntervalSince1970
) )
@ -236,9 +230,9 @@ class KeyHandler {
IME.prtDebugIntel( IME.prtDebugIntel(
"UOM: Suggestion retrieved, overriding the node score of the selected candidate.") "UOM: Suggestion retrieved, overriding the node score of the selected candidate.")
_builder.grid.overrideNodeScoreForSelectedCandidate( _builder.grid.overrideNodeScoreForSelectedCandidate(
location: getActualCandidateCursorIndex(), location: actualCandidateCursorIndex,
value: overrideValue, value: overrideValue,
overridingScore: findHighestScore(nodes: getRawNodes(), epsilon: kEpsilon) overridingScore: findHighestScore(nodes: rawNodes, epsilon: kEpsilon)
) )
} else { } else {
IME.prtDebugIntel("UOM: Blank suggestion retrieved, dismissing.") IME.prtDebugIntel("UOM: Blank suggestion retrieved, dismissing.")
@ -258,69 +252,6 @@ class KeyHandler {
return highestScore + epsilon 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). // MARK: - Extracted methods and functions (Tekkon).
func ensureParser() { func ensureParser() {
@ -357,4 +288,59 @@ class KeyHandler {
} }
_composer.clear() _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
}
} }

View File

@ -47,16 +47,16 @@ extension KeyHandler {
if cancelCandidateKey { if cancelCandidateKey {
if (state is InputState.AssociatedPhrases) if (state is InputState.AssociatedPhrases)
|| mgrPrefs.useSCPCTypingMode || mgrPrefs.useSCPCTypingMode
|| isBuilderEmpty() || isBuilderEmpty
{ {
// //
// //
// 使 BackSpace // 使 BackSpace
// isBuilderEmpty() // isBuilderEmpty
clear() clear()
stateCallback(InputState.EmptyIgnoringPreviousState()) stateCallback(InputState.EmptyIgnoringPreviousState())
} else { } else {
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
} }
return true return true
} }
@ -320,7 +320,7 @@ extension KeyHandler {
punctuationNamePrefix = "_punctuation_" punctuationNamePrefix = "_punctuation_"
} }
let parser = getCurrentMandarinParser() let parser = currentMandarinParser
let arrCustomPunctuations: [String] = [ let arrCustomPunctuations: [String] = [
punctuationNamePrefix, parser, String(format: "%c", CChar(charCode)), punctuationNamePrefix, parser, String(format: "%c", CChar(charCode)),

View File

@ -135,7 +135,7 @@ extension KeyHandler {
) { ) {
return true return true
} }
state = marking.convertToInputting() state = marking.convertedToInputting
stateCallback(state) stateCallback(state)
} }
@ -154,7 +154,7 @@ extension KeyHandler {
// update the composing buffer. // update the composing buffer.
let composeReading = _composer.hasToneMarker() let composeReading = _composer.hasToneMarker()
if !composeReading { if !composeReading {
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
return true return true
} }
} }
@ -166,7 +166,7 @@ extension KeyHandler {
// However, Swift does not support "|=". // However, Swift does not support "|=".
composeReading = composeReading || (!_composer.isEmpty && (input.isSpace || input.isEnter)) composeReading = composeReading || (!_composer.isEmpty && (input.isSpace || input.isEnter))
if composeReading { if composeReading {
if input.isSpace && !_composer.hasToneMarker() { if input.isSpace, !_composer.hasToneMarker() {
_composer.receiveKey(fromString: " ") // _composer.receiveKey(fromString: " ") //
} }
let reading = _composer.getComposition() let reading = _composer.getComposition()
@ -176,7 +176,7 @@ extension KeyHandler {
IME.prtDebugIntel("B49C0979語彙庫內無「\(reading)」的匹配記錄。") IME.prtDebugIntel("B49C0979語彙庫內無「\(reading)」的匹配記錄。")
errorCallback() errorCallback()
_composer.clear() _composer.clear()
stateCallback((getBuilderLength() == 0) ? InputState.EmptyIgnoringPreviousState() : buildInputtingState()) stateCallback((builderLength == 0) ? InputState.EmptyIgnoringPreviousState() : buildInputtingState)
return true return true
} }
@ -184,7 +184,7 @@ extension KeyHandler {
insertReadingToBuilderAtCursor(reading: reading) insertReadingToBuilderAtCursor(reading: reading)
// ... then walk the grid... // ... then walk the grid...
let poppedText = popOverflowComposingTextAndWalk() let poppedText = popOverflowComposingTextAndWalk
// ... get and tweak override model suggestion if possible... // ... get and tweak override model suggestion if possible...
dealWithOverrideModelSuggestions() dealWithOverrideModelSuggestions()
@ -192,7 +192,7 @@ extension KeyHandler {
// ... then update the text. // ... then update the text.
_composer.clear() _composer.clear()
let inputting = buildInputtingState() let inputting = buildInputtingState
inputting.poppedText = poppedText inputting.poppedText = poppedText
stateCallback(inputting) stateCallback(inputting)
@ -233,7 +233,7 @@ extension KeyHandler {
// but does not compose. Only sequences such as "ˊ", "ˊˊ", "ˊˇ", or "ˊ " // but does not compose. Only sequences such as "ˊ", "ˊˊ", "ˊˇ", or "ˊ "
// would compose. // would compose.
if keyConsumedByReading { if keyConsumedByReading {
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
return true return true
} }
@ -247,7 +247,7 @@ extension KeyHandler {
if input.isSpace { if input.isSpace {
// If the Space key is NOT set to be a selection key // If the Space key is NOT set to be a selection key
if input.isShiftHold || !mgrPrefs.chooseCandidateUsingSpace { if input.isShiftHold || !mgrPrefs.chooseCandidateUsingSpace {
if getBuilderCursorIndex() >= getBuilderLength() { if builderCursorIndex >= builderLength {
let composingBuffer = currentState.composingBuffer let composingBuffer = currentState.composingBuffer
if !composingBuffer.isEmpty { if !composingBuffer.isEmpty {
stateCallback(InputState.Committing(poppedText: composingBuffer)) stateCallback(InputState.Committing(poppedText: composingBuffer))
@ -257,8 +257,8 @@ extension KeyHandler {
stateCallback(InputState.Empty()) stateCallback(InputState.Empty())
} else if ifLangModelHasUnigrams(forKey: " ") { } else if ifLangModelHasUnigrams(forKey: " ") {
insertReadingToBuilderAtCursor(reading: " ") insertReadingToBuilderAtCursor(reading: " ")
let poppedText = popOverflowComposingTextAndWalk() let poppedText = popOverflowComposingTextAndWalk
let inputting = buildInputtingState() let inputting = buildInputtingState
inputting.poppedText = poppedText inputting.poppedText = poppedText
stateCallback(inputting) stateCallback(inputting)
} }
@ -355,8 +355,8 @@ extension KeyHandler {
if ifLangModelHasUnigrams(forKey: "_punctuation_list") { if ifLangModelHasUnigrams(forKey: "_punctuation_list") {
if _composer.isEmpty { if _composer.isEmpty {
insertReadingToBuilderAtCursor(reading: "_punctuation_list") insertReadingToBuilderAtCursor(reading: "_punctuation_list")
let poppedText: String! = popOverflowComposingTextAndWalk() let poppedText: String! = popOverflowComposingTextAndWalk
let inputting = buildInputtingState() let inputting = buildInputtingState
inputting.poppedText = poppedText inputting.poppedText = poppedText
stateCallback(inputting) stateCallback(inputting)
stateCallback(buildCandidate(state: inputting, useVerticalMode: input.useVerticalMode)) stateCallback(buildCandidate(state: inputting, useVerticalMode: input.useVerticalMode))
@ -392,7 +392,7 @@ extension KeyHandler {
punctuationNamePrefix = "_punctuation_" punctuationNamePrefix = "_punctuation_"
} }
let parser = getCurrentMandarinParser() let parser = currentMandarinParser
let arrCustomPunctuations: [String] = [ let arrCustomPunctuations: [String] = [
punctuationNamePrefix, parser, String(format: "%c", CChar(charCode)), punctuationNamePrefix, parser, String(format: "%c", CChar(charCode)),
] ]

View File

@ -29,22 +29,22 @@ import Cocoa
// MARK: - § Misc functions. // MARK: - § Misc functions.
extension KeyHandler { extension KeyHandler {
func getCurrentMandarinParser() -> String { var currentMandarinParser: String {
mgrPrefs.mandarinParserName + "_" mgrPrefs.mandarinParserName + "_"
} }
func getActualCandidateCursorIndex() -> Int { var actualCandidateCursorIndex: Int {
var cursorIndex = getBuilderCursorIndex() var cursorIndex = builderCursorIndex
// Windows Yahoo Kimo IME style, phrase is *at the rear of* the cursor. // Windows Yahoo Kimo IME style, phrase is *at the rear of* the cursor.
// (i.e. the cursor is always *before* the phrase.) // (i.e. the cursor is always *before* the phrase.)
// This is different from MS Phonetics IME style ... // This is different from MS Phonetics IME style ...
// ... since Windows Yahoo Kimo allows "node crossing". // ... since Windows Yahoo Kimo allows "node crossing".
if (mgrPrefs.setRearCursorMode if (mgrPrefs.setRearCursorMode
&& (cursorIndex < getBuilderLength())) && (cursorIndex < builderLength))
|| cursorIndex == 0 || cursorIndex == 0
{ {
if cursorIndex == 0, !mgrPrefs.setRearCursorMode { if cursorIndex == 0, !mgrPrefs.setRearCursorMode {
cursorIndex += getKeyLengthAtIndexZero() cursorIndex += keyLengthAtIndexZero
} else { } else {
cursorIndex += 1 cursorIndex += 1
} }

View File

@ -31,14 +31,14 @@ import Cocoa
extension KeyHandler { extension KeyHandler {
// MARK: - State Building // MARK: - State Building
func buildInputtingState() -> InputState.Inputting { var buildInputtingState: InputState.Inputting {
// "Updating the composing buffer" means to request the client // "Updating the composing buffer" means to request the client
// to "refresh" the text input buffer with our "composing text" // to "refresh" the text input buffer with our "composing text"
var composingBuffer = "" var composingBuffer = ""
var composedStringCursorIndex = 0 var composedStringCursorIndex = 0
var readingCursorIndex = 0 var readingCursorIndex = 0
let builderCursorIndex = getBuilderCursorIndex() let builderCursorIndex = builderCursorIndex
for theAnchor in _walkedNodes { for theAnchor in _walkedNodes {
guard let node = theAnchor.node else { guard let node = theAnchor.node else {
@ -106,7 +106,7 @@ extension KeyHandler {
InputState.ChoosingCandidate( InputState.ChoosingCandidate(
composingBuffer: currentState.composingBuffer, composingBuffer: currentState.composingBuffer,
cursorIndex: currentState.cursorIndex, cursorIndex: currentState.cursorIndex,
candidates: getCandidatesArray(), candidates: candidatesArray,
useVerticalMode: useVerticalMode useVerticalMode: useVerticalMode
) )
} }
@ -115,7 +115,7 @@ extension KeyHandler {
// buildAssociatePhraseStateWithKey // buildAssociatePhraseStateWithKey
// 使 // 使
// ObjC buildAssociatePhraseArray // Core buildAssociatePhraseArray
// String Swift // String Swift
// nil // nil
// //
@ -139,7 +139,7 @@ extension KeyHandler {
errorCallback: @escaping () -> Void errorCallback: @escaping () -> Void
) -> Bool { ) -> Bool {
if input.isESC { if input.isESC {
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
return true return true
} }
@ -152,7 +152,7 @@ extension KeyHandler {
return true return true
} }
} }
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
return true return true
} }
@ -168,7 +168,7 @@ extension KeyHandler {
readings: state.readings readings: state.readings
) )
marking.tooltipForInputting = state.tooltipForInputting marking.tooltipForInputting = state.tooltipForInputting
stateCallback(marking.markedRange.length == 0 ? marking.convertToInputting() : marking) stateCallback(marking.markedRange.length == 0 ? marking.convertedToInputting : marking)
} else { } else {
IME.prtDebugIntel("1149908D") IME.prtDebugIntel("1149908D")
errorCallback() errorCallback()
@ -191,7 +191,7 @@ extension KeyHandler {
readings: state.readings readings: state.readings
) )
marking.tooltipForInputting = state.tooltipForInputting marking.tooltipForInputting = state.tooltipForInputting
stateCallback(marking.markedRange.length == 0 ? marking.convertToInputting() : marking) stateCallback(marking.markedRange.length == 0 ? marking.convertedToInputting : marking)
} else { } else {
IME.prtDebugIntel("9B51408D") IME.prtDebugIntel("9B51408D")
errorCallback() errorCallback()
@ -217,8 +217,8 @@ extension KeyHandler {
if _composer.isEmpty { if _composer.isEmpty {
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)
@ -273,7 +273,7 @@ extension KeyHandler {
) -> Bool { ) -> Bool {
guard state is InputState.Inputting else { return false } guard state is InputState.Inputting else { return false }
var composingBuffer = currentReadings().joined(separator: "-") var composingBuffer = currentReadings.joined(separator: "-")
if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin { if mgrPrefs.inlineDumpPinyinInLieuOfZhuyin {
composingBuffer = restoreToneOneInZhuyinKey(target: composingBuffer) // composingBuffer = restoreToneOneInZhuyinKey(target: composingBuffer) //
composingBuffer = Tekkon.cnvPhonaToHanyuPinyin(target: composingBuffer) // composingBuffer = Tekkon.cnvPhonaToHanyuPinyin(target: composingBuffer) //
@ -341,7 +341,7 @@ extension KeyHandler {
if _composer.hasToneMarker(withNothingElse: true) { if _composer.hasToneMarker(withNothingElse: true) {
_composer.clear() _composer.clear()
} else if _composer.isEmpty { } else if _composer.isEmpty {
if getBuilderCursorIndex() >= 0 { if builderCursorIndex >= 0 {
deleteBuilderReadingInFrontOfCursor() deleteBuilderReadingInFrontOfCursor()
walk() walk()
} else { } else {
@ -354,10 +354,10 @@ extension KeyHandler {
_composer.doBackSpace() _composer.doBackSpace()
} }
if _composer.isEmpty, getBuilderLength() == 0 { if _composer.isEmpty, builderLength == 0 {
stateCallback(InputState.EmptyIgnoringPreviousState()) stateCallback(InputState.EmptyIgnoringPreviousState())
} else { } else {
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
} }
return true return true
} }
@ -372,10 +372,10 @@ extension KeyHandler {
guard state is InputState.Inputting else { return false } guard state is InputState.Inputting else { return false }
if _composer.isEmpty { if _composer.isEmpty {
if getBuilderCursorIndex() != getBuilderLength() { if builderCursorIndex != builderLength {
deleteBuilderReadingToTheFrontOfCursor() deleteBuilderReadingToTheFrontOfCursor()
walk() walk()
let inputting = buildInputtingState() let inputting = buildInputtingState
// count > 0!isEmpty滿 // count > 0!isEmpty滿
if inputting.composingBuffer.isEmpty { if inputting.composingBuffer.isEmpty {
stateCallback(InputState.EmptyIgnoringPreviousState()) stateCallback(InputState.EmptyIgnoringPreviousState())
@ -428,9 +428,9 @@ extension KeyHandler {
return true return true
} }
if getBuilderCursorIndex() != 0 { if builderCursorIndex != 0 {
setBuilderCursorIndex(value: 0) builderCursorIndex = 0
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
} else { } else {
IME.prtDebugIntel("66D97F90") IME.prtDebugIntel("66D97F90")
errorCallback() errorCallback()
@ -456,9 +456,9 @@ extension KeyHandler {
return true return true
} }
if getBuilderCursorIndex() != getBuilderLength() { if builderCursorIndex != builderLength {
setBuilderCursorIndex(value: getBuilderLength()) builderCursorIndex = builderLength
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
} else { } else {
IME.prtDebugIntel("9B69908E") IME.prtDebugIntel("9B69908E")
errorCallback() errorCallback()
@ -490,10 +490,10 @@ extension KeyHandler {
// If reading is not empty, we cancel the reading. // If reading is not empty, we cancel the reading.
if !_composer.isEmpty { if !_composer.isEmpty {
_composer.clear() _composer.clear()
if getBuilderLength() == 0 { if builderLength == 0 {
stateCallback(InputState.EmptyIgnoringPreviousState()) stateCallback(InputState.EmptyIgnoringPreviousState())
} else { } else {
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
} }
} }
} }
@ -526,7 +526,7 @@ extension KeyHandler {
composingBuffer: currentState.composingBuffer, composingBuffer: currentState.composingBuffer,
cursorIndex: currentState.cursorIndex, cursorIndex: currentState.cursorIndex,
markerIndex: UInt(nextPosition), markerIndex: UInt(nextPosition),
readings: currentReadings() readings: currentReadings
) )
marking.tooltipForInputting = currentState.tooltip marking.tooltipForInputting = currentState.tooltip
stateCallback(marking) stateCallback(marking)
@ -536,9 +536,9 @@ extension KeyHandler {
stateCallback(state) stateCallback(state)
} }
} else { } else {
if getBuilderCursorIndex() < getBuilderLength() { if builderCursorIndex < builderLength {
setBuilderCursorIndex(value: getBuilderCursorIndex() + 1) builderCursorIndex += 1
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
} else { } else {
IME.prtDebugIntel("A96AAD58") IME.prtDebugIntel("A96AAD58")
errorCallback() errorCallback()
@ -575,7 +575,7 @@ extension KeyHandler {
composingBuffer: currentState.composingBuffer, composingBuffer: currentState.composingBuffer,
cursorIndex: currentState.cursorIndex, cursorIndex: currentState.cursorIndex,
markerIndex: UInt(previousPosition), markerIndex: UInt(previousPosition),
readings: currentReadings() readings: currentReadings
) )
marking.tooltipForInputting = currentState.tooltip marking.tooltipForInputting = currentState.tooltip
stateCallback(marking) stateCallback(marking)
@ -585,9 +585,9 @@ extension KeyHandler {
stateCallback(state) stateCallback(state)
} }
} else { } else {
if getBuilderCursorIndex() > 0 { if builderCursorIndex > 0 {
setBuilderCursorIndex(value: getBuilderCursorIndex() - 1) builderCursorIndex -= 1
stateCallback(buildInputtingState()) stateCallback(buildInputtingState)
} else { } else {
IME.prtDebugIntel("7045E6F3") IME.prtDebugIntel("7045E6F3")
errorCallback() errorCallback()

View File

@ -648,7 +648,7 @@ extension ctlInputMethod: ctlCandidateDelegate {
let selectedValue = state.candidates[Int(index)] let selectedValue = state.candidates[Int(index)]
keyHandler.fixNode(value: selectedValue) keyHandler.fixNode(value: selectedValue)
let inputting = keyHandler.buildInputtingState() let inputting = keyHandler.buildInputtingState
if mgrPrefs.useSCPCTypingMode { if mgrPrefs.useSCPCTypingMode {
keyHandler.clear() keyHandler.clear()