NSTextView 语法高亮

发布于 2024-08-21 03:17:43 字数 58 浏览 7 评论 0原文

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

I'm working on a Cocoa text editor which uses an NSTextView. Is it possible to change the color of certain portions of the text?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

孤独岁月 2024-08-28 03:17:43

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

在委托方法中,您需要使用 NSTextView-textStorage 方法从文本视图获取当前的 NSTextStorage 对象。 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];

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

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

You should add your controller as the delegate of the NSTextStorage object of the NSTextView ([textView textStorage]) and then implement the delegate method ‑textStorageDidProcessEditing:. This is called whenever the text changes.

In the delegate method you need to get the current NSTextStorage object from the text view using the -textStorage method of NSTextView. NSTextStorage is a subclass of NSAttributedString and contains the attributed contents of the view.

Your code must then parse the string and apply coloring to whatever ranges of text are interesting to you. You apply color to a range using something like this, which will apply a yellow color to the whole string:

//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];

How you parse the text is up to you. NSScanner is a useful class to use when parsing text.

Note that this method is by no means the most efficient way of handling syntax coloring. If the documents you are editing are very large you will most likely want to consider offloading the parsing to a separate thread and/or being clever about which sections of text are reparsed.

孤独难免 2024-08-28 03:17:43

Rob Keniger 的答案很好,但对于寻找更具体示例的人来说,这是我编写的一个简短的语法突出显示,应该突出显示正则表达式模板语法。我希望 \ 为灰色,紧随其后的字符为黑色。我希望 $ 为红色,紧跟在 $ 后面的数字字符也为红色。其他一切都应该是黑色的。这是我的解决方案:

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

@interface RMETemplateHighlighter : NSObject <NSTextStorageDelegate>

@end

我在 nib 文件中将其初始化为对象,并将其通过插座连接到我的视图控制器。在视图控制器的 awakeFromNib 中,我有这个(其中 replacer 是我的 NSTextView 出口,templateHighlighter 是出口对于上面的类):

self.replacer.textStorage.delegate = self.templateHighlighter;

我的实现如下所示:

- (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 == '

所以你就可以看到一个完全有效的示例。有一些细节让我绊倒了大约 10 分钟,比如您必须从 textStorage 中取出字符串才能访问各个字符……也许这可以为其他人节省几分钟。

) { NSUInteger l = ((i < n - 1) && isdigit([string characterAtIndex:i+1])) ? 2 : 1; [textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(i, l)]; i++; } } }

所以你就可以看到一个完全有效的示例。有一些细节让我绊倒了大约 10 分钟,比如您必须从 textStorage 中取出字符串才能访问各个字符……也许这可以为其他人节省几分钟。

Rob Keniger's answer is good, but for someone looking for a more concrete example, here's a short syntax highlighter I wrote that should highlight RegEx template syntax. I want \ to be gray, with the character immediately following them to be black. I want $ to be red, with a digit character immediately following the $ to also be red. Everything else should be black. Here's my solution:

I made a template highlighter class, with a header that looks like this:

@interface RMETemplateHighlighter : NSObject <NSTextStorageDelegate>

@end

I initialize it in the nib file as an object and hook it up to my view controller with an outlet. In awakeFromNib of the view controller, I have this (where replacer is my NSTextView outlet and templateHighlighter is the outlet for the class above):

self.replacer.textStorage.delegate = self.templateHighlighter;

And my implementation looks like this:

- (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 == '

So there you go, a fully working example. There were a few details that had me tripped up for ~10 minutes, like the fact that you have to take the string out of textStorage to access the individual characters... maybe this save other people a few minutes.

) { NSUInteger l = ((i < n - 1) && isdigit([string characterAtIndex:i+1])) ? 2 : 1; [textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(i, l)]; i++; } } }

So there you go, a fully working example. There were a few details that had me tripped up for ~10 minutes, like the fact that you have to take the string out of textStorage to access the individual characters... maybe this save other people a few minutes.

几味少女 2024-08-28 03:17:43

我建议您首先阅读有关语法高亮的 CocoaDev 页面。许多人为不同的目标提出了解决方案。

如果你想执行源代码语法高亮,我建议你看看UKSyntaxColoredTextDocument来自Uli Kusterer

I recommend you to start by reading the CocoaDev page about Syntax Highlighing. A lot of people have come with solutions for various goals.

If you want to perform source code syntax highlighting, I suggest you to take a look at the UKSyntaxColoredTextDocument from Uli Kusterer.

允世 2024-08-28 03:17:43

当然。您可以为 NSTextView 提供一个 NSAttributedString,您可以对属性字符串执行的一些操作是将颜色应用于字符串的某些子范围。

或者您可以在 Google 上搜索,会发现很多人都以前做过这方面的事情。

我可能会推荐使用 OkudaKit

Sure. You can give the NSTextView an NSAttributedString, and some of the stuff you can do with the attributed string is apply colors to certain subranges of the string.

Or you can search on Google and see that a lot of people have done stuff with this before.

I'd probably recommend using OkudaKit.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文