My goal is to modify a string - remove all non-letters (numbers, whitespace, etc) - before pasting it in an NSTextView.
Via this link, I came up with the following code:
override func paste(_ sender: Any?) {
let pasteboard = NSPasteboard.general
// receive string from pasteboard
if let pasteboardString = pasteboard.string(forType: .string) {
let lettersOnly = CharacterSet.letters
// filter the incoming string
let lettersOnlyString = String(pasteboardString.unicodeScalars.filter { lettersOnly.contains($0) })
// put back filtered string into pasteboard
pasteboard.setString(lettersOnlyString, forType: .string)
super.paste(sender)
// put back initial formatted string
pasteboard.setString(pasteboardString, forType: .string)
}
}
lettersOnlyString
is indeed the modified string, but in the end the original string gets pasted anyway, I still see all non-letter characters.
What am I missing here, maybe this is not the route to go? Maybe I need to overwrite another method for this?
I think I found the answer, I had to add pasteboard.clearContents()
before pasteboard.setString
.
Just for completeness, this is the working code:
override func paste(_ sender: Any?) {
let pasteboard = NSPasteboard.general
// get string from pasteboard
if let pasteboardString = pasteboard.string(forType: .string) {
// remove formatting from string
let lettersOnly = CharacterSet.letters
let lettersOnlyString = String(pasteboardString.unicodeScalars.filter { lettersOnly.contains($0) })
// put modified string on pasteboard
pasteboard.clearContents()
pasteboard.setString(lettersOnlyString, forType: .string)
// paste string from pasteboard as plain text
pasteAsPlainText(sender)
// put original string back on pasteboard
pasteboard.clearContents()
pasteboard.setString(pasteboardString, forType: .string)
}
}
UPDATE:
It can be done even easier:
override func paste(_: Any?) {
let pasteboard = NSPasteboard.general
guard let pasteboardString = pasteboard.string(forType: .string),
let validatedInput = validateInput(pasteboardString)
else { return }
insertText(validatedInput, replacementRange: NSMakeRange(NSNotFound, 0))
}
where validateInput() is a refactored function that filters the input string.