Processing shift-tab (backtab) events in NSTextView

February 22, 2020

I'm writing a Mac App which includes an NSTextView. One of the things I found difficult to discover online is how to respond to when the user presses shift-tab while editing in the text view - I wanted to intercept this event to de-indent a list item.

Turns out this is called a "backtab" and NSTextView has a built in way for consumers to respond to it, as part of NSTextViewDelegate. You implement the doCommandBy function and check for #selector(insertBacktab(_:))

extension MyViewController: NSTextViewDelegate {
    func textView(
        _ textView: NSTextView,
        doCommandBy commandSelector: Selector
    ) -> Bool {
        if commandSelector == #selector(insertBacktab(_:)) {
            print("Handling the backtab!")
            return true
        return false

Note: we return true to indicate that the event was handled, which prevents any other default behavior. We need to return false otherwise, since we still want other commands (like inserting newlines) to work correctly.