diff --git a/Source/Modules/SessionCtl_Core.swift b/Source/Modules/SessionCtl_Core.swift index f885eccf..4274c231 100644 --- a/Source/Modules/SessionCtl_Core.swift +++ b/Source/Modules/SessionCtl_Core.swift @@ -23,12 +23,12 @@ import TooltipUI /// - Remark: 在輸入法的主函式中分配的 IMKServer 型別為客體應用程式創建的每個 /// 輸入會話創建一個控制器型別。因此,對於每個輸入會話,都有一個對應的 IMKInputController。 @objc(SessionCtl) // 必須加上 ObjC,因為 IMK 是用 ObjC 寫的。 -class SessionCtl: IMKInputController { +public class SessionCtl: IMKInputController { /// 標記狀態來聲明目前新增的詞彙是否需要賦以非常低的權重。 - static var areWeNerfing = false + public static var areWeNerfing = false /// 目前在用的的選字窗副本。 - var ctlCandidateCurrent: CtlCandidateProtocol = { + public var ctlCandidateCurrent: CtlCandidateProtocol = { let direction: NSUserInterfaceLayoutOrientation = PrefMgr.shared.useHorizontalCandidateList ? .horizontal : .vertical if #available(macOS 10.15, *) { @@ -40,18 +40,18 @@ class SessionCtl: IMKInputController { }() /// 工具提示視窗的副本。 - var tooltipInstance = TooltipUI() + public var tooltipInstance = TooltipUI() /// 浮動組字窗的副本。 - var popupCompositionBuffer = PopupCompositionBuffer() + public var popupCompositionBuffer = PopupCompositionBuffer() // MARK: - /// 當前 Caps Lock 按鍵是否被摁下。 - var isCapsLocked: Bool { NSEvent.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock) } + public var isCapsLocked: Bool { NSEvent.modifierFlags.intersection(.deviceIndependentFlagsMask).contains(.capsLock) } /// 當前這個 SessionCtl 副本是否處於英數輸入模式。 - var isASCIIMode = false { + public var isASCIIMode = false { didSet { resetKeyHandler() setKeyLayout() @@ -61,7 +61,7 @@ class SessionCtl: IMKInputController { /// 按鍵調度模組的副本。 var keyHandler = KeyHandler(lm: LMMgr.currentLM(), uom: LMMgr.currentUOM(), pref: PrefMgr.shared) /// 用以記錄當前輸入法狀態的變數。 - var state: IMEStateProtocol = IMEState.ofEmpty() { + public var state: IMEStateProtocol = IMEState.ofEmpty() { didSet { guard oldValue.type != state.type else { return } vCLog("Current State: \(state.type.rawValue), client: \(clientBundleIdentifier)") @@ -73,10 +73,11 @@ class SessionCtl: IMKInputController { /// Shift 按鍵事件分析器的副本。 /// - Remark: 警告:該工具必須為 Struct 且全專案只能有一個唯一初期化副本。否則會在動 Caps Lock 的時候誤以為是在摁 Shift。 - static var theShiftKeyDetector = ShiftKeyUpChecker(useLShift: PrefMgr.shared.togglingAlphanumericalModeWithLShift) + public static var theShiftKeyDetector = ShiftKeyUpChecker( + useLShift: PrefMgr.shared.togglingAlphanumericalModeWithLShift) /// `handle(event:)` 會利用這個參數判定某次 Shift 按鍵是否用來切換中英文輸入。 - var rencentKeyHandledByKeyHandlerEtc = false + public var rencentKeyHandledByKeyHandlerEtc = false /// 記錄當前輸入環境是縱排輸入還是橫排輸入。 public static var isVerticalTyping: Bool = false @@ -93,7 +94,7 @@ class SessionCtl: IMKInputController { /// InputMode 需要在每次出現內容變更的時候都連帶重設組字器與各項語言模組, /// 順帶更新 IME 模組及 UserPrefs 當中對於當前語言模式的記載。 - var inputMode: Shared.InputMode = IMEApp.currentInputMode { + public var inputMode: Shared.InputMode = IMEApp.currentInputMode { willSet { /// 將新的簡繁輸入模式提報給 Prefs 模組。IMEApp 模組會據此計算正確的資料值。 PrefMgr.shared.mostRecentInputMode = newValue.rawValue @@ -126,7 +127,7 @@ class SessionCtl: IMKInputController { /// - server: IMKServer /// - delegate: 客體物件 /// - inputClient: 用以接受輸入的客體應用物件 - override init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) { + override public init!(server: IMKServer!, delegate: Any!, client inputClient: Any!) { super.init(server: server, delegate: delegate, client: inputClient) keyHandler.delegate = self syncBaseLMPrefs() @@ -137,7 +138,7 @@ class SessionCtl: IMKInputController { extension SessionCtl { /// 指定鍵盤佈局。 - func setKeyLayout() { + public func setKeyLayout() { guard let client = client() else { return } func doSetKeyLayout() { @@ -154,7 +155,7 @@ extension SessionCtl { } /// 重設按鍵調度模組,會將當前尚未遞交的內容遞交出去。 - func resetKeyHandler() { + public func resetKeyHandler() { // 過濾掉尚未完成拼寫的注音。 if state.type == .ofInputting, PrefMgr.shared.trimUnfinishedReadingsOnCommit { keyHandler.composer.clear() @@ -174,7 +175,7 @@ extension SessionCtl { extension SessionCtl { /// 啟用輸入法時,會觸發該函式。 /// - Parameter sender: 呼叫了該函式的客體(無須使用)。 - override func activateServer(_ sender: Any!) { + public override func activateServer(_ sender: Any!) { _ = sender // 防止格式整理工具毀掉與此對應的參數。 UserDefaults.standard.synchronize() @@ -200,7 +201,7 @@ extension SessionCtl { /// 停用輸入法時,會觸發該函式。 /// - Parameter sender: 呼叫了該函式的客體(無須使用)。 - override func deactivateServer(_ sender: Any!) { + public override func deactivateServer(_ sender: Any!) { _ = sender // 防止格式整理工具毀掉與此對應的參數。 resetKeyHandler() // 這條會自動搞定 Empty 狀態。 handle(state: IMEState.ofDeactivated()) @@ -211,7 +212,7 @@ extension SessionCtl { /// - value: 輸入法在系統偏好設定當中的副本的 identifier,與 bundle identifier 類似。在輸入法的 info.plist 內定義。 /// - tag: 標記(無須使用)。 /// - sender: 呼叫了該函式的客體(無須使用)。 - override func setValue(_ value: Any!, forTag tag: Int, client sender: Any!) { + public override func setValue(_ value: Any!, forTag tag: Int, client sender: Any!) { _ = tag // 防止格式整理工具毀掉與此對應的參數。 _ = sender // 防止格式整理工具毀掉與此對應的參數。 let newInputMode = Shared.InputMode(rawValue: value as? String ?? "") ?? Shared.InputMode.imeModeNULL @@ -225,7 +226,7 @@ extension SessionCtl { } /// 將輸入法偏好設定同步至語言模組內。 - func syncBaseLMPrefs() { + public func syncBaseLMPrefs() { LMMgr.currentLM().isPhraseReplacementEnabled = PrefMgr.shared.phraseReplacementEnabled LMMgr.currentLM().isCNSEnabled = PrefMgr.shared.cns11643Enabled LMMgr.currentLM().isSymbolEnabled = PrefMgr.shared.symbolInputEnabled @@ -248,7 +249,7 @@ extension SessionCtl { /// 「`commitComposition(_ message)`」遞交給客體。 /// - Parameter sender: 呼叫了該函式的客體(無須使用)。 /// - Returns: 返回一個 uint,其中承載了與系統 NSEvent 操作事件有關的掩碼集合(詳見 NSEvent.h)。 - override func recognizedEvents(_ sender: Any!) -> Int { + public override func recognizedEvents(_ sender: Any!) -> Int { _ = sender // 防止格式整理工具毀掉與此對應的參數。 let events: NSEvent.EventTypeMask = [.keyDown, .flagsChanged] return Int(events.rawValue) @@ -258,7 +259,7 @@ extension SessionCtl { /// 也就是說 handle(event:) 完全抓不到這個 Event。 /// 這時需要在 commitComposition 這一關做一些收尾處理。 /// - Parameter sender: 呼叫了該函式的客體(無須使用)。 - override func commitComposition(_ sender: Any!) { + public override func commitComposition(_ sender: Any!) { _ = sender // 防止格式整理工具毀掉與此對應的參數。 resetKeyHandler() // super.commitComposition(sender) // 這句不要引入,否則每次切出輸入法時都會死當。 @@ -267,7 +268,7 @@ extension SessionCtl { /// 指定輸入法要遞交出去的內容(雖然 InputMethodKit 可能並不會真的用到這個函式)。 /// - Parameter sender: 呼叫了該函式的客體(無須使用)。 /// - Returns: 字串內容,或者 nil。 - override func composedString(_ sender: Any!) -> Any! { + public override func composedString(_ sender: Any!) -> Any! { _ = sender // 防止格式整理工具毀掉與此對應的參數。 guard state.hasComposition else { return "" } return state.displayedTextConverted @@ -275,7 +276,7 @@ extension SessionCtl { /// 輸入法要被換掉或關掉的時候,要做的事情。 /// 不過好像因為 IMK 的 Bug 而並不會被執行。 - override func inputControllerWillClose() { + public override func inputControllerWillClose() { // 下述兩行用來防止尚未完成拼寫的注音內容貝蒂交出去。 resetKeyHandler() super.inputControllerWillClose() diff --git a/Source/Modules/SessionCtl_Delegates.swift b/Source/Modules/SessionCtl_Delegates.swift index 2b42d90c..c1a19f79 100644 --- a/Source/Modules/SessionCtl_Delegates.swift +++ b/Source/Modules/SessionCtl_Delegates.swift @@ -11,18 +11,18 @@ import Shared // MARK: - KeyHandler Delegate extension SessionCtl: KeyHandlerDelegate { - var clientBundleIdentifier: String { + public var clientBundleIdentifier: String { guard let client = client() else { return "" } return client.bundleIdentifier() ?? "" } - func candidateController() -> CtlCandidateProtocol { ctlCandidateCurrent } + public func candidateController() -> CtlCandidateProtocol { ctlCandidateCurrent } - func candidateSelectionCalledByKeyHandler(at index: Int) { + public func candidateSelectionCalledByKeyHandler(at index: Int) { candidatePairSelected(at: index) } - func performUserPhraseOperation(with state: IMEStateProtocol, addToFilter: Bool) + public func performUserPhraseOperation(with state: IMEStateProtocol, addToFilter: Bool) -> Bool { guard state.type == .ofMarking else { return false } @@ -53,11 +53,11 @@ extension SessionCtl: KeyHandlerDelegate { // MARK: - Candidate Controller Delegate extension SessionCtl: CtlCandidateDelegate { - var selectionKeys: String { + public var selectionKeys: String { PrefMgr.shared.useIMKCandidateWindow ? "123456789" : PrefMgr.shared.candidateKeys } - func candidatePairs(conv: Bool = false) -> [(String, String)] { + public func candidatePairs(conv: Bool = false) -> [(String, String)] { if !state.isCandidateContainer || state.candidates.isEmpty { return [] } if !conv || PrefMgr.shared.cns11643Enabled || state.candidates[0].0.contains("_punctuation") { return state.candidates @@ -71,7 +71,7 @@ extension SessionCtl: CtlCandidateDelegate { return convertedCandidates } - func candidatePairSelected(at index: Int) { + public func candidatePairSelected(at index: Int) { if state.type == .ofSymbolTable, (0.. NSRect { + public func lineHeightRect(zeroCursor: Bool = false) -> NSRect { var lineHeightRect = NSRect.seniorTheBeast guard let client = client() else { return lineHeightRect @@ -40,7 +40,7 @@ extension SessionCtl { return lineHeightRect } - func show(tooltip: String) { + public func show(tooltip: String) { guard client() != nil else { return } let lineHeightRect = lineHeightRect() var finalOrigin: NSPoint = lineHeightRect.origin @@ -69,7 +69,7 @@ extension SessionCtl { ) } - func showCandidates() { + public func showCandidates() { guard let client = client() else { return } state.isVerticalCandidateWindow = (isVerticalTyping || !PrefMgr.shared.useHorizontalCandidateList) @@ -159,7 +159,7 @@ extension SessionCtl { /// 5) Do NOT enable either KangXi conversion mode nor JIS conversion mode. They are disabled by default. /// 6) Expecting the glyph differences of the candidate "骨" between PingFang SC and PingFang TC when rendering /// the candidate window in different "vChewing-CHS" and "vChewing-CHT" input modes. - static func candidateFont(name: String? = nil, size: Double) -> NSFont { + public static func candidateFont(name: String? = nil, size: Double) -> NSFont { let finalReturnFont: NSFont = { switch IMEApp.currentInputMode { diff --git a/Source/Modules/SessionCtl_HandleEvent.swift b/Source/Modules/SessionCtl_HandleEvent.swift index d4335676..6c343fee 100644 --- a/Source/Modules/SessionCtl_HandleEvent.swift +++ b/Source/Modules/SessionCtl_HandleEvent.swift @@ -20,7 +20,7 @@ extension SessionCtl { /// - event: 裝置操作輸入事件,可能會是 nil。 /// - sender: 呼叫了該函式的客體(無須使用)。 /// - Returns: 回「`true`」以將該案件已攔截處理的訊息傳遞給 IMK;回「`false`」則放行、不作處理。 - @objc(handleEvent:client:) override func handle(_ event: NSEvent!, client sender: Any!) -> Bool { + @objc(handleEvent:client:) public override func handle(_ event: NSEvent!, client sender: Any!) -> Bool { _ = sender // 防止格式整理工具毀掉與此對應的參數。 // MARK: 前置處理 diff --git a/Source/Modules/SessionCtl_HandleStates.swift b/Source/Modules/SessionCtl_HandleStates.swift index 521d55f5..5d59a82b 100644 --- a/Source/Modules/SessionCtl_HandleStates.swift +++ b/Source/Modules/SessionCtl_HandleStates.swift @@ -21,7 +21,7 @@ extension SessionCtl { /// 且開始敲字之後才會執行。這個過程會使得不同的 SessionCtl 副本之間出現 /// 不必要的互相干涉、打斷彼此的工作。 /// - Parameter newState: 新狀態。 - func handle(state newState: IMEStateProtocol) { + public func handle(state newState: IMEStateProtocol) { let previous = state state = newState switch state.type { @@ -97,7 +97,7 @@ extension SessionCtl { } /// 針對受 .NotEmpty() 管轄的非空狀態,在組字區內顯示游標。 - func setInlineDisplayWithCursor() { + public func setInlineDisplayWithCursor() { if state.type == .ofAssociates { doSetMarkedText( state.data.attributedStringPlaceholder, selectionRange: NSRange(location: 0, length: 0), @@ -152,7 +152,7 @@ extension SessionCtl { } /// 把 setMarkedText 包裝一下,按需啟用 GCD。 - func doSetMarkedText(_ string: Any!, selectionRange: NSRange, replacementRange: NSRange) { + public func doSetMarkedText(_ string: Any!, selectionRange: NSRange, replacementRange: NSRange) { guard let client = client() else { return } if let myID = Bundle.main.bundleIdentifier, let clientID = client.bundleIdentifier(), myID == clientID { DispatchQueue.main.async { diff --git a/Source/Modules/SessionCtl_IMKCandidatesData.swift b/Source/Modules/SessionCtl_IMKCandidatesData.swift index 066847c3..2689d983 100644 --- a/Source/Modules/SessionCtl_IMKCandidatesData.swift +++ b/Source/Modules/SessionCtl_IMKCandidatesData.swift @@ -15,7 +15,7 @@ extension SessionCtl { /// 生成 IMK 選字窗專用的候選字串陣列。 /// - Parameter sender: 呼叫了該函式的客體(無須使用)。 /// - Returns: IMK 選字窗專用的候選字串陣列。 - override func candidates(_ sender: Any!) -> [Any]! { + public override func candidates(_ sender: Any!) -> [Any]! { _ = sender // 防止格式整理工具毀掉與此對應的參數。 var arrResult = [String]() @@ -54,7 +54,7 @@ extension SessionCtl { /// IMK 選字窗限定函式,只要選字窗內的高亮內容選擇出現變化了、就會呼叫這個函式。 /// - Parameter _: 已經高亮選中的候選字詞內容。 - override open func candidateSelectionChanged(_: NSAttributedString!) { + public override func candidateSelectionChanged(_: NSAttributedString!) { // 警告:不要考慮用實作這個函式的方式來更新內文組字區的顯示。 // 因為這樣會導致 IMKServer.commitCompositionWithReply() 呼叫你本來不想呼叫的 commitComposition(), // 然後 keyHandler 會被重設,屆時輸入法會在狀態處理等方面崩潰掉。 @@ -71,7 +71,7 @@ extension SessionCtl { /// IMK 選字窗限定函式,只要選字窗確認了某個候選字詞的選擇、就會呼叫這個函式。 /// - Parameter candidateString: 已經確認的候選字詞內容。 - override open func candidateSelected(_ candidateString: NSAttributedString!) { + public override func candidateSelected(_ candidateString: NSAttributedString!) { let candidateString: String = candidateString?.string ?? "" if state.type == .ofAssociates { if !PrefMgr.shared.alsoConfirmAssociatedCandidatesByEnter { diff --git a/Source/Modules/SessionCtl_Menu.swift b/Source/Modules/SessionCtl_Menu.swift index c5b7b062..934f2889 100644 --- a/Source/Modules/SessionCtl_Menu.swift +++ b/Source/Modules/SessionCtl_Menu.swift @@ -20,7 +20,7 @@ extension Bool { // 因為選單部分的內容又臭又長,所以就單獨拉到一個檔案內管理了。 extension SessionCtl { - override func menu() -> NSMenu! { + public override func menu() -> NSMenu! { let optionKeyPressed = NSEvent.modifierFlags.contains(.option) let menu = NSMenu(title: "Input Method Menu") @@ -191,7 +191,7 @@ extension SessionCtl { // MARK: - IME Menu Items extension SessionCtl { - @objc override func showPreferences(_: Any?) { + @objc public override func showPreferences(_: Any?) { if #unavailable(macOS 10.15) { showLegacyPreferences() } else if NSEvent.modifierFlags.contains(.option) { @@ -203,24 +203,24 @@ extension SessionCtl { } } - func showLegacyPreferences() { + public func showLegacyPreferences() { (NSApp.delegate as? AppDelegate)?.showPreferences() NSApp.activate(ignoringOtherApps: true) } - @objc func showCheatSheet(_: Any?) { + @objc public func showCheatSheet(_: Any?) { guard let url = Bundle.main.url(forResource: "shortcuts", withExtension: "html") else { return } DispatchQueue.main.async { NSWorkspace.shared.openFile(url.path, withApplication: "Safari") } } - @objc func showClientListMgr(_: Any?) { + @objc public func showClientListMgr(_: Any?) { (NSApp.delegate as? AppDelegate)?.showClientListMgr() NSApp.activate(ignoringOtherApps: true) } - @objc func toggleSCPCTypingMode(_: Any? = nil) { + @objc public func toggleSCPCTypingMode(_: Any? = nil) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("Per-Char Select Mode", comment: "") + "\n" @@ -230,7 +230,7 @@ extension SessionCtl { ) } - @objc func toggleChineseConverter(_: Any?) { + @objc public func toggleChineseConverter(_: Any?) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("Force KangXi Writing", comment: "") + "\n" @@ -240,7 +240,7 @@ extension SessionCtl { ) } - @objc func toggleShiftJISShinjitaiOutput(_: Any?) { + @objc public func toggleShiftJISShinjitaiOutput(_: Any?) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("JIS Shinjitai Output", comment: "") + "\n" @@ -250,7 +250,7 @@ extension SessionCtl { ) } - @objc func toggleCurrencyNumerals(_: Any?) { + @objc public func toggleCurrencyNumerals(_: Any?) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("Currency Numeral Output", comment: "") + "\n" @@ -260,7 +260,7 @@ extension SessionCtl { ) } - @objc func toggleHalfWidthPunctuation(_: Any?) { + @objc public func toggleHalfWidthPunctuation(_: Any?) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("Half-Width Punctuation Mode", comment: "") + "\n" @@ -270,7 +270,7 @@ extension SessionCtl { ) } - @objc func toggleCNS11643Enabled(_: Any?) { + @objc public func toggleCNS11643Enabled(_: Any?) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("CNS11643 Mode", comment: "") + "\n" @@ -280,7 +280,7 @@ extension SessionCtl { ) } - @objc func toggleSymbolEnabled(_: Any?) { + @objc public func toggleSymbolEnabled(_: Any?) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("Symbol & Emoji Input", comment: "") + "\n" @@ -290,7 +290,7 @@ extension SessionCtl { ) } - @objc func toggleAssociatedPhrasesEnabled(_: Any?) { + @objc public func toggleAssociatedPhrasesEnabled(_: Any?) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("Per-Char Associated Phrases", comment: "") + "\n" @@ -300,7 +300,7 @@ extension SessionCtl { ) } - @objc func togglePhraseReplacement(_: Any?) { + @objc public func togglePhraseReplacement(_: Any?) { resetKeyHandler() Notifier.notify( message: NSLocalizedString("Use Phrase Replacement", comment: "") + "\n" @@ -310,20 +310,20 @@ extension SessionCtl { ) } - @objc func selfUninstall(_: Any?) { + @objc public func selfUninstall(_: Any?) { (NSApp.delegate as? AppDelegate)?.selfUninstall() } - @objc func selfTerminate(_: Any?) { + @objc public func selfTerminate(_: Any?) { NSApp.activate(ignoringOtherApps: true) NSApp.terminate(nil) } - @objc func checkForUpdate(_: Any?) { + @objc public func checkForUpdate(_: Any?) { (NSApp.delegate as? AppDelegate)?.updateSputnik.checkForUpdate(forced: true, url: kUpdateInfoSourceURL) } - @objc func openUserDataFolder(_: Any?) { + @objc public func openUserDataFolder(_: Any?) { if !LMMgr.userDataFolderExists { return } @@ -332,35 +332,35 @@ extension SessionCtl { ) } - @objc func openUserPhrases(_: Any?) { + @objc public func openUserPhrases(_: Any?) { LMMgr.openPhraseFile(fromURL: LMMgr.userPhrasesDataURL(IMEApp.currentInputMode)) if NSEvent.modifierFlags.contains(.option) { LMMgr.openPhraseFile(fromURL: LMMgr.userPhrasesDataURL(IMEApp.currentInputMode.reversed)) } } - @objc func openExcludedPhrases(_: Any?) { + @objc public func openExcludedPhrases(_: Any?) { LMMgr.openPhraseFile(fromURL: LMMgr.userFilteredDataURL(IMEApp.currentInputMode)) if NSEvent.modifierFlags.contains(.option) { LMMgr.openPhraseFile(fromURL: LMMgr.userFilteredDataURL(IMEApp.currentInputMode.reversed)) } } - @objc func openUserSymbols(_: Any?) { + @objc public func openUserSymbols(_: Any?) { LMMgr.openPhraseFile(fromURL: LMMgr.userSymbolDataURL(IMEApp.currentInputMode)) if NSEvent.modifierFlags.contains(.option) { LMMgr.openPhraseFile(fromURL: LMMgr.userSymbolDataURL(IMEApp.currentInputMode.reversed)) } } - @objc func openPhraseReplacement(_: Any?) { + @objc public func openPhraseReplacement(_: Any?) { LMMgr.openPhraseFile(fromURL: LMMgr.userReplacementsDataURL(IMEApp.currentInputMode)) if NSEvent.modifierFlags.contains(.option) { LMMgr.openPhraseFile(fromURL: LMMgr.userReplacementsDataURL(IMEApp.currentInputMode.reversed)) } } - @objc func openAssociatedPhrases(_: Any?) { + @objc public func openAssociatedPhrases(_: Any?) { LMMgr.openPhraseFile(fromURL: LMMgr.userAssociatesDataURL(IMEApp.currentInputMode)) if NSEvent.modifierFlags.contains(.option) { LMMgr.openPhraseFile( @@ -368,25 +368,25 @@ extension SessionCtl { } } - @objc func reloadUserPhrasesData(_: Any?) { + @objc public func reloadUserPhrasesData(_: Any?) { LMMgr.initUserLangModels() } - @objc func removeUnigramsFromUOM(_: Any?) { + @objc public func removeUnigramsFromUOM(_: Any?) { LMMgr.removeUnigramsFromUserOverrideModel(IMEApp.currentInputMode) if NSEvent.modifierFlags.contains(.option) { LMMgr.removeUnigramsFromUserOverrideModel(IMEApp.currentInputMode.reversed) } } - @objc func clearUOM(_: Any?) { + @objc public func clearUOM(_: Any?) { LMMgr.clearUserOverrideModelData(IMEApp.currentInputMode) if NSEvent.modifierFlags.contains(.option) { LMMgr.clearUserOverrideModelData(IMEApp.currentInputMode.reversed) } } - @objc func showAbout(_: Any?) { + @objc public func showAbout(_: Any?) { (NSApp.delegate as? AppDelegate)?.showAbout() NSApp.activate(ignoringOtherApps: true) }