NSTextView: When to automatically insert characters (like auto-matching parenthesis)?

540 views Asked by At

I've got an NSTextView and I'm acting as its NSTextStorage delegate, so I'm getting callbacks for textStorageWillProcessEditing: and textStorageDidProcessEditing:, and currently I'm using the did callback to change some attributes on the text (coloring certain words).

What I'd like to do is add auto-matching of certain character pairs. When the user types (, I want to insert a ) too but I'm not exactly sure when or where is the proper time to do this.

From the text storage delegate protocol, it says the will method lets you change the text to be displayed.. but I'm not really sure what that means or how I can do that. The text system is really big and confusing.

How should I do this?

1

There are 1 answers

0
willbur1984 On

In my open-source project, I subclassed NSTextView and overrode insertText: to handle the insertion of matching characters there. You can examine the argument to insertText: to see if it is something you want to act on, call super to perform the normal insertion of text, then call insertText: again with the appropriate matching character string if needed.

Something like this:

- (void)insertText:(id)insertString {
    [super insertText:insertString];

    // if the insert string isn't one character in length, it cannot be a brace character
    if ([insertString length] != 1)
        return;

    unichar firstCharacter = [insertString characterAtIndex:0];

    switch (firstCharacter) {
        case '(':
            [super insertString:@")"];
            break;
        case '[':
            [super insertString:@"]"];
            break;
        case '{':
            [super insertString:@"}"];
            break;
        default:
            return;
    }

    // adjust the selected range since we inserted an extra character
    [self setSelectedRange:NSMakeRange(self.selectedRange.location - 1, 0)];
}