39 lines
1.8 KiB
Swift
39 lines
1.8 KiB
Swift
import AppKit
|
|
import TermindPresentation
|
|
|
|
/// Keep the native field editor and binding in sync without interrupting marked-text composition.
|
|
enum SingleLineFieldEditing {
|
|
static func paste() {
|
|
guard let editor = NSApp.keyWindow?.firstResponder as? NSTextView,
|
|
let field = editor.delegate as? NSTextField, !(field is NSSecureTextField),
|
|
let text = NSPasteboard.general.string(forType: .string)
|
|
else { return }
|
|
insert(text, into: editor)
|
|
}
|
|
|
|
static func insert(_ text: String, into editor: NSTextView) {
|
|
editor.insertText(SingleLineTextInput.normalized(text), replacementRange: editor.selectedRange())
|
|
}
|
|
|
|
static func normalizedValue(in field: NSTextField) -> String? {
|
|
let editor = field.currentEditor() as? NSTextView
|
|
guard editor?.hasMarkedText() != true else { return nil }
|
|
let original = field.stringValue
|
|
let normalized = SingleLineTextInput.normalized(original)
|
|
guard original != normalized else { return original }
|
|
let selection = editor?.selectedRange()
|
|
field.stringValue = normalized
|
|
if let editor, let selection {
|
|
let originalString = original as NSString
|
|
let start = min(selection.location, originalString.length)
|
|
let end = start + min(selection.length, originalString.length - start)
|
|
let normalizedStart = (SingleLineTextInput.normalized(originalString.substring(to: start)) as NSString)
|
|
.length
|
|
let normalizedEnd = (SingleLineTextInput.normalized(originalString.substring(to: end)) as NSString).length
|
|
editor.string = normalized
|
|
editor.setSelectedRange(NSRange(location: normalizedStart, length: normalizedEnd - normalizedStart))
|
|
}
|
|
return normalized
|
|
}
|
|
}
|