From 3a63b9e48753d368437cac0095a1dd3295d912ab Mon Sep 17 00:00:00 2001 From: qwertyyb Date: Sun, 14 Apr 2024 15:10:02 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E5=9C=A8=E4=B8=AD?= =?UTF-8?q?=E6=96=87=E5=92=8C=E8=8B=B1=E6=96=87/=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E9=97=B4=E6=8F=92=E5=85=A5=E7=A9=BA=E6=A0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Fire/FireInputController.swift | 19 ++++++++++++++++--- Fire/Preferences/GeneralPane.swift | 5 ++++- Fire/Utils.swift | 22 ++++++++++++++++++++++ Fire/types.swift | 3 +++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/Fire/FireInputController.swift b/Fire/FireInputController.swift index fd39ba5..bd7e938 100644 --- a/Fire/FireInputController.swift +++ b/Fire/FireInputController.swift @@ -17,6 +17,7 @@ class FireInputController: IMKInputController { private var _candidates: [Candidate] = [] private var _hasNext: Bool = false private var _lastInputIsNumber = false + private var _lastInputText = "" internal var inputMode: InputMode { get { Fire.shared.inputMode } set(value) { Fire.shared.inputMode = value } @@ -132,6 +133,8 @@ class FireInputController: IMKInputController { private func enModeHandler(event: NSEvent) -> Bool? { // 英文输入模式, 不做任何处理 if inputMode == .enUS { + NSLog("[FireInputController] enModeHandler, in en mode: \(event.characters ?? "")") + _lastInputText = event.characters ?? "" return false } return nil @@ -252,6 +255,8 @@ class FireInputController: IMKInputController { if event.keyCode == kVK_Space && _originalString.count > 0 { if let first = self._candidates.first { insertCandidate(first) + } else { + _lastInputText = " " } return true } @@ -370,9 +375,17 @@ class FireInputController: IMKInputController { // 往输入框插入当前字符 func insertText(_ text: String) { NSLog("insertText: %@", text) - let value = NSAttributedString(string: text) - client()?.insertText(value, replacementRange: replacementRange()) - _lastInputIsNumber = text.last != nil && Int(String(text.last!)) != nil + if text.count > 0 { + var newText = text + if Defaults[.enableWhitespaceBetweenZhEn] && Utils.shared.shouldConcatWithWhitespace(_lastInputText, text) { + newText = " " + newText + NSLog("[FireInputController] insertCandidate should append whitespace: \(newText)") + } + let value = NSAttributedString(string: newText) + client()?.insertText(value, replacementRange: replacementRange()) + _lastInputIsNumber = newText.last != nil && Int(String(newText.last!)) != nil + _lastInputText = newText + } clean() } diff --git a/Fire/Preferences/GeneralPane.swift b/Fire/Preferences/GeneralPane.swift index 5242dce..4f82a65 100644 --- a/Fire/Preferences/GeneralPane.swift +++ b/Fire/Preferences/GeneralPane.swift @@ -24,6 +24,7 @@ struct GeneralPane: View { @Default(.disableEnMode) private var disableEnMode @Default(.disableTempEnMode) private var disableTempEnMode @Default(.showInputModeStatus) private var showInputModeStatus + @Default(.enableWhitespaceBetweenZhEn) private var enableWhitespaceBetweenZhEn var body: some View { Settings.Container(contentWidth: 450.0) { @@ -79,10 +80,12 @@ struct GeneralPane: View { GroupBox(label: Text("中英文切换")) { VStack(alignment: .leading, spacing: 12) { HStack { + Toggle("禁止切换英文", isOn: $disableEnMode) + Spacer() Toggle("状态栏显示", isOn: $showInputModeStatus) } HStack { - Toggle("禁止切换英文", isOn: $disableEnMode) + Toggle("中文与英文/数字之间插入空格", isOn: $enableWhitespaceBetweenZhEn) Spacer() Toggle("禁用;键临时英文模式", isOn: $disableTempEnMode) } diff --git a/Fire/Utils.swift b/Fire/Utils.swift index 05e0fa5..eafe8c0 100644 --- a/Fire/Utils.swift +++ b/Fire/Utils.swift @@ -61,6 +61,28 @@ class Utils { } return NSScreen.main } + + // 根据上次输入的字符,判断插入的新字符是否要前加空格 + func shouldConcatWithWhitespace(_ lastText: String, _ nextText: String) -> Bool { + NSLog("[Utils] shouldConcatWithWhitespace, lastText: \(lastText), nextText: \(nextText)") + if lastText.count <= 0 || nextText.count <= 0 { + return false + } + guard let firstEnReg = try? NSRegularExpression(pattern: "[a-zA-Z0-9]$"), + let nextCnReg = try? NSRegularExpression(pattern: "^[\\u4e00-\\u9fa5]") else { + return false + } + if firstEnReg.numberOfMatches(in: lastText, range: NSMakeRange(0, lastText.count)) > 0 + && nextCnReg.numberOfMatches(in: nextText, range: NSMakeRange(0, nextText.count)) > 0 { + return true + } + guard let firstCnReg = try? NSRegularExpression(pattern: "[\\u4e00-\\u9fa5]$"), + let nextEnReg = try? NSRegularExpression(pattern: "^[a-zA-Z0-9]") else { + return false + } + return firstCnReg.numberOfMatches(in: lastText, range: NSMakeRange(0, lastText.count)) > 0 + && nextEnReg.numberOfMatches(in: nextText, range: NSMakeRange(0, nextText.count)) > 0 + } static let shared = Utils() } diff --git a/Fire/types.swift b/Fire/types.swift index 4100a9a..780d70b 100644 --- a/Fire/types.swift +++ b/Fire/types.swift @@ -129,6 +129,9 @@ extension Defaults.Keys { static let customPunctuationSettings = Key<[String: String]>("customPunctuationSettings", default: punctuation) // 数字后输入"。"自动转为"." static let enableDotAfterNumber = Key("enableDotAfterNumber", default: true) + // 在中文和英文之间插入空格,在中文输入模式下生效,也可在英文模式下输入英文再切到中文输入模式下输入中文时生效 + // 在从中文模式输入中文后再切到英文输入模式下输入英文时不生效 + static let enableWhitespaceBetweenZhEn = Key("enableWhitespaceBetweenZhEn", default: true) static let wbTablePath = Key( "wbTableURL",