diff --git a/Packages/vChewing_LangModelAssembly/README.md b/Packages/vChewing_LangModelAssembly/README.md index c5fb705a..e679db0f 100644 --- a/Packages/vChewing_LangModelAssembly/README.md +++ b/Packages/vChewing_LangModelAssembly/README.md @@ -9,7 +9,7 @@ 以下是子模組: - lmCassette:專門用來處理 CIN 磁帶檔案的模組,命名為「遠野」引擎。 -- LMAssociates:聯想詞模組。 +- LMAssociates:關聯詞語模組。 - LMCoreEX:可以直接讀取 TXT 格式的帶有權重資料的語彙檔案的模組。 - LMCoreJSON:專門用來讀取原廠 JSON 檔案的模組。 - lmPlainBopomofo:專門用來讀取使用者自訂ㄅ半候選字順序覆蓋定義檔案(plist)的模組。 diff --git a/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator.swift b/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator.swift index ae353cd9..a41e7915 100644 --- a/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator.swift +++ b/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator.swift @@ -73,7 +73,7 @@ public extension vChewingLM { /// 比較適合那種每筆記錄都有不同的權重數值的語言模組,雖然也可以強制施加權重數值就是了。 /// LMCoreEX 的辭典陣列不承載 Unigram 本體、而是承載索引範圍,這樣可以節約記憶體。 /// 一個 LMCoreEX 就可以滿足威注音幾乎所有語言模組副本的需求,當然也有這兩個例外: - /// LMReplacements 與 LMAssociates 分別擔當語彙置換表資料與使用者聯想詞的資料承載工作。 + /// LMReplacements 與 LMAssociates 分別擔當語彙置換表資料與使用者關聯詞語的資料承載工作。 /// 但是,LMCoreEX 對 2010-2013 年等舊 mac 機種而言,讀取速度異常緩慢。 /// 於是 LMCoreJSON 就出場了,專門用來讀取原廠的 JSON 格式的辭典。 diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/IMEState.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/IMEState.swift index 74ce5573..4a75e226 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/IMEState.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/IMEState.swift @@ -33,7 +33,7 @@ import Shared /// 威注音輸入法在「組字區與組音區/組筆區同時為空」、 /// 且客體軟體正在準備接收使用者文字輸入行為的時候,會處於空狀態。 /// 有時,威注音會利用呼叫空狀態的方式,讓組字區內已經顯示出來的內容遞交出去。 -/// - **聯想詞狀態 .ofAssociates**: 逐字選字模式內的聯想詞輸入狀態。 +/// - **關聯詞語狀態 .ofAssociates**: 逐字選字模式內的關聯詞語輸入狀態。 /// - **中絕狀態 .ofAbortion**: 與 .ofEmpty() 類似,但會扔掉上一個狀態的內容、 /// 不將這些內容遞交給客體應用。該狀態在處理完畢之後會被立刻切換至 .ofEmpty()。 /// - **遞交狀態 .ofCommitting**: 該狀態會承載要遞交出去的內容,讓輸入法控制器處理時代為遞交。 diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_Core.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_Core.swift index 65966263..35c83c1c 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_Core.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_Core.swift @@ -198,18 +198,44 @@ public class InputHandler: InputHandlerProtocol { } } - /// 用以組建聯想詞陣列的函式。 - /// - Parameter key: 給定的聯想詞的開頭字。 - /// - Returns: 抓取到的聯想詞陣列。 + /// 用以組建關聯詞語陣列的函式,生成的內容不包含重複的結果。 + /// - Parameter pairs: 給定的詞音配對陣列。 + /// - Returns: 抓取到的關聯詞語陣列。 /// 不會是 nil,但那些負責接收結果的函式會對空白陣列結果做出正確的處理。 - func generateArrayOfAssociates(withPair pair: Megrez.KeyValuePaired) -> [(keyArray: [String], value: String)] { + func generateArrayOfAssociates(withPairs pairs: [Megrez.KeyValuePaired]) -> [(keyArray: [String], value: String)] { var arrResult: [(keyArray: [String], value: String)] = [] - if currentLM.hasAssociatedPhrasesFor(pair: pair) { - arrResult = currentLM.associatedPhrasesFor(pair: pair).map { ([""], $0) } + pairs.forEach { pair in + if currentLM.hasAssociatedPhrasesFor(pair: pair) { + let arrFetched: [String] = currentLM.associatedPhrasesFor(pair: pair) + arrFetched.forEach { thingToAdd in + // keyArray 對關聯詞語候選字詞而言(現階段)毫無意義。這裡只判斷 value。 + if !arrResult.map(\.value).contains(thingToAdd) { + arrResult.append((keyArray: [""], value: thingToAdd)) + } + } + } } return arrResult } + /// 用以組建關聯詞語陣列的函式,生成的內容不包含重複的結果。 + /// - Parameter pair: 給定的詞音配對。 + /// - Returns: 抓取到的關聯詞語陣列。 + /// 不會是 nil,但那些負責接收結果的函式會對空白陣列結果做出正確的處理。 + func generateArrayOfAssociates(withPair pair: Megrez.KeyValuePaired) -> [(keyArray: [String], value: String)] { + var pairs = [Megrez.KeyValuePaired]() + var keyArray = pair.keyArray + var value = pair.value + while !keyArray.isEmpty { + // 關聯詞語處理用不到組字引擎,故不需要 score。 + if keyArray.count == value.count { pairs.append(.init(keyArray: keyArray, value: value)) } + pairs.append(.init(key: "", value: value)) // 保底。 + keyArray = Array(keyArray.dropFirst()) + value = value.dropFirst().description + } + return generateArrayOfAssociates(withPairs: pairs) + } + /// 用來計算離當前游標最近的一個節點邊界的距離的函式。 /// - Parameter direction: 文字輸入方向意義上的方向。 /// - Returns: 邊界距離。 diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleCandidate.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleCandidate.swift index 686e2d49..f63af872 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleCandidate.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleCandidate.swift @@ -11,6 +11,7 @@ import CandidateWindow import CocoaExtension import InputMethodKit +import Megrez import Shared // MARK: - § 對選字狀態進行調度 (Handle Candidate State). @@ -96,7 +97,22 @@ extension InputHandler { delegate.switchState(IMEState.ofAbortion()) return true } + let highlightedCandidate = state.candidates[ctlCandidate.highlightedIndex] // 關聯詞語功能專用。 + var handleAssociates = !prefs.useSCPCTypingMode && prefs.associatedPhrasesEnabled // 關聯詞語功能專用。 + handleAssociates = handleAssociates && compositor.cursor == compositor.length // 關聯詞語功能專用。 confirmHighlightedCandidate() + // 關聯詞語。 + associatedPhrases: if handleAssociates { + guard handleAssociates else { break associatedPhrases } + guard input.keyModifierFlags == .shift else { break associatedPhrases } + let pair = Megrez.KeyValuePaired( + keyArray: highlightedCandidate.keyArray, value: highlightedCandidate.value + ) + let associatedCandidates = generateArrayOfAssociates(withPair: pair) + guard !associatedCandidates.isEmpty else { break associatedPhrases } + delegate.switchState(IMEState.ofCommitting(textToCommit: state.displayedText)) + delegate.switchState(IMEState.ofAssociates(candidates: associatedCandidates)) + } return true case .kTab: let updated: Bool = @@ -158,7 +174,7 @@ extension InputHandler { } } - // MARK: 聯想詞處理 (Associated Phrases) 以及標準選字處理 + // MARK: 關聯詞語處理 (Associated Phrases) 以及標準選字處理 if state.type == .ofAssociates, !input.isShiftHold { return false } diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleComposition.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleComposition.swift index 3a8c53c8..1d94d71d 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleComposition.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleComposition.swift @@ -186,8 +186,12 @@ extension InputHandler { delegate.switchState(IMEState.ofCommitting(textToCommit: text)) if prefs.associatedPhrasesEnabled { - let associatedPhrases = generateStateOfAssociates(withPair: .init(keyArray: reading, value: text)) - delegate.switchState(associatedPhrases.candidates.isEmpty ? IMEState.ofEmpty() : associatedPhrases) + let associatedCandidates = generateArrayOfAssociates(withPairs: [.init(keyArray: reading, value: text)]) + delegate.switchState( + associatedCandidates.isEmpty + ? IMEState.ofEmpty() + : IMEState.ofAssociates(candidates: associatedCandidates) + ) } default: break } @@ -348,20 +352,24 @@ extension InputHandler { inputting.textToCommit = textToCommit delegate.switchState(inputting) - /// 逐字選字模式的處理,與注音輸入的部分完全雷同。 + /// 逐字選字模式的處理。 if prefs.useSCPCTypingMode { let candidateState: IMEStateProtocol = generateStateOfCandidates() switch candidateState.candidates.count { case 2...: delegate.switchState(candidateState) case 1: let firstCandidate = candidateState.candidates.first! // 一定會有,所以強制拆包也無妨。 - let reading: String = firstCandidate.0.joined(separator: compositor.separator) + let reading: [String] = firstCandidate.keyArray let text: String = firstCandidate.value delegate.switchState(IMEState.ofCommitting(textToCommit: text)) if prefs.associatedPhrasesEnabled { - let associatedPhrases = generateStateOfAssociates(withPair: .init(keyArray: [reading], value: text)) - delegate.switchState(associatedPhrases.candidates.isEmpty ? IMEState.ofEmpty() : associatedPhrases) + let associatedCandidates = generateArrayOfAssociates(withPairs: [.init(keyArray: reading, value: text)]) + delegate.switchState( + associatedCandidates.isEmpty + ? IMEState.ofEmpty() + : IMEState.ofAssociates(candidates: associatedCandidates) + ) } default: break } diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleStates.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleStates.swift index d1d3661c..7703d85a 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleStates.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_HandleStates.swift @@ -149,23 +149,24 @@ extension InputHandler { return result } - // MARK: - 用以接收聯想詞陣列且生成狀態 + // MARK: - 用以接收關聯詞語陣列且生成狀態 - /// 拿著給定的聯想詞陣列資料內容,切換至聯想詞狀態。 + /// 拿著給定的關聯詞語陣列資料內容,切換至關聯詞語狀態。 /// /// 這次重寫時,針對「generateStateOfAssociates」這個(用以生成帶有 - /// 聯想詞候選清單的結果的狀態回呼的)函式進行了小幅度的重構處理,使其始終 + /// 關聯詞語候選清單的結果的狀態回呼的)函式進行了小幅度的重構處理,使其始終 /// 可以從 Core 部分的「generateArrayOfAssociates」函式獲取到一個內容類型 - /// 為「String」的標準 Swift 陣列。這樣一來,該聯想詞狀態回呼函式將始終能 + /// 為「String」的標準 Swift 陣列。這樣一來,該關聯詞語狀態回呼函式將始終能 /// 夠傳回正確的結果形態、永遠也無法傳回 nil。於是,所有在用到該函式時以 /// 回傳結果類型判斷作為合法性判斷依據的函式,全都將依據改為檢查傳回的陣列 /// 是否為空:如果陣列為空的話,直接回呼一個空狀態。 + /// + /// 該函式僅用於 SessionCtl,因為 InputHandler 內部可以直接存取 generateArrayOfAssociates(). /// - Parameters: - /// - key: 給定的索引鍵(也就是給定的聯想詞的開頭字)。 - /// - Returns: 回呼一個新的聯想詞狀態,來就給定的聯想詞陣列資料內容顯示選字窗。 + /// - key: 給定的索引鍵(也就是給定的關聯詞語的開頭字)。 + /// - Returns: 回呼一個新的關聯詞語狀態,來就給定的關聯詞語陣列資料內容顯示選字窗。 public func generateStateOfAssociates(withPair pair: Megrez.KeyValuePaired) -> IMEStateProtocol { - IMEState.ofAssociates( - candidates: generateArrayOfAssociates(withPair: pair)) + IMEState.ofAssociates(candidates: generateArrayOfAssociates(withPair: pair)) } // MARK: - 用以處理就地新增自訂語彙時的行為 @@ -342,9 +343,16 @@ extension InputHandler { // MARK: - Enter 鍵的處理,包括對其他修飾鍵的應對。 /// Enter 鍵的處理。 - /// - Parameter input: 輸入按鍵訊號。 + /// - Parameters: + /// - input: 輸入按鍵訊號。 + /// - readingOnly: 是否僅遞交讀音。 + /// - associatesData: 給定的關聯詞語資料陣列。 + /// 該部分僅對 .ofInputting() 狀態有效、且不能是漢音符號模式與內碼輸入模式。 /// - Returns: 將按鍵行為「是否有處理掉」藉由 SessionCtl 回報給 IMK。 - @discardableResult func handleEnter(input: InputSignalProtocol, readingOnly: Bool = false) -> Bool { + @discardableResult func handleEnter( + input: InputSignalProtocol, readingOnly: Bool = false, + associatesData: @escaping () -> ([(keyArray: [String], value: String)]) = { [] } + ) -> Bool { guard let delegate = delegate else { return false } let state = delegate.state @@ -360,13 +368,21 @@ extension InputHandler { } else if readingOnly { displayedText = commissionByCtrlCommandEnter() } else if input.isCommandHold, input.isControlHold { - displayedText = - input.isOptionHold - ? commissionByCtrlOptionCommandEnter(isShiftPressed: input.isShiftHold) - : commissionByCtrlCommandEnter(isShiftPressed: input.isShiftHold) + displayedText = input.isOptionHold + ? commissionByCtrlOptionCommandEnter(isShiftPressed: input.isShiftHold) + : commissionByCtrlCommandEnter(isShiftPressed: input.isShiftHold) } delegate.switchState(IMEState.ofCommitting(textToCommit: displayedText)) + + associatedPhrases: if !prefs.useSCPCTypingMode, prefs.associatedPhrasesEnabled { + guard input.keyModifierFlags == .shift else { break associatedPhrases } + guard isComposerOrCalligrapherEmpty else { break associatedPhrases } + let associatedCandidates = associatesData() + guard !associatedCandidates.isEmpty else { break associatedPhrases } + delegate.switchState(IMEState.ofAssociates(candidates: associatedCandidates)) + } + return true } diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_TriageInput.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_TriageInput.swift index 911c9292..e81b8942 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_TriageInput.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/InputHandler_TriageInput.swift @@ -13,6 +13,7 @@ import CocoaExtension import IMKUtils import InputMethodKit import LangModelAssembly +import Megrez import Shared // MARK: - § 根據狀態調度按鍵輸入 (Handle Input with States) * Triage @@ -45,7 +46,15 @@ public extension InputHandler { case .kEnd: return handleEnd() case .kBackSpace: return handleBackSpace(input: input) case .kWindowsDelete: return handleDelete(input: input) - case .kCarriageReturn, .kLineFeed: return handleEnter(input: input) + case .kCarriageReturn, .kLineFeed: + let frontNode = compositor.walkedNodes.last + return handleEnter(input: input) { + guard !self.isHaninKeyboardSymbolMode, !self.isCodePointInputMode else { return [] } + guard let frontNode = frontNode else { return [] } + let pair = Megrez.KeyValuePaired(keyArray: frontNode.keyArray, value: frontNode.value) + let associates = self.generateArrayOfAssociates(withPair: pair) + return associates + } case .kSymbolMenuPhysicalKeyJIS, .kSymbolMenuPhysicalKeyIntl: let isJIS = keyCodeType == .kSymbolMenuPhysicalKeyJIS switch input.keyModifierFlags { diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/SessionCtl_Delegates.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/SessionCtl_Delegates.swift index 09ccf68d..ca9fa1df 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/SessionCtl_Delegates.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/SessionCtl_Delegates.swift @@ -229,7 +229,7 @@ extension SessionCtl: CtlCandidateDelegate { defer { switchState(result) } // 這是最終輸出結果。 switchState(IMEState.ofCommitting(textToCommit: selectedValue.value)) guard PrefMgr.shared.associatedPhrasesEnabled else { return } - // 此時是聯想詞選字模式,所以「selectedValue.value」必須只保留最後一個字。 + // 此時是關聯詞語選字模式,所以「selectedValue.value」必須只保留最後一個字。 // 不然的話,一旦你選中了由多個字組成的聯想候選詞,則連續聯想會被打斷。 guard let valueKept = selectedValue.value.last?.description else { return } let associates = inputHandler.generateStateOfAssociates( diff --git a/Packages/vChewing_MainAssembly/Sources/MainAssembly/SettingsUI/VwrSettingsPaneKeyboard.swift b/Packages/vChewing_MainAssembly/Sources/MainAssembly/SettingsUI/VwrSettingsPaneKeyboard.swift index dfaf43fd..e2de462a 100644 --- a/Packages/vChewing_MainAssembly/Sources/MainAssembly/SettingsUI/VwrSettingsPaneKeyboard.swift +++ b/Packages/vChewing_MainAssembly/Sources/MainAssembly/SettingsUI/VwrSettingsPaneKeyboard.swift @@ -176,7 +176,7 @@ private struct VwrSettingsPaneKeyboard_KeyboardShortcuts: View { isOn: $usingHotKeySCPC ) Toggle( - LocalizedStringKey("Per-Char Associated Phrases"), + LocalizedStringKey("Associated Phrases"), isOn: $usingHotKeyAssociates ) Toggle( diff --git a/Packages/vChewing_Shared/Sources/Shared/Shared.swift b/Packages/vChewing_Shared/Sources/Shared/Shared.swift index 7ad16dc4..9297ef11 100644 --- a/Packages/vChewing_Shared/Sources/Shared/Shared.swift +++ b/Packages/vChewing_Shared/Sources/Shared/Shared.swift @@ -41,7 +41,7 @@ public enum StateType: String { /// 該狀態在處理完畢之後會被立刻切換至 .ofEmpty()。如果直接呼叫處理該狀態的話, /// 在呼叫處理之前的組字區的內容會消失,除非你事先呼叫處理過 .ofEmpty()。 case ofCommitting = "Committing" - /// **聯想詞狀態 .ofAssociates**: 逐字選字模式內的聯想詞輸入狀態。 + /// **關聯詞語狀態 .ofAssociates**: 逐字選字模式內的關聯詞語輸入狀態。 case ofAssociates = "Associates" /// **輸入狀態 .ofInputting**: 使用者輸入了內容。此時會出現組字區(Compositor)。 case ofInputting = "Inputting" diff --git a/Packages/vChewing_Shared/Sources/Shared/UserDef.swift b/Packages/vChewing_Shared/Sources/Shared/UserDef.swift index e73744ad..70b6c20e 100644 --- a/Packages/vChewing_Shared/Sources/Shared/UserDef.swift +++ b/Packages/vChewing_Shared/Sources/Shared/UserDef.swift @@ -492,7 +492,7 @@ public extension UserDef { description: "This will batch-replace specified candidates." ) case .kUsingHotKeySCPC: return .init(userDef: self, shortTitle: "Per-Char Select Mode") - case .kUsingHotKeyAssociates: return .init(userDef: self, shortTitle: "Per-Char Associated Phrases") + case .kUsingHotKeyAssociates: return .init(userDef: self, shortTitle: "Associated Phrases") case .kUsingHotKeyCNS: return .init(userDef: self, shortTitle: "CNS11643 Mode") case .kUsingHotKeyKangXi: return .init(userDef: self, shortTitle: "Force KangXi Writing") case .kUsingHotKeyJIS: return .init(userDef: self, shortTitle: "Reverse Lookup (Phonabets)") diff --git a/README-CHS.md b/README-CHS.md index 63f2c714..53c9cb64 100644 --- a/README-CHS.md +++ b/README-CHS.md @@ -29,7 +29,7 @@ >- 可以将自己打的繁体中文自动转成日本 JIS 新字体来输出(包括基础的字词转换)、也可以转成康熙繁体来输出。 >- 简繁体中文语料库彼此分离,彻底杜绝任何繁简转换过程可能造成的失误。 >- 支持近年的全字库汉字输入。 ->- 可以自动整理使用者语汇档案格式、自订联想词。 +>- 可以自动整理使用者语汇档案格式、自订关联词语。 >- …… 威注音分支专案及威注音词库由孙志贵(Shiki Suen)维护,其内容属于可在 Gitee 公开展示的合法内容。小麦注音官方原始仓库内的词库的内容均与孙志贵无关。 diff --git a/README.md b/README.md index 6ec5b7f1..528e0c8d 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ >- 可以將自己打的繁體中文自動轉成日本 JIS 新字體來輸出(包括基礎的字詞轉換)、也可以轉成康熙繁體來輸出。 >- 簡繁體中文語料庫彼此分離,徹底杜絕任何繁簡轉換過程可能造成的失誤。 >- 支援近年的全字庫漢字輸入。 ->- 可以自動整理使用者語彙檔案格式、自訂聯想詞。 +>- 可以自動整理使用者語彙檔案格式、自訂關聯詞語。 >- …… 威注音分支專案及威注音詞庫由孫志貴(Shiki Suen)維護,其內容屬於可在 Gitee 公開展示的合法內容。小麥注音官方原始倉庫內的詞庫的內容均與孫志貴無關。 diff --git a/Source/Modules/SessionCtl_Menu.swift b/Source/Modules/SessionCtl_Menu.swift index e4e69cf8..4da7fed2 100644 --- a/Source/Modules/SessionCtl_Menu.swift +++ b/Source/Modules/SessionCtl_Menu.swift @@ -49,7 +49,7 @@ extension SessionCtl { useSCPCTypingModeItem.state = PrefMgr.shared.useSCPCTypingMode.state let userAssociatedPhrasesItem = menu.addItem( - withTitle: "Per-Char Associated Phrases".localized, + withTitle: "Associated Phrases".localized, action: #selector(toggleAssociatedPhrasesEnabled(_:)), keyEquivalent: PrefMgr.shared.usingHotKeyAssociates ? "O" : "" ) @@ -350,7 +350,7 @@ public extension SessionCtl { @objc func toggleAssociatedPhrasesEnabled(_: Any? = nil) { resetInputHandler(forceComposerCleanup: true) Notifier.notify( - message: "Per-Char Associated Phrases".localized + "\n" + message: "Associated Phrases".localized + "\n" + (PrefMgr.shared.associatedPhrasesEnabled.toggled() ? "NotificationSwitchON".localized : "NotificationSwitchOFF".localized) diff --git a/Source/Resources/Base.lproj/Localizable.strings b/Source/Resources/Base.lproj/Localizable.strings index a4e46f12..8b68cc04 100644 --- a/Source/Resources/Base.lproj/Localizable.strings +++ b/Source/Resources/Base.lproj/Localizable.strings @@ -151,7 +151,7 @@ "Inline comments are not supported in associated phrases." = "Inline comments are not supported in associated phrases."; "CNS11643 Mode" = "CNS11643 Mode"; "JIS Shinjitai Output" = "JIS Shinjitai Output"; -"Per-Char Associated Phrases" = "Per-Char Associated Phrases"; +"Associated Phrases" = "Associated Phrases"; "Open User Dictionary Folder" = "Open User Dictionary Folder"; "Edit Associated Phrases…" = "Edit Associated Phrases…"; "Reboot vChewing…" = "Reboot vChewing…"; diff --git a/Source/Resources/en.lproj/Localizable.strings b/Source/Resources/en.lproj/Localizable.strings index a4e46f12..8b68cc04 100644 --- a/Source/Resources/en.lproj/Localizable.strings +++ b/Source/Resources/en.lproj/Localizable.strings @@ -151,7 +151,7 @@ "Inline comments are not supported in associated phrases." = "Inline comments are not supported in associated phrases."; "CNS11643 Mode" = "CNS11643 Mode"; "JIS Shinjitai Output" = "JIS Shinjitai Output"; -"Per-Char Associated Phrases" = "Per-Char Associated Phrases"; +"Associated Phrases" = "Associated Phrases"; "Open User Dictionary Folder" = "Open User Dictionary Folder"; "Edit Associated Phrases…" = "Edit Associated Phrases…"; "Reboot vChewing…" = "Reboot vChewing…"; diff --git a/Source/Resources/en.lproj/shortcuts.html b/Source/Resources/en.lproj/shortcuts.html index af560785..9bcbfc6e 100644 --- a/Source/Resources/en.lproj/shortcuts.html +++ b/Source/Resources/en.lproj/shortcuts.html @@ -17,7 +17,7 @@