diff --git a/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator.swift b/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator.swift index 5d28b965..f52be57a 100644 --- a/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator.swift +++ b/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator.swift @@ -74,10 +74,6 @@ extension vChewingLM { // 磁帶資料模組。「currentCassette」對外唯讀,僅用來讀取磁帶本身的中繼資料(Metadata)。 static var lmCassette = LMCassette() - public var currentCassette: LMCassette { - get { Self.lmCassette } - set { Self.lmCassette = newValue } - } // 聲明使用者語言模組。 // 使用者語言模組使用多執行緒的話,可能會導致一些問題。有時間再仔細排查看看。 @@ -208,6 +204,7 @@ extension vChewingLM { } } + public var isCassetteDataLoaded: Bool { Self.lmCassette.isLoaded } public static func loadCassetteData(path: String) { DispatchQueue.main.async { if FileManager.default.isReadableFile(atPath: path) { diff --git a/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator_CassetteExtension.swift b/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator_CassetteExtension.swift new file mode 100644 index 00000000..4fb065ab --- /dev/null +++ b/Packages/vChewing_LangModelAssembly/Sources/LangModelAssembly/LMInstantiator_CassetteExtension.swift @@ -0,0 +1,52 @@ +// (c) 2021 and onwards The vChewing Project (MIT-NTL License). +// ==================== +// This code is released under the MIT license (SPDX-License-Identifier: MIT) +// ... with NTL restriction stating that: +// No trademark license is granted to use the trade names, trademarks, service +// marks, or product names of Contributor, except as required to fulfill notice +// requirements defined in MIT License. + +import Foundation +import Megrez +import Shared + +extension vChewingLM.LMInstantiator { + /// 當前磁帶所規定的花牌鍵。 + public var cassetteWildcardKey: String { Self.lmCassette.wildcardKey } + /// 當前磁帶規定的最大碼長。 + public var maxCassetteKeyLength: Int { Self.lmCassette.maxKeyLength } + + /// 將當前的按鍵轉換成磁帶內定義了的字根。 + /// - Parameter char: 按鍵字元。 + /// - Returns: 轉換結果。如果轉換失敗,則返回原始按鍵字元。 + public func convertCassetteKeyToDisplay(char: String) -> String { + Self.lmCassette.convertKeyToDisplay(char: char) + } + + /// 檢查當前的按鍵是否屬於目前的磁帶規定的允許的字根按鍵。 + /// - Parameter key: 按鍵字元。 + /// - Returns: 檢查結果。 + public func isThisCassetteKeyAllowed(key: String) -> Bool { + Self.lmCassette.allowedKeys.contains(key) + } + + /// 檢查給定的索引鍵在搭上花牌鍵之後是否有匹配結果。 + /// - Parameter key: 給定的索引鍵。 + /// - Returns: 是否有批配結果。 + public func hasCassetteWildcardResultsFor(key: String) -> Bool { + Self.lmCassette.hasUnigramsFor(key: key + Self.lmCassette.wildcard) + } + + /// 提供磁帶反查結果。 + /// - Parameter value: 要拿來反查的字詞。 + /// - Returns: 反查結果字串陣列。 + public func cassetteReverseLookup(for value: String) -> [String] { + var lookupResult = Self.lmCassette.reverseLookupMap[value] ?? [] + guard !lookupResult.isEmpty else { return [] } + lookupResult = lookupResult.map { $0.trimmingCharacters(in: .newlines) } + return lookupResult.stableSort(by: { $0.count < $1.count }).stableSort { + Self.lmCassette.unigramsFor(key: $0).count + < Self.lmCassette.unigramsFor(key: $1).count + } + } +} diff --git a/Source/Modules/InputHandler_Core.swift b/Source/Modules/InputHandler_Core.swift index 75f7ceea..9c0ce0b1 100644 --- a/Source/Modules/InputHandler_Core.swift +++ b/Source/Modules/InputHandler_Core.swift @@ -428,11 +428,9 @@ public class InputHandler: InputHandlerProtocol { return composer.getInlineCompositionForDisplay(isHanyuPinyin: prefs.showHanyuPinyinInCompositionBuffer) } if !prefs.showTranslatedStrokesInCompositionBuffer { return calligrapher } - var result = calligrapher.charComponents - for idx in 0.. Bool? { guard let delegate = delegate else { return nil } - var wildcardKey: String { currentLM.currentCassette.wildcardKey } // 花牌鍵。 - var wildcard: String { currentLM.currentCassette.wildcard } // 花牌鍵。 + var wildcardKey: String { currentLM.cassetteWildcardKey } // 花牌鍵。 let isWildcardKeyInput: Bool = (input.text == wildcardKey && !wildcardKey.isEmpty) var keyConsumedByStrokes = false @@ -193,14 +192,14 @@ extension InputHandler { var isLongestPossibleKeyFormed: Bool { guard !isWildcardKeyInput, prefs.autoCompositeWithLongestPossibleCassetteKey else { return false } - return !currentLM.currentCassette.hasUnigramsFor(key: calligrapher + wildcard) && !calligrapher.isEmpty + return !currentLM.hasCassetteWildcardResultsFor(key: calligrapher) && !calligrapher.isEmpty } var isStrokesFull: Bool { - calligrapher.count >= currentLM.currentCassette.maxKeyLength || isLongestPossibleKeyFormed + calligrapher.count >= currentLM.maxCassetteKeyLength || isLongestPossibleKeyFormed } - prehandling: if !skipStrokeHandling && currentLM.currentCassette.allowedKeys.contains(input.text) { + prehandling: if !skipStrokeHandling && currentLM.isThisCassetteKeyAllowed(key: input.text) { if calligrapher.isEmpty, isWildcardKeyInput { delegate.callError("3606B9C0") var newEmptyState = compositor.isEmpty ? IMEState.ofEmpty() : generateStateOfInputting() diff --git a/Source/Modules/SessionCtl_Delegates.swift b/Source/Modules/SessionCtl_Delegates.swift index 7b291f42..8c034071 100644 --- a/Source/Modules/SessionCtl_Delegates.swift +++ b/Source/Modules/SessionCtl_Delegates.swift @@ -69,14 +69,8 @@ extension SessionCtl: CtlCandidateDelegate { if isVerticalTyping { return blankResult } // 縱排輸入的場合,選字窗沒有足夠的空間顯示反查結果。 if value.isEmpty { return blankResult } // 空字串沒有需要反查的東西。 if value.contains("_") { return blankResult } - guard var lookupResult = LMMgr.currentLM.currentCassette.reverseLookupMap[value] else { return blankResult } - for i in 0..