From 1fdb767805534b431cffa7064c81d230a71cbae9 Mon Sep 17 00:00:00 2001 From: ShikiSuen Date: Sat, 6 Aug 2022 17:09:05 +0800 Subject: [PATCH] Repo // Refactor: improving phrase filtering / nerfing process. * Shift+CMD+Enter is now used for nerfing a phrase. * Use BackSpace or Delete to add the marked phrase to user phrase exclusion filter. --- .../ControllerModules/InputState.swift | 19 +++++++++--------- .../ControllerModules/KeyHandler_Core.swift | 2 +- .../ControllerModules/KeyHandler_States.swift | 20 ++++++++++++++++++- .../ctlInputMethod_Core.swift | 8 ++++---- .../ctlInputMethod_Delegates.swift | 13 ++++-------- .../Resources/Base.lproj/Localizable.strings | 2 +- Source/Resources/en.lproj/Localizable.strings | 2 +- Source/Resources/ja.lproj/Localizable.strings | 2 +- .../zh-Hans.lproj/Localizable.strings | 2 +- .../zh-Hant.lproj/Localizable.strings | 2 +- 10 files changed, 43 insertions(+), 29 deletions(-) diff --git a/Source/Modules/ControllerModules/InputState.swift b/Source/Modules/ControllerModules/InputState.swift index 943c3db1..d75ec67a 100644 --- a/Source/Modules/ControllerModules/InputState.swift +++ b/Source/Modules/ControllerModules/InputState.swift @@ -277,7 +277,7 @@ public enum InputState { return arrOutput.joined(separator: " ") } - private var deleteTargetExists = false + private var markedTargetExists = false var tooltip: String { if composingBuffer.count != readings.count { ctlInputMethod.tooltipController.setColor(state: .denialOverflow) @@ -318,11 +318,12 @@ public enum InputState { userPhrase: text, mode: IME.currentInputMode, key: joined ) if exist { - deleteTargetExists = exist + markedTargetExists = exist ctlInputMethod.tooltipController.setColor(state: .prompt) return String( format: NSLocalizedString( - "\"%@\" already exists: ENTER to boost, \n SHIFT+CMD+ENTER to exclude.", comment: "" + "\"%@\" already exists: ENTER to boost, SHIFT+CMD+ENTER to nerf, \n BackSpace or Delete key to exclude.", + comment: "" ) + "\n// " + literalReadingThread, text ) } @@ -397,12 +398,10 @@ public enum InputState { return state } - var validToWrite: Bool { + var validToFilter: Bool { /// 與小麥注音不同,威注音會自動解消「游標插斷字符」的異常狀態,所以允許在字音長度不相符的情況下加詞。 /// 這裡的 deleteTargetExists 是防止使用者排除「詞庫內尚未存在的詞」。 - (ctlInputMethod.areWeDeleting && !deleteTargetExists) - ? false - : allowedMarkRange.contains(literalMarkedRange.count) + markedTargetExists ? allowedMarkRange.contains(literalMarkedRange.count) : false } var chkIfUserPhraseExists: Bool { @@ -418,7 +417,8 @@ public enum InputState { let text = composingBuffer.utf16SubString(with: markedRange) let selectedReadings = readings[literalMarkedRange] let joined = selectedReadings.joined(separator: "-") - return "\(text) \(joined)" + let nerfedScore = ctlInputMethod.areWeNerfing && markedTargetExists ? " -114.514" : "" + return "\(text) \(joined)\(nerfedScore)" } var userPhraseConverted: String { @@ -426,8 +426,9 @@ public enum InputState { ChineseConverter.crossConvert(composingBuffer.utf16SubString(with: markedRange)) ?? "" let selectedReadings = readings[literalMarkedRange] let joined = selectedReadings.joined(separator: "-") + let nerfedScore = ctlInputMethod.areWeNerfing && markedTargetExists ? " -114.514" : "" let convertedMark = "#𝙃𝙪𝙢𝙖𝙣𝘾𝙝𝙚𝙘𝙠𝙍𝙚𝙦𝙪𝙞𝙧𝙚𝙙" - return "\(text) \(joined)\t\(convertedMark)" + return "\(text) \(joined)\(nerfedScore)\t\(convertedMark)" } } diff --git a/Source/Modules/ControllerModules/KeyHandler_Core.swift b/Source/Modules/ControllerModules/KeyHandler_Core.swift index 26ea1ccc..429bb248 100644 --- a/Source/Modules/ControllerModules/KeyHandler_Core.swift +++ b/Source/Modules/ControllerModules/KeyHandler_Core.swift @@ -23,7 +23,7 @@ protocol KeyHandlerDelegate { _: KeyHandler, didSelectCandidateAt index: Int, ctlCandidate controller: ctlCandidateProtocol ) - func keyHandler(_ keyHandler: KeyHandler, didRequestWriteUserPhraseWith state: InputStateProtocol) + func keyHandler(_ keyHandler: KeyHandler, didRequestWriteUserPhraseWith state: InputStateProtocol, addToFilter: Bool) -> Bool } diff --git a/Source/Modules/ControllerModules/KeyHandler_States.swift b/Source/Modules/ControllerModules/KeyHandler_States.swift index 4f303e52..59e283b6 100644 --- a/Source/Modules/ControllerModules/KeyHandler_States.swift +++ b/Source/Modules/ControllerModules/KeyHandler_States.swift @@ -177,7 +177,7 @@ extension KeyHandler { // Enter if input.isEnter { if let keyHandlerDelegate = delegate { - if !keyHandlerDelegate.keyHandler(self, didRequestWriteUserPhraseWith: state) { + if !keyHandlerDelegate.keyHandler(self, didRequestWriteUserPhraseWith: state, addToFilter: false) { IME.prtDebugIntel("5B69CC8D") errorCallback() return true @@ -187,6 +187,24 @@ extension KeyHandler { return true } + // BackSpace & Delete + if input.isBackSpace || input.isDelete { + if let keyHandlerDelegate = delegate { + if !state.validToFilter { + IME.prtDebugIntel("1F88B191") + errorCallback() + return true + } + if !keyHandlerDelegate.keyHandler(self, didRequestWriteUserPhraseWith: state, addToFilter: true) { + IME.prtDebugIntel("68D3C6C8") + errorCallback() + return true + } + } + stateCallback(buildInputtingState) + return true + } + // Shift + Left if input.isCursorBackward || input.emacsKey == EmacsKey.backward, input.isShiftHold { var index = state.markerIndex diff --git a/Source/Modules/ControllerModules/ctlInputMethod_Core.swift b/Source/Modules/ControllerModules/ctlInputMethod_Core.swift index 460b9a81..e9d60314 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_Core.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_Core.swift @@ -21,8 +21,8 @@ import InputMethodKit /// 輸入會話創建一個控制器型別。因此,對於每個輸入會話,都有一個對應的 IMKInputController。 @objc(ctlInputMethod) // 必須加上 ObjC,因為 IMK 是用 ObjC 寫的。 class ctlInputMethod: IMKInputController { - /// 標記狀態來聲明目前是在新增使用者語彙、還是準備要濾除使用者語彙。 - static var areWeDeleting = false + /// 標記狀態來聲明目前新增的詞彙是否需要賦以非常低的權重。 + static var areWeNerfing = false /// 目前在用的的選字窗副本。 static var ctlCandidateCurrent: ctlCandidateProtocol = ctlCandidateUniversal.init(.horizontal) @@ -209,8 +209,8 @@ class ctlInputMethod: IMKInputController { /// 否則,每次處理這種判斷時都會觸發 NSInternalInconsistencyException。 if event.type == .flagsChanged { return false } - // 準備修飾鍵,用來判定是否需要利用就地新增語彙時的 Enter 鍵來砍詞。 - ctlInputMethod.areWeDeleting = event.modifierFlags.contains([.shift, .command]) + // 準備修飾鍵,用來判定要新增的詞彙是否需要賦以非常低的權重。 + ctlInputMethod.areWeNerfing = event.modifierFlags.contains([.shift, .command]) var textFrame = NSRect.zero diff --git a/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift b/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift index 898c5d43..ead447f3 100644 --- a/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift +++ b/Source/Modules/ControllerModules/ctlInputMethod_Delegates.swift @@ -22,27 +22,22 @@ extension ctlInputMethod: KeyHandlerDelegate { ctlCandidate(controller, didSelectCandidateAtIndex: index) } - func keyHandler(_ keyHandler: KeyHandler, didRequestWriteUserPhraseWith state: InputStateProtocol) + func keyHandler(_ keyHandler: KeyHandler, didRequestWriteUserPhraseWith state: InputStateProtocol, addToFilter: Bool) -> Bool { - guard let state = state as? InputState.Marking else { - return false - } - if !state.validToWrite { - return false - } + guard let state = state as? InputState.Marking else { return false } let refInputModeReversed: InputMode = (keyHandler.inputMode == InputMode.imeModeCHT) ? InputMode.imeModeCHS : InputMode.imeModeCHT if !mgrLangModel.writeUserPhrase( state.userPhrase, inputMode: keyHandler.inputMode, areWeDuplicating: state.chkIfUserPhraseExists, - areWeDeleting: ctlInputMethod.areWeDeleting + areWeDeleting: addToFilter ) || !mgrLangModel.writeUserPhrase( state.userPhraseConverted, inputMode: refInputModeReversed, areWeDuplicating: false, - areWeDeleting: ctlInputMethod.areWeDeleting + areWeDeleting: addToFilter ) { return false diff --git a/Source/Resources/Base.lproj/Localizable.strings b/Source/Resources/Base.lproj/Localizable.strings index 9b8d0199..3a5162d4 100644 --- a/Source/Resources/Base.lproj/Localizable.strings +++ b/Source/Resources/Base.lproj/Localizable.strings @@ -29,7 +29,7 @@ "\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase."; "\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase."; "\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase."; -"\"%@\" already exists: ENTER to boost, \n SHIFT+CMD+ENTER to exclude." = "\"%@\" already exists: ENTER to boost, \n SHIFT+CMD+ENTER to exclude."; +"\"%@\" already exists: ENTER to boost, SHIFT+CMD+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists: ENTER to boost, SHIFT+CMD+ENTER to nerf, \n BackSpace or Delete key to exclude."; "Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…"; "Use Phrase Replacement" = "Use Phrase Replacement"; "Candidates keys cannot be empty." = "Candidates keys cannot be empty."; diff --git a/Source/Resources/en.lproj/Localizable.strings b/Source/Resources/en.lproj/Localizable.strings index 9b8d0199..3a5162d4 100644 --- a/Source/Resources/en.lproj/Localizable.strings +++ b/Source/Resources/en.lproj/Localizable.strings @@ -29,7 +29,7 @@ "\"%@\" length must ≥ 2 for a user phrase." = "\"%@\" length must ≥ 2 for a user phrase."; "\"%@\" length should ≤ %d for a user phrase." = "\"%@\" length should ≤ %d for a user phrase."; "\"%@\" selected. ENTER to add user phrase." = "\"%@\" selected. ENTER to add user phrase."; -"\"%@\" already exists: ENTER to boost, \n SHIFT+CMD+ENTER to exclude." = "\"%@\" already exists: ENTER to boost, \n SHIFT+CMD+ENTER to exclude."; +"\"%@\" already exists: ENTER to boost, SHIFT+CMD+ENTER to nerf, \n BackSpace or Delete key to exclude." = "\"%@\" already exists: ENTER to boost, SHIFT+CMD+ENTER to nerf, \n BackSpace or Delete key to exclude."; "Edit Phrase Replacement Table…" = "Edit Phrase Replacement Table…"; "Use Phrase Replacement" = "Use Phrase Replacement"; "Candidates keys cannot be empty." = "Candidates keys cannot be empty."; diff --git a/Source/Resources/ja.lproj/Localizable.strings b/Source/Resources/ja.lproj/Localizable.strings index 146eefca..9df877d1 100644 --- a/Source/Resources/ja.lproj/Localizable.strings +++ b/Source/Resources/ja.lproj/Localizable.strings @@ -29,7 +29,7 @@ "\"%@\" length must ≥ 2 for a user phrase." = "「%@」もう1つ文字のお選びを。"; "\"%@\" length should ≤ %d for a user phrase." = "「%@」文字数過剰で登録不可、%d 文字以内にして下さい。"; "\"%@\" selected. ENTER to add user phrase." = "「%@」を ENTER で辞書に登録。"; -"\"%@\" already exists: ENTER to boost, \n SHIFT+CMD+ENTER to exclude." = "「%@」は既存語彙:ENTER で最優先にし;\n SHIFT+CMD+ENTER で排除。"; +"\"%@\" already exists: ENTER to boost, SHIFT+CMD+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」は既存語彙:ENTER で最優先にし、SHIFT+CMD+ENTER で優先順位を下げる;\n BackSpace 或いは Delete で排除。"; "Edit Phrase Replacement Table…" = "言葉置換表を編集…"; "Use Phrase Replacement" = "言葉置換機能"; "Candidates keys cannot be empty." = "言選り用キー陣列に何かキーをご登録ください。"; diff --git a/Source/Resources/zh-Hans.lproj/Localizable.strings b/Source/Resources/zh-Hans.lproj/Localizable.strings index 3cc45095..1c1113f4 100644 --- a/Source/Resources/zh-Hans.lproj/Localizable.strings +++ b/Source/Resources/zh-Hans.lproj/Localizable.strings @@ -29,7 +29,7 @@ "\"%@\" length must ≥ 2 for a user phrase." = "「%@」字数不足以自订语汇。"; "\"%@\" length should ≤ %d for a user phrase." = "「%@」字数超过 %d、无法自订。"; "\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自订语汇。"; -"\"%@\" already exists: ENTER to boost, \n SHIFT+CMD+ENTER to exclude." = "「%@」已存在:敲 Enter 以升权;\n 敲 Shift+CMD+Enter 以排除。"; +"\"%@\" already exists: ENTER to boost, SHIFT+CMD+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:敲 Enter 以升权、敲 Shift+CMD+Enter 以降权;\n 敲 BackSpace 或 Delete 以排除。"; "Edit Phrase Replacement Table…" = "编辑语汇置换表…"; "Use Phrase Replacement" = "使用语汇置换"; "Candidates keys cannot be empty." = "您必须指定选字键。"; diff --git a/Source/Resources/zh-Hant.lproj/Localizable.strings b/Source/Resources/zh-Hant.lproj/Localizable.strings index 92c828cc..4f2e921a 100644 --- a/Source/Resources/zh-Hant.lproj/Localizable.strings +++ b/Source/Resources/zh-Hant.lproj/Localizable.strings @@ -29,7 +29,7 @@ "\"%@\" length must ≥ 2 for a user phrase." = "「%@」字數不足以自訂語彙。"; "\"%@\" length should ≤ %d for a user phrase." = "「%@」字數超過 %d、無法自訂。"; "\"%@\" selected. ENTER to add user phrase." = "「%@」敲 Enter 添入自訂語彙。"; -"\"%@\" already exists: ENTER to boost, \n SHIFT+CMD+ENTER to exclude." = "「%@」已存在:敲 Enter 以升權;\n 敲 Shift+CMD+Enter 以排除。"; +"\"%@\" already exists: ENTER to boost, SHIFT+CMD+ENTER to nerf, \n BackSpace or Delete key to exclude." = "「%@」已存在:敲 Enter 以升權、敲 Shift+CMD+Enter 以降權;\n 敲 BackSpace 或 Delete 以排除。"; "Edit Phrase Replacement Table…" = "編輯語彙置換表…"; "Use Phrase Replacement" = "使用語彙置換"; "Candidates keys cannot be empty." = "您必須指定選字鍵。";