NSTextView语法高亮显示

igu*_*222 16 cocoa syntax-highlighting objective-c nstextview

我正在使用一个使用NSTextView的Cocoa文本编辑器.是否可以更改文本某些部分的颜色?

Rob*_*ger 29

您应该将控制器添加为()NSTextStorage对象的委托,然后实现委托方法.每当文本更改时都会调用此方法.NSTextView[textView textStorage]?textStorageDidProcessEditing:

在委托方法中,您需要NSTextStorage使用-textStorage方法从文本视图中获取当前对象NSTextView.NSTextStorageNSAttributedString视图的属性并包含视图的属性内容.

然后,您的代码必须解析字符串并将着色应用于您感兴趣的任何文本范围.您可以使用类似的颜色将颜色应用于范围,这将对整个字符串应用黄色:

//get the range of the entire run of text
NSRange area = NSMakeRange(0, [textStorage length]);

//remove existing coloring
[textStorage removeAttribute:NSForegroundColorAttributeName range:area];

//add new coloring
[textStorage addAttribute:NSForegroundColorAttributeName 
                    value:[NSColor yellowColor] 
                    range:area];
Run Code Online (Sandbox Code Playgroud)

你如何解析文本取决于你.NSScanner是解析文本时使用的有用类.

请注意,此方法绝不是处理语法着色的最有效方法.如果您正在编辑的文档非常大,您很可能会考虑将解析卸载到单独的线程和/或聪明地重新分析哪些文本部分.


Art*_*are 10

Rob Keniger的答案很好,但是对于寻找更具体的例子的人来说,这是一个我写的短语法高亮显示器应该突出显示RegEx模板语法.我想\变成灰色,跟着他们的角色变成黑色.我想要$变成红色,紧跟着后面的数字字符$也是红色的.其他一切都应该是黑色的.这是我的解决方案:

我制作了一个模板荧光笔类,其标题如下所示:

@interface RMETemplateHighlighter : NSObject <NSTextStorageDelegate>

@end
Run Code Online (Sandbox Code Playgroud)

我在nib文件中初始化它作为一个对象,并通过一个插座将它连接到我的视图控制器.在awakeFromNib视图控制器中,我有这个(replacer我的NSTextView插座在哪里,是templateHighlighter上面课程的出口):

self.replacer.textStorage.delegate = self.templateHighlighter;
Run Code Online (Sandbox Code Playgroud)

我的实现看起来像这样:

- (void)textStorageDidProcessEditing:(NSNotification *)notification {
    NSTextStorage *textStorage = notification.object;
    NSString *string = textStorage.string;
    NSUInteger n = string.length;
    [textStorage removeAttribute:NSForegroundColorAttributeName range:NSMakeRange(0, n)];
    for (NSUInteger i = 0; i < n; i++) {
        unichar c = [string characterAtIndex:i];
        if (c == '\\') {
            [textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor lightGrayColor] range:NSMakeRange(i, 1)];
            i++;
        } else if (c == '$') {
            NSUInteger l = ((i < n - 1) && isdigit([string characterAtIndex:i+1])) ? 2 : 1;
            [textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(i, l)];
            i++;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

所以,你去,一个完整的例子.有一些细节让我绊倒了大约10分钟,就像你必须从textStorage中取出字符串才能访问各个角色......也许这可以节省其他人几分钟.