Podświetlanie składni NSTextView

Pracuję nad edytorem tekstu Cocoa, który używa NSTextView. Czy można zmienić kolor niektórych części tekstu?

Author: igul222, 2010-02-08

4 answers

Powinieneś dodać swój kontroler jako delegat NSTextStorage obiektu NSTextView ([textView textStorage]) a następnie zaimplementować metodę delegate ‑textStorageDidProcessEditing:. Jest to wywoływane za każdym razem, gdy tekst się zmienia.

W metodzie delegate należy pobrać bieżący obiekt NSTextStorage z widoku tekstowego przy użyciu metody -textStorage z NSTextView. NSTextStorage jest podklasą NSAttributedString i zawiera przypisaną zawartość widoku.

Twój kod musi następnie przetworzyć łańcuch znaków i zastosować kolorowanie do dowolnych zakresów tekstu interesujące dla Ciebie. Można zastosować kolor do zakresu za pomocą czegoś takiego, co zastosuje żółty kolor do całego ciągu:

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

Sposób parsowania tekstu zależy od Ciebie. NSScanner jest klasą przydatną do użycia podczas parsowania tekstu.

Zauważ, że ta metoda nie jest w żaden sposób najbardziej efektywnym sposobem obsługi kolorowania składni. Jeśli edytowane dokumenty są bardzo duże, najprawdopodobniej będziesz chciał rozważyć przeniesienie parsowania do osobnego wątku i / lub sprytne, co do którego fragmenty tekstu są reparsowane.

 29
Author: Rob Keniger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-08 22:52:35

Odpowiedź Roba Kenigera jest dobra, ale dla kogoś, kto szuka bardziej konkretnego przykładu, oto krótki zakreślacz składni, który napisałem, że powinien podświetlić składnię szablonu RegEx. Chcę, żeby \ była szara, a postać zaraz za nimi była czarna. Chcę, aby $ było czerwone, a znak cyfry zaraz po $ również był czerwony. Wszystko inne powinno być czarne. Oto moje rozwiązanie:

Zrobiłem klasę highlighter szablonu, z nagłówkiem, który wygląda Tak:

@interface RMETemplateHighlighter : NSObject <NSTextStorageDelegate>

@end

Inicjalizuję go w pliku nib jako obiekt i podłączam do mojego kontrolera widoku z gniazdem. W awakeFromNib kontrolera widoku mam to (gdzie replacer jest moim gniazdem NSTextView i templateHighlighter jest gniazdem dla powyższej klasy):

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

A moja realizacja wygląda tak:

- (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++;
        }
    }
}
Więc proszę bardzo, w pełni działający przykład. Było kilka szczegółów, które sprawiły, że potknąłem się na ~10 minut, jak fakt, że trzeba wyjąć sznurek z textStorage, aby uzyskać dostęp do poszczególnych znaków... może to uratuje innym kilka minut.
 9
Author: ArtOfWarfare,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:46:33

Polecam zacząć od przeczytania Strony o Zakreślaniu składni. Wiele osób przyszło z rozwiązaniami dla różnych celów.

Jeśli chcesz wykonać podświetlanie składni kodu źródłowego, proponuję rzucić okiem na UKSyntaxColoredTextDocument z Uli Kusterer.

 4
Author: Laurent Etiemble,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-08 08:57:13

Jasne. Możesz dać NSTextView an NSAttributedString, a niektóre rzeczy, które możesz zrobić z przypisanym ciągiem, to zastosować kolory do pewnych podzbiorów łańcucha.

Lub możesz wyszukać w Google i zobaczyć, że wiele osób robiło już z tym coś wcześniej.

Prawdopodobnie zalecałbym użycie OkudaKit .

 2
Author: Dave DeLong,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-07 21:36:53