0

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?

koen
  • 5,383
  • 7
  • 50
  • 89

1 Answers1

0

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.

koen
  • 5,383
  • 7
  • 50
  • 89