InputHandler // Remove state parameter.
This commit is contained in:
parent
36a83f25a2
commit
581122720d
|
@ -40,7 +40,7 @@ public protocol InputHandlerDelegate {
|
|||
func switchState(_ newState: IMEStateProtocol)
|
||||
func candidateController() -> CtlCandidateProtocol
|
||||
func candidateSelectionCalledByInputHandler(at index: Int)
|
||||
func performUserPhraseOperation(with state: IMEStateProtocol, addToFilter: Bool)
|
||||
func performUserPhraseOperation(addToFilter: Bool)
|
||||
-> Bool
|
||||
}
|
||||
|
||||
|
|
|
@ -17,11 +17,9 @@ extension InputHandler {
|
|||
/// 當且僅當選字窗出現時,對於經過初次篩選處理的輸入訊號的處理均藉由此函式來進行。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入訊號。
|
||||
/// - state: 給定狀態(通常為當前狀態)。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
||||
func handleCandidate(
|
||||
state: IMEStateProtocol,
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
|
@ -31,6 +29,7 @@ extension InputHandler {
|
|||
}
|
||||
|
||||
var ctlCandidate = delegate.candidateController()
|
||||
let state = delegate.state
|
||||
|
||||
// MARK: 取消選字 (Cancel Candidate)
|
||||
|
||||
|
@ -287,9 +286,7 @@ extension InputHandler {
|
|||
if candidateIndex != -114_514 {
|
||||
delegate.candidateSelectionCalledByInputHandler(at: candidateIndex)
|
||||
delegate.switchState(IMEState.ofAbortion())
|
||||
return handleInput(
|
||||
event: input, state: IMEState.ofEmpty(), errorCallback: errorCallback
|
||||
)
|
||||
return handleInput(event: input, errorCallback: errorCallback)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ extension InputHandler {
|
|||
|
||||
/// 逐字選字模式的處理。
|
||||
if prefs.useSCPCTypingMode {
|
||||
let candidateState: IMEStateProtocol = generateStateOfCandidates(state: inputting)
|
||||
let candidateState: IMEStateProtocol = generateStateOfCandidates()
|
||||
switch candidateState.candidates.count {
|
||||
case 2...: delegate.switchState(candidateState)
|
||||
case 1:
|
||||
|
|
|
@ -25,8 +25,7 @@ extension InputHandler {
|
|||
/// 再根據返回的 result bool 數值來告知 IMK「這個按鍵事件是被處理了還是被放行了」。
|
||||
/// 這裡不用 handleCandidate() 是因為需要針對聯想詞輸入狀態做額外處理。
|
||||
private func doHandleInput(_ event: NSEvent) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
return handleInput(event: event, state: delegate.state) { errorString in
|
||||
handleInput(event: event) { errorString in
|
||||
vCLog(errorString)
|
||||
IMEApp.buzz()
|
||||
}
|
||||
|
|
|
@ -20,12 +20,10 @@ extension InputHandler {
|
|||
/// - Remark: 送入該函式處理之前,先用 inputHandler.handleEvent() 分診、來判斷是否需要交給 IMKCandidates 處理。
|
||||
/// - Parameters:
|
||||
/// - input: 輸入訊號。
|
||||
/// - state: 給定狀態(通常為當前狀態)。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 告知 IMK「該按鍵是否已經被輸入法攔截處理」。
|
||||
func handleInput(
|
||||
event input: InputSignalProtocol,
|
||||
state: IMEStateProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
// 如果按鍵訊號內的 inputTest 是空的話,則忽略該按鍵輸入,因為很可能是功能修飾鍵。
|
||||
|
@ -34,7 +32,7 @@ extension InputHandler {
|
|||
guard !input.text.isEmpty, input.charCode.isPrintable, let delegate = delegate else { return false }
|
||||
|
||||
let inputText: String = input.text
|
||||
var state = state // 常數轉變數。
|
||||
var state = delegate.state // 常數轉變數。
|
||||
|
||||
// 提前過濾掉一些不合規的按鍵訊號輸入,免得相關按鍵訊號被送給 Megrez 引發輸入法崩潰。
|
||||
if input.isInvalid {
|
||||
|
@ -107,17 +105,13 @@ extension InputHandler {
|
|||
// MARK: 處理候選字詞 (Handle Candidates)
|
||||
|
||||
if [.ofCandidates, .ofSymbolTable].contains(state.type) {
|
||||
return handleCandidate(
|
||||
state: state, input: input, errorCallback: errorCallback
|
||||
)
|
||||
return handleCandidate(input: input, errorCallback: errorCallback)
|
||||
}
|
||||
|
||||
// MARK: 處理聯想詞 (Handle Associated Phrases)
|
||||
|
||||
if state.type == .ofAssociates {
|
||||
if handleCandidate(
|
||||
state: state, input: input, errorCallback: errorCallback
|
||||
) {
|
||||
if handleCandidate(input: input, errorCallback: errorCallback) {
|
||||
return true
|
||||
} else {
|
||||
delegate.switchState(IMEState.ofEmpty())
|
||||
|
@ -127,12 +121,7 @@ extension InputHandler {
|
|||
// MARK: 處理標記範圍、以便決定要把哪個範圍拿來新增使用者(濾除)語彙 (Handle Marking)
|
||||
|
||||
if state.type == .ofMarking {
|
||||
if handleMarkingState(
|
||||
state, input: input,
|
||||
errorCallback: errorCallback
|
||||
) {
|
||||
return true
|
||||
}
|
||||
if handleMarkingState(input: input, errorCallback: errorCallback) { return true }
|
||||
state = state.convertedToInputting
|
||||
delegate.switchState(state)
|
||||
}
|
||||
|
@ -172,13 +161,10 @@ extension InputHandler {
|
|||
}
|
||||
return true
|
||||
} else if input.isShiftHold { // 臉書等網站會攔截 Tab 鍵,所以用 Shift+Command+Space 對候選字詞做正向/反向輪替。
|
||||
return handleInlineCandidateRotation(
|
||||
state: state, reverseModifier: input.isCommandHold,
|
||||
errorCallback: errorCallback
|
||||
)
|
||||
return handleInlineCandidateRotation(reverseOrder: input.isCommandHold, errorCallback: errorCallback)
|
||||
}
|
||||
}
|
||||
let candidateState: IMEStateProtocol = generateStateOfCandidates(state: state)
|
||||
let candidateState: IMEStateProtocol = generateStateOfCandidates()
|
||||
if candidateState.candidates.isEmpty {
|
||||
errorCallback("3572F238")
|
||||
} else {
|
||||
|
@ -191,56 +177,46 @@ extension InputHandler {
|
|||
|
||||
if let keyCodeType = KeyCode(rawValue: input.keyCode) {
|
||||
switch keyCodeType {
|
||||
case .kEscape: return handleEsc(state: state)
|
||||
case .kEscape: return handleEsc()
|
||||
case .kTab:
|
||||
return handleInlineCandidateRotation(
|
||||
state: state, reverseModifier: input.isShiftHold, errorCallback: errorCallback
|
||||
)
|
||||
return handleInlineCandidateRotation(reverseOrder: input.isShiftHold, errorCallback: errorCallback)
|
||||
case .kUpArrow, .kDownArrow, .kLeftArrow, .kRightArrow:
|
||||
if (input.isControlHold || input.isShiftHold) && (input.isOptionHold) {
|
||||
if input.isLeft { // Ctrl+PgLf / Shift+PgLf
|
||||
return handleHome(state: state, errorCallback: errorCallback)
|
||||
return handleHome(errorCallback: errorCallback)
|
||||
} else if input.isRight { // Ctrl+PgRt or Shift+PgRt
|
||||
return handleEnd(state: state, errorCallback: errorCallback)
|
||||
return handleEnd(errorCallback: errorCallback)
|
||||
}
|
||||
}
|
||||
if input.isCursorBackward { // Forward
|
||||
return handleBackward(
|
||||
state: state, input: input, errorCallback: errorCallback
|
||||
)
|
||||
return handleBackward(input: input, errorCallback: errorCallback)
|
||||
}
|
||||
if input.isCursorForward { // Backward
|
||||
return handleForward(
|
||||
state: state, input: input, errorCallback: errorCallback
|
||||
)
|
||||
return handleForward(input: input, errorCallback: errorCallback)
|
||||
}
|
||||
if input.isCursorClockLeft || input.isCursorClockRight { // Clock keys
|
||||
if input.isOptionHold, state.type == .ofInputting {
|
||||
if input.isCursorClockRight {
|
||||
return handleInlineCandidateRotation(
|
||||
state: state, reverseModifier: false, errorCallback: errorCallback
|
||||
)
|
||||
return handleInlineCandidateRotation(reverseOrder: false, errorCallback: errorCallback)
|
||||
}
|
||||
if input.isCursorClockLeft {
|
||||
return handleInlineCandidateRotation(
|
||||
state: state, reverseModifier: true, errorCallback: errorCallback
|
||||
)
|
||||
return handleInlineCandidateRotation(reverseOrder: true, errorCallback: errorCallback)
|
||||
}
|
||||
}
|
||||
return handleClockKey(state: state, errorCallback: errorCallback)
|
||||
return handleClockKey(errorCallback: errorCallback)
|
||||
}
|
||||
case .kHome: return handleHome(state: state, errorCallback: errorCallback)
|
||||
case .kEnd: return handleEnd(state: state, errorCallback: errorCallback)
|
||||
case .kHome: return handleHome(errorCallback: errorCallback)
|
||||
case .kEnd: return handleEnd(errorCallback: errorCallback)
|
||||
case .kBackSpace:
|
||||
return handleBackSpace(state: state, input: input, errorCallback: errorCallback)
|
||||
return handleBackSpace(input: input, errorCallback: errorCallback)
|
||||
case .kWindowsDelete:
|
||||
return handleDelete(state: state, input: input, errorCallback: errorCallback)
|
||||
return handleDelete(input: input, errorCallback: errorCallback)
|
||||
case .kCarriageReturn, .kLineFeed:
|
||||
return (input.isCommandHold && input.isControlHold)
|
||||
? (input.isOptionHold
|
||||
? handleCtrlOptionCommandEnter(state: state)
|
||||
: handleCtrlCommandEnter(state: state))
|
||||
: handleEnter(state: state)
|
||||
? handleCtrlOptionCommandEnter()
|
||||
: handleCtrlCommandEnter())
|
||||
: handleEnter()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +234,7 @@ extension InputHandler {
|
|||
var inputting = generateStateOfInputting()
|
||||
inputting.textToCommit = textToCommit
|
||||
delegate.switchState(inputting)
|
||||
let candidateState = generateStateOfCandidates(state: inputting)
|
||||
let candidateState = generateStateOfCandidates()
|
||||
if candidateState.candidates.isEmpty {
|
||||
errorCallback("B5127D8A")
|
||||
} else {
|
||||
|
@ -273,7 +249,7 @@ extension InputHandler {
|
|||
// 得在這裡先 commit buffer,不然會導致「在摁 ESC 離開符號選單時會重複輸入上一次的組字區的內容」的不當行為。
|
||||
// 於是這裡用「模擬一次 Enter 鍵的操作」使其代為執行這個 commit buffer 的動作。
|
||||
// 這裡不需要該函式所傳回的 bool 結果,所以用「_ =」解消掉。
|
||||
_ = handleEnter(state: state)
|
||||
_ = handleEnter()
|
||||
delegate.switchState(IMEState.ofSymbolTable(node: CandidateNode.root))
|
||||
return true
|
||||
}
|
||||
|
@ -304,11 +280,7 @@ extension InputHandler {
|
|||
let parser = currentKeyboardParser
|
||||
let arrCustomPunctuations: [String] = [punctuationNamePrefix, parser, input.text]
|
||||
let customPunctuation: String = arrCustomPunctuations.joined()
|
||||
if handlePunctuation(
|
||||
customPunctuation,
|
||||
state: state,
|
||||
errorCallback: errorCallback
|
||||
) {
|
||||
if handlePunctuation(customPunctuation, errorCallback: errorCallback) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -317,11 +289,7 @@ extension InputHandler {
|
|||
let arrPunctuations: [String] = [punctuationNamePrefix, input.text]
|
||||
let punctuation: String = arrPunctuations.joined()
|
||||
|
||||
if handlePunctuation(
|
||||
punctuation,
|
||||
state: state,
|
||||
errorCallback: errorCallback
|
||||
) {
|
||||
if handlePunctuation(punctuation, errorCallback: errorCallback) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -354,11 +322,7 @@ extension InputHandler {
|
|||
return true
|
||||
default: // 包括 case 0,直接塞給組字區。
|
||||
let letter = "_letter_\(inputText)"
|
||||
if handlePunctuation(
|
||||
letter,
|
||||
state: state,
|
||||
errorCallback: errorCallback
|
||||
) {
|
||||
if handlePunctuation(letter, errorCallback: errorCallback) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,15 +84,12 @@ extension InputHandler {
|
|||
|
||||
/// 拿著給定的候選字詞陣列資料內容,切換至選字狀態。
|
||||
/// - Parameters:
|
||||
/// - currentState: 當前狀態。
|
||||
/// - Returns: 回呼一個新的選詞狀態,來就給定的候選字詞陣列資料內容顯示選字窗。
|
||||
func generateStateOfCandidates(
|
||||
state currentState: IMEStateProtocol
|
||||
) -> IMEStateProtocol {
|
||||
func generateStateOfCandidates() -> IMEStateProtocol {
|
||||
IMEState.ofCandidates(
|
||||
candidates: generateArrayOfCandidates(fixOrder: prefs.useFixecCandidateOrderOnSelection),
|
||||
displayTextSegments: compositor.walkedNodes.values,
|
||||
cursor: currentState.cursor
|
||||
cursor: delegate?.state.cursor ?? generateStateOfInputting().cursor
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -110,9 +107,7 @@ extension InputHandler {
|
|||
/// - Parameters:
|
||||
/// - key: 給定的索引鍵(也就是給定的聯想詞的開頭字)。
|
||||
/// - Returns: 回呼一個新的聯想詞狀態,來就給定的聯想詞陣列資料內容顯示選字窗。
|
||||
public func generateStateOfAssociates(
|
||||
withPair pair: Megrez.Compositor.KeyValuePaired
|
||||
) -> IMEStateProtocol {
|
||||
public func generateStateOfAssociates(withPair pair: Megrez.Compositor.KeyValuePaired) -> IMEStateProtocol {
|
||||
IMEState.ofAssociates(
|
||||
candidates: generateArrayOfAssociates(withPair: pair))
|
||||
}
|
||||
|
@ -121,16 +116,15 @@ extension InputHandler {
|
|||
|
||||
/// 用以處理就地新增自訂語彙時的行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleMarkingState(
|
||||
_ state: IMEStateProtocol,
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
|
||||
if input.isEsc {
|
||||
delegate.switchState(generateStateOfInputting())
|
||||
|
@ -154,7 +148,7 @@ extension InputHandler {
|
|||
errorCallback("9AAFAC00")
|
||||
return true
|
||||
}
|
||||
if !delegate.performUserPhraseOperation(with: state, addToFilter: false) {
|
||||
if !delegate.performUserPhraseOperation(addToFilter: false) {
|
||||
errorCallback("5B69CC8D")
|
||||
return true
|
||||
}
|
||||
|
@ -168,7 +162,7 @@ extension InputHandler {
|
|||
errorCallback("1F88B191")
|
||||
return true
|
||||
}
|
||||
if !delegate.performUserPhraseOperation(with: state, addToFilter: true) {
|
||||
if !delegate.performUserPhraseOperation(addToFilter: true) {
|
||||
errorCallback("68D3C6C8")
|
||||
return true
|
||||
}
|
||||
|
@ -231,10 +225,10 @@ extension InputHandler {
|
|||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handlePunctuation(
|
||||
_ customPunctuation: String,
|
||||
state: IMEStateProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
|
||||
if !currentLM.hasUnigramsFor(key: customPunctuation) {
|
||||
return false
|
||||
|
@ -258,7 +252,7 @@ extension InputHandler {
|
|||
// 從這一行之後開始,就是針對逐字選字模式的單獨處理。
|
||||
guard prefs.useSCPCTypingMode, composer.isEmpty else { return true }
|
||||
|
||||
let candidateState = generateStateOfCandidates(state: inputting)
|
||||
let candidateState = generateStateOfCandidates()
|
||||
switch candidateState.candidates.count {
|
||||
case 2...: delegate.switchState(candidateState)
|
||||
case 1:
|
||||
|
@ -278,12 +272,10 @@ extension InputHandler {
|
|||
|
||||
/// Enter 鍵的處理。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleEnter(
|
||||
state: IMEStateProtocol
|
||||
) -> Bool {
|
||||
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))
|
||||
|
@ -295,12 +287,10 @@ extension InputHandler {
|
|||
|
||||
/// Command+Enter 鍵的處理(注音文)。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleCtrlCommandEnter(
|
||||
state: IMEStateProtocol
|
||||
) -> Bool {
|
||||
func handleCtrlCommandEnter() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
var displayedText = compositor.keys.joined(separator: "-")
|
||||
|
@ -322,12 +312,10 @@ extension InputHandler {
|
|||
|
||||
/// Command+Option+Enter 鍵的處理(網頁 Ruby 注音文標記)。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleCtrlOptionCommandEnter(
|
||||
state: IMEStateProtocol
|
||||
) -> Bool {
|
||||
func handleCtrlOptionCommandEnter() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
var composed = ""
|
||||
|
@ -357,16 +345,15 @@ extension InputHandler {
|
|||
|
||||
/// 處理 BackSpace (macOS Delete) 按鍵行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleBackSpace(
|
||||
state: IMEStateProtocol,
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
// 引入 macOS 內建注音輸入法的行為,允許用 Shift+BackSpace 解構前一個漢字的讀音。
|
||||
|
@ -418,16 +405,15 @@ extension InputHandler {
|
|||
|
||||
/// 處理 PC Delete (macOS Fn+BackSpace) 按鍵行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleDelete(
|
||||
state: IMEStateProtocol,
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if input.isShiftHold {
|
||||
|
@ -462,14 +448,13 @@ extension InputHandler {
|
|||
|
||||
/// 處理與當前文字輸入排版前後方向呈 90 度的那兩個方向鍵的按鍵行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleClockKey(
|
||||
state: IMEStateProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
if !composer.isEmpty {
|
||||
errorCallback("9B6F908D")
|
||||
|
@ -482,14 +467,13 @@ extension InputHandler {
|
|||
|
||||
/// 處理 Home 鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleHome(
|
||||
state: IMEStateProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if !composer.isEmpty {
|
||||
|
@ -513,14 +497,13 @@ extension InputHandler {
|
|||
|
||||
/// 處理 End 鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleEnd(
|
||||
state: IMEStateProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if !composer.isEmpty {
|
||||
|
@ -544,12 +527,10 @@ extension InputHandler {
|
|||
|
||||
/// 處理 Esc 鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleEsc(
|
||||
state: IMEStateProtocol
|
||||
) -> Bool {
|
||||
func handleEsc() -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if prefs.escToCleanInputBuffer {
|
||||
|
@ -573,16 +554,15 @@ extension InputHandler {
|
|||
|
||||
/// 處理向前方向鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleForward(
|
||||
state: IMEStateProtocol,
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if !composer.isEmpty {
|
||||
|
@ -612,7 +592,7 @@ extension InputHandler {
|
|||
}
|
||||
} else if input.isOptionHold {
|
||||
if input.isControlHold {
|
||||
return handleEnd(state: state, errorCallback: errorCallback)
|
||||
return handleEnd(errorCallback: errorCallback)
|
||||
}
|
||||
// 游標跳轉動作無論怎樣都會執行,但如果出了執行失敗的結果的話則觸發報錯流程。
|
||||
if !compositor.jumpCursorBySpan(to: .front) {
|
||||
|
@ -641,16 +621,15 @@ extension InputHandler {
|
|||
|
||||
/// 處理向後方向鍵的行為。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - input: 輸入按鍵訊號。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleBackward(
|
||||
state: IMEStateProtocol,
|
||||
input: InputSignalProtocol,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
guard state.type == .ofInputting else { return false }
|
||||
|
||||
if !composer.isEmpty {
|
||||
|
@ -680,7 +659,7 @@ extension InputHandler {
|
|||
}
|
||||
} else if input.isOptionHold {
|
||||
if input.isControlHold {
|
||||
return handleHome(state: state, errorCallback: errorCallback)
|
||||
return handleHome(errorCallback: errorCallback)
|
||||
}
|
||||
// 游標跳轉動作無論怎樣都會執行,但如果出了執行失敗的結果的話則觸發報錯流程。
|
||||
if !compositor.jumpCursorBySpan(to: .rear) {
|
||||
|
@ -709,16 +688,15 @@ extension InputHandler {
|
|||
|
||||
/// 以給定之參數來處理上下文候選字詞之輪替。
|
||||
/// - Parameters:
|
||||
/// - state: 當前狀態。
|
||||
/// - reverseModifier: 是否有控制輪替方向的修飾鍵輸入。
|
||||
/// - reverseOrder: 是否有控制輪替方向的修飾鍵輸入。
|
||||
/// - errorCallback: 錯誤回呼。
|
||||
/// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。
|
||||
func handleInlineCandidateRotation(
|
||||
state: IMEStateProtocol,
|
||||
reverseModifier: Bool,
|
||||
reverseOrder: Bool,
|
||||
errorCallback: @escaping (String) -> Void
|
||||
) -> Bool {
|
||||
guard let delegate = delegate else { return false }
|
||||
let state = delegate.state
|
||||
if composer.isEmpty, compositor.isEmpty || compositor.walkedNodes.isEmpty { return false }
|
||||
guard state.type == .ofInputting else {
|
||||
guard state.type == .ofEmpty else {
|
||||
|
@ -772,12 +750,12 @@ extension InputHandler {
|
|||
if candidates[0] == currentPaired {
|
||||
/// 如果第一個候選字詞是當前節點的候選字詞的值的話,
|
||||
/// 那就切到下一個(或上一個,也就是最後一個)候選字詞。
|
||||
currentIndex = reverseModifier ? candidates.count - 1 : 1
|
||||
currentIndex = reverseOrder ? candidates.count - 1 : 1
|
||||
}
|
||||
} else {
|
||||
for candidate in candidates {
|
||||
if candidate == currentPaired {
|
||||
if reverseModifier {
|
||||
if reverseOrder {
|
||||
if currentIndex == 0 {
|
||||
currentIndex = candidates.count - 1
|
||||
} else {
|
||||
|
|
|
@ -22,9 +22,7 @@ extension SessionCtl: InputHandlerDelegate {
|
|||
candidatePairSelected(at: index)
|
||||
}
|
||||
|
||||
public func performUserPhraseOperation(with state: IMEStateProtocol, addToFilter: Bool)
|
||||
-> Bool
|
||||
{
|
||||
public func performUserPhraseOperation(addToFilter: Bool) -> Bool {
|
||||
guard state.type == .ofMarking else { return false }
|
||||
if !LMMgr.writeUserPhrase(
|
||||
state.data.userPhraseDumped, inputMode: inputMode,
|
||||
|
|
Loading…
Reference in New Issue