KeyHandler // Use guard-let in handleCandidate().

This commit is contained in:
ShikiSuen 2022-06-09 08:31:15 +08:00
parent e2757a34f5
commit 03e9872f55
1 changed files with 314 additions and 310 deletions

View File

@ -37,341 +37,345 @@ extension KeyHandler {
) -> Bool {
let inputText = input.inputText
let charCode: UniChar = input.charCode
if let ctlCandidateCurrent = delegate?.ctlCandidate() {
// MARK: Cancel Candidate
guard let ctlCandidateCurrent = delegate?.ctlCandidate() else {
IME.prtDebugIntel("06661F6E")
errorCallback()
return true
}
let cancelCandidateKey =
input.isBackSpace || input.isESC || input.isDelete
|| ((input.isCursorBackward || input.isCursorForward) && input.isShiftHold)
// MARK: Cancel Candidate
if cancelCandidateKey {
if (state is InputState.AssociatedPhrases)
|| mgrPrefs.useSCPCTypingMode
|| isBuilderEmpty
{
//
//
// 使 BackSpace
// isBuilderEmpty
clear()
stateCallback(InputState.EmptyIgnoringPreviousState())
} else {
stateCallback(buildInputtingState)
}
let cancelCandidateKey =
input.isBackSpace || input.isESC || input.isDelete
|| ((input.isCursorBackward || input.isCursorForward) && input.isShiftHold)
if cancelCandidateKey {
if (state is InputState.AssociatedPhrases)
|| mgrPrefs.useSCPCTypingMode
|| isBuilderEmpty
{
//
//
// 使 BackSpace
// isBuilderEmpty
clear()
stateCallback(InputState.EmptyIgnoringPreviousState())
} else {
stateCallback(buildInputtingState)
}
return true
}
// MARK: Enter
if input.isEnter {
if state is InputState.AssociatedPhrases {
clear()
stateCallback(InputState.EmptyIgnoringPreviousState())
return true
}
delegate!.keyHandler(
self,
didSelectCandidateAt: ctlCandidateCurrent.selectedCandidateIndex,
ctlCandidate: ctlCandidateCurrent
)
return true
}
// MARK: Enter
// MARK: Tab
if input.isEnter {
if state is InputState.AssociatedPhrases {
clear()
stateCallback(InputState.EmptyIgnoringPreviousState())
return true
if input.isTab {
let updated: Bool =
mgrPrefs.specifyShiftTabKeyBehavior
? (input.isShiftHold
? ctlCandidateCurrent.showPreviousPage()
: ctlCandidateCurrent.showNextPage())
: (input.isShiftHold
? ctlCandidateCurrent.highlightPreviousCandidate()
: ctlCandidateCurrent.highlightNextCandidate())
if !updated {
IME.prtDebugIntel("9B691919")
errorCallback()
}
return true
}
// MARK: Space
if input.isSpace {
let updated: Bool =
mgrPrefs.specifyShiftSpaceKeyBehavior
? (input.isShiftHold
? ctlCandidateCurrent.highlightNextCandidate()
: ctlCandidateCurrent.showNextPage())
: (input.isShiftHold
? ctlCandidateCurrent.showNextPage()
: ctlCandidateCurrent.highlightNextCandidate())
if !updated {
IME.prtDebugIntel("A11C781F")
errorCallback()
}
return true
}
// MARK: PgDn
if input.isPageDown || input.emacsKey == vChewingEmacsKey.nextPage {
let updated: Bool = ctlCandidateCurrent.showNextPage()
if !updated {
IME.prtDebugIntel("9B691919")
errorCallback()
}
return true
}
// MARK: PgUp
if input.isPageUp {
let updated: Bool = ctlCandidateCurrent.showPreviousPage()
if !updated {
IME.prtDebugIntel("9569955D")
errorCallback()
}
return true
}
// MARK: Left Arrow
if input.isLeft {
switch ctlCandidateCurrent.currentLayout {
case .horizontal:
do {
if !ctlCandidateCurrent.highlightPreviousCandidate() {
IME.prtDebugIntel("1145148D")
errorCallback()
}
}
case .vertical:
do {
if !ctlCandidateCurrent.showPreviousPage() {
IME.prtDebugIntel("1919810D")
errorCallback()
}
}
}
return true
}
// MARK: EmacsKey Backward
if input.emacsKey == vChewingEmacsKey.backward {
let updated: Bool = ctlCandidateCurrent.highlightPreviousCandidate()
if !updated {
IME.prtDebugIntel("9B89308D")
errorCallback()
}
return true
}
// MARK: Right Arrow
if input.isRight {
switch ctlCandidateCurrent.currentLayout {
case .horizontal:
do {
if !ctlCandidateCurrent.highlightNextCandidate() {
IME.prtDebugIntel("9B65138D")
errorCallback()
}
}
case .vertical:
do {
if !ctlCandidateCurrent.showNextPage() {
IME.prtDebugIntel("9244908D")
errorCallback()
}
}
}
return true
}
// MARK: EmacsKey Forward
if input.emacsKey == vChewingEmacsKey.forward {
let updated: Bool = ctlCandidateCurrent.highlightNextCandidate()
if !updated {
IME.prtDebugIntel("9B2428D")
errorCallback()
}
return true
}
// MARK: Up Arrow
if input.isUp {
switch ctlCandidateCurrent.currentLayout {
case .horizontal:
do {
if !ctlCandidateCurrent.showPreviousPage() {
IME.prtDebugIntel("9B614524")
errorCallback()
}
}
case .vertical:
do {
if !ctlCandidateCurrent.highlightPreviousCandidate() {
IME.prtDebugIntel("ASD9908D")
errorCallback()
}
}
}
return true
}
// MARK: Down Arrow
if input.isDown {
switch ctlCandidateCurrent.currentLayout {
case .horizontal:
do {
if !ctlCandidateCurrent.showNextPage() {
IME.prtDebugIntel("92B990DD")
errorCallback()
}
}
case .vertical:
do {
if !ctlCandidateCurrent.highlightNextCandidate() {
IME.prtDebugIntel("6B99908D")
errorCallback()
}
}
}
return true
}
// MARK: Home Key
if input.isHome || input.emacsKey == vChewingEmacsKey.home {
if ctlCandidateCurrent.selectedCandidateIndex == 0 {
IME.prtDebugIntel("9B6EDE8D")
errorCallback()
} else {
ctlCandidateCurrent.selectedCandidateIndex = 0
}
return true
}
// MARK: End Key
var candidates: [String]!
if let state = state as? InputState.ChoosingCandidate {
candidates = state.candidates
} else if let state = state as? InputState.AssociatedPhrases {
candidates = state.candidates
}
if candidates.isEmpty {
return false
} else { // count > 0!isEmpty滿
if input.isEnd || input.emacsKey == vChewingEmacsKey.end {
if ctlCandidateCurrent.selectedCandidateIndex == candidates.count - 1 {
IME.prtDebugIntel("9B69AAAD")
errorCallback()
} else {
ctlCandidateCurrent.selectedCandidateIndex = candidates.count - 1
}
}
}
// MARK: - Associated Phrases
if state is InputState.AssociatedPhrases {
if !input.isShiftHold { return false }
}
var index: Int = NSNotFound
var match: String!
if state is InputState.AssociatedPhrases {
match = input.inputTextIgnoringModifiers
} else {
match = inputText
}
var j = 0
while j < ctlCandidateCurrent.keyLabels.count {
let label: CandidateKeyLabel = ctlCandidateCurrent.keyLabels[j]
if match.compare(label.key, options: .caseInsensitive, range: nil, locale: .current) == .orderedSame {
index = j
break
}
j += 1
}
if index != NSNotFound {
let candidateIndex = ctlCandidateCurrent.candidateIndexAtKeyLabelIndex(index)
if candidateIndex != Int.max {
delegate!.keyHandler(
self,
didSelectCandidateAt: ctlCandidateCurrent.selectedCandidateIndex,
ctlCandidate: ctlCandidateCurrent
self, didSelectCandidateAt: candidateIndex, ctlCandidate: ctlCandidateCurrent
)
return true
}
}
// MARK: Tab
if state is InputState.AssociatedPhrases { return false }
if input.isTab {
let updated: Bool =
mgrPrefs.specifyShiftTabKeyBehavior
? (input.isShiftHold
? ctlCandidateCurrent.showPreviousPage()
: ctlCandidateCurrent.showNextPage())
: (input.isShiftHold
? ctlCandidateCurrent.highlightPreviousCandidate()
: ctlCandidateCurrent.highlightNextCandidate())
if !updated {
IME.prtDebugIntel("9B691919")
errorCallback()
}
return true
}
// MARK: SCPC Mode Processing
// MARK: Space
if mgrPrefs.useSCPCTypingMode {
var punctuationNamePrefix = ""
if input.isSpace {
let updated: Bool =
mgrPrefs.specifyShiftSpaceKeyBehavior
? (input.isShiftHold
? ctlCandidateCurrent.highlightNextCandidate()
: ctlCandidateCurrent.showNextPage())
: (input.isShiftHold
? ctlCandidateCurrent.showNextPage()
: ctlCandidateCurrent.highlightNextCandidate())
if !updated {
IME.prtDebugIntel("A11C781F")
errorCallback()
}
return true
}
// MARK: PgDn
if input.isPageDown || input.emacsKey == vChewingEmacsKey.nextPage {
let updated: Bool = ctlCandidateCurrent.showNextPage()
if !updated {
IME.prtDebugIntel("9B691919")
errorCallback()
}
return true
}
// MARK: PgUp
if input.isPageUp {
let updated: Bool = ctlCandidateCurrent.showPreviousPage()
if !updated {
IME.prtDebugIntel("9569955D")
errorCallback()
}
return true
}
// MARK: Left Arrow
if input.isLeft {
switch ctlCandidateCurrent.currentLayout {
case .horizontal:
do {
if !ctlCandidateCurrent.highlightPreviousCandidate() {
IME.prtDebugIntel("1145148D")
errorCallback()
}
}
case .vertical:
do {
if !ctlCandidateCurrent.showPreviousPage() {
IME.prtDebugIntel("1919810D")
errorCallback()
}
}
}
return true
}
// MARK: EmacsKey Backward
if input.emacsKey == vChewingEmacsKey.backward {
let updated: Bool = ctlCandidateCurrent.highlightPreviousCandidate()
if !updated {
IME.prtDebugIntel("9B89308D")
errorCallback()
}
return true
}
// MARK: Right Arrow
if input.isRight {
switch ctlCandidateCurrent.currentLayout {
case .horizontal:
do {
if !ctlCandidateCurrent.highlightNextCandidate() {
IME.prtDebugIntel("9B65138D")
errorCallback()
}
}
case .vertical:
do {
if !ctlCandidateCurrent.showNextPage() {
IME.prtDebugIntel("9244908D")
errorCallback()
}
}
}
return true
}
// MARK: EmacsKey Forward
if input.emacsKey == vChewingEmacsKey.forward {
let updated: Bool = ctlCandidateCurrent.highlightNextCandidate()
if !updated {
IME.prtDebugIntel("9B2428D")
errorCallback()
}
return true
}
// MARK: Up Arrow
if input.isUp {
switch ctlCandidateCurrent.currentLayout {
case .horizontal:
do {
if !ctlCandidateCurrent.showPreviousPage() {
IME.prtDebugIntel("9B614524")
errorCallback()
}
}
case .vertical:
do {
if !ctlCandidateCurrent.highlightPreviousCandidate() {
IME.prtDebugIntel("ASD9908D")
errorCallback()
}
}
}
return true
}
// MARK: Down Arrow
if input.isDown {
switch ctlCandidateCurrent.currentLayout {
case .horizontal:
do {
if !ctlCandidateCurrent.showNextPage() {
IME.prtDebugIntel("92B990DD")
errorCallback()
}
}
case .vertical:
do {
if !ctlCandidateCurrent.highlightNextCandidate() {
IME.prtDebugIntel("6B99908D")
errorCallback()
}
}
}
return true
}
// MARK: Home Key
if input.isHome || input.emacsKey == vChewingEmacsKey.home {
if ctlCandidateCurrent.selectedCandidateIndex == 0 {
IME.prtDebugIntel("9B6EDE8D")
errorCallback()
} else {
ctlCandidateCurrent.selectedCandidateIndex = 0
}
return true
}
// MARK: End Key
var candidates: [String]!
if let state = state as? InputState.ChoosingCandidate {
candidates = state.candidates
} else if let state = state as? InputState.AssociatedPhrases {
candidates = state.candidates
}
if candidates.isEmpty {
return false
} else { // count > 0!isEmpty滿
if input.isEnd || input.emacsKey == vChewingEmacsKey.end {
if ctlCandidateCurrent.selectedCandidateIndex == candidates.count - 1 {
IME.prtDebugIntel("9B69AAAD")
errorCallback()
} else {
ctlCandidateCurrent.selectedCandidateIndex = candidates.count - 1
}
}
}
// MARK: - Associated Phrases
if state is InputState.AssociatedPhrases {
if !input.isShiftHold { return false }
}
var index: Int = NSNotFound
var match: String!
if state is InputState.AssociatedPhrases {
match = input.inputTextIgnoringModifiers
if input.isOptionHold && !input.isControlHold {
punctuationNamePrefix = "_alt_punctuation_"
} else if input.isControlHold && !input.isOptionHold {
punctuationNamePrefix = "_ctrl_punctuation_"
} else if input.isControlHold && input.isOptionHold {
punctuationNamePrefix = "_alt_ctrl_punctuation_"
} else if mgrPrefs.halfWidthPunctuationEnabled {
punctuationNamePrefix = "_half_punctuation_"
} else {
match = inputText
punctuationNamePrefix = "_punctuation_"
}
var j = 0
while j < ctlCandidateCurrent.keyLabels.count {
let label: CandidateKeyLabel = ctlCandidateCurrent.keyLabels[j]
if match.compare(label.key, options: .caseInsensitive, range: nil, locale: .current) == .orderedSame {
index = j
break
}
j += 1
let parser = currentMandarinParser
let arrCustomPunctuations: [String] = [
punctuationNamePrefix, parser, String(format: "%c", CChar(charCode)),
]
let customPunctuation: String = arrCustomPunctuations.joined(separator: "")
let arrPunctuations: [String] = [punctuationNamePrefix, String(format: "%c", CChar(charCode))]
let punctuation: String = arrPunctuations.joined(separator: "")
var shouldAutoSelectCandidate: Bool =
_composer.inputValidityCheck(key: charCode) || ifLangModelHasUnigrams(forKey: customPunctuation)
|| ifLangModelHasUnigrams(forKey: punctuation)
if !shouldAutoSelectCandidate, input.isUpperCaseASCIILetterKey {
let letter: String! = String(format: "%@%c", "_letter_", CChar(charCode))
if ifLangModelHasUnigrams(forKey: letter) { shouldAutoSelectCandidate = true }
}
if index != NSNotFound {
let candidateIndex = ctlCandidateCurrent.candidateIndexAtKeyLabelIndex(index)
if shouldAutoSelectCandidate {
let candidateIndex = ctlCandidateCurrent.candidateIndexAtKeyLabelIndex(0)
if candidateIndex != Int.max {
delegate!.keyHandler(
self, didSelectCandidateAt: candidateIndex, ctlCandidate: ctlCandidateCurrent
self,
didSelectCandidateAt: candidateIndex,
ctlCandidate: ctlCandidateCurrent
)
clear()
let empty = InputState.EmptyIgnoringPreviousState()
stateCallback(empty)
return handle(
input: input, state: empty, stateCallback: stateCallback, errorCallback: errorCallback
)
return true
}
return true
}
if state is InputState.AssociatedPhrases { return false }
// MARK: SCPC Mode Processing
if mgrPrefs.useSCPCTypingMode {
var punctuationNamePrefix = ""
if input.isOptionHold && !input.isControlHold {
punctuationNamePrefix = "_alt_punctuation_"
} else if input.isControlHold && !input.isOptionHold {
punctuationNamePrefix = "_ctrl_punctuation_"
} else if input.isControlHold && input.isOptionHold {
punctuationNamePrefix = "_alt_ctrl_punctuation_"
} else if mgrPrefs.halfWidthPunctuationEnabled {
punctuationNamePrefix = "_half_punctuation_"
} else {
punctuationNamePrefix = "_punctuation_"
}
let parser = currentMandarinParser
let arrCustomPunctuations: [String] = [
punctuationNamePrefix, parser, String(format: "%c", CChar(charCode)),
]
let customPunctuation: String = arrCustomPunctuations.joined(separator: "")
let arrPunctuations: [String] = [punctuationNamePrefix, String(format: "%c", CChar(charCode))]
let punctuation: String = arrPunctuations.joined(separator: "")
var shouldAutoSelectCandidate: Bool =
_composer.inputValidityCheck(key: charCode) || ifLangModelHasUnigrams(forKey: customPunctuation)
|| ifLangModelHasUnigrams(forKey: punctuation)
if !shouldAutoSelectCandidate, input.isUpperCaseASCIILetterKey {
let letter: String! = String(format: "%@%c", "_letter_", CChar(charCode))
if ifLangModelHasUnigrams(forKey: letter) { shouldAutoSelectCandidate = true }
}
if shouldAutoSelectCandidate {
let candidateIndex = ctlCandidateCurrent.candidateIndexAtKeyLabelIndex(0)
if candidateIndex != Int.max {
delegate!.keyHandler(
self,
didSelectCandidateAt: candidateIndex,
ctlCandidate: ctlCandidateCurrent
)
clear()
let empty = InputState.EmptyIgnoringPreviousState()
stateCallback(empty)
return handle(
input: input, state: empty, stateCallback: stateCallback, errorCallback: errorCallback
)
}
return true
}
}
} // END: "if let ctlCandidateCurrent"
}
IME.prtDebugIntel("172A0F81")
errorCallback()