diff --git a/Source/Modules/InputHandler_Core.swift b/Source/Modules/InputHandler_Core.swift index afbe8b6e..b9cf9463 100644 --- a/Source/Modules/InputHandler_Core.swift +++ b/Source/Modules/InputHandler_Core.swift @@ -202,6 +202,16 @@ public class InputHandler: InputHandlerProtocol { return arrResult } + /// 用來計算離當前游標最近的一個節點邊界的距離的函式。 + /// - Parameter direction: 文字輸入方向意義上的方向。 + /// - Returns: 邊界距離。 + func getStepsToNearbyNodeBorder(direction: Megrez.Compositor.TypingDirection) -> Int { + let currentCursor = compositor.cursor + var testCompositor = compositor + testCompositor.jumpCursorBySpan(to: direction) + return abs(testCompositor.cursor - currentCursor) + } + /// 鞏固當前組字器游標上下文,防止在當前游標位置固化節點時給作業範圍以外的內容帶來不想要的變化。 /// /// 打比方說輸入法原廠詞庫內有「章太炎」一詞,你敲「章太炎」,然後想把「太」改成「泰」以使其變成「章泰炎」。 diff --git a/Source/Modules/InputHandler_HandleStates.swift b/Source/Modules/InputHandler_HandleStates.swift index a6375049..3c8dde36 100644 --- a/Source/Modules/InputHandler_HandleStates.swift +++ b/Source/Modules/InputHandler_HandleStates.swift @@ -438,24 +438,32 @@ extension InputHandler { default: break } - if input.isShiftHold, input.isOptionHold { + let steps = getStepsToNearbyNodeBorder(direction: .rear) + var actualSteps = 1 + + switch input.modifierFlags { + case .shift: delegate.switchState(IMEState.ofAbortion()) return true + case .option: + actualSteps = steps + default: break } if isComposerOrCalligrapherEmpty { - if compositor.cursor > 0 { - compositor.dropKey(direction: .rear) - walk() - } else { + if compositor.cursor <= 0 || actualSteps <= 0 { delegate.callError("9D69908D") return true } + for _ in 0 ..< actualSteps { + compositor.dropKey(direction: .rear) + } + walk() } else { letComposerAndCalligrapherDoBackSpace() } - switch isComposerOrCalligrapherEmpty && compositor.isEmpty { + switch isConsideredEmptyForNow { case false: delegate.switchState(generateStateOfInputting()) case true: delegate.switchState(IMEState.ofAbortion()) } @@ -477,18 +485,28 @@ extension InputHandler { guard state.type == .ofInputting else { return false } - if input.isShiftHold { + let steps = getStepsToNearbyNodeBorder(direction: .front) + var actualSteps = 1 + + // macOS 認為 PC Delete 鍵訊號是必然有 .function 這個修飾鍵在起作用的。 + // 總之處理起來非常機車就是了。 + switch input.modifierFlags { + case _ where input.isShiftHold && !input.isOptionHold && !input.isControlHold: delegate.switchState(IMEState.ofAbortion()) return true - } - - if compositor.cursor == compositor.length, isComposerOrCalligrapherEmpty { - delegate.callError("9B69938D") - return true + case _ where !input.isShiftHold && input.isOptionHold && !input.isControlHold: + actualSteps = steps + default: break } if isComposerOrCalligrapherEmpty { - compositor.dropKey(direction: .front) + if compositor.cursor >= compositor.length || actualSteps <= 0 { + delegate.callError("9B69938D") + return true + } + for _ in 0 ..< actualSteps { + compositor.dropKey(direction: .front) + } walk() } else { clearComposerAndCalligrapher()