2012-01-24 15 views
67

Chcę kaskadować silnik SyntaxHighlighting AvalonEdit. Mam 2 HighlightingDefinitions. Pierwsza to główna składnia. Drugi to złożony wielowierszowy-preprocesor-język znaczników. Z tego powodu zbyt skomplikowane jest umieszczenie drugiej gramatyki w pierwszej. Najprostszym sposobem jest wyrenderowanie pierwszej składni i zmiana dotkniętych części linii (w oparciu o drugą składnię).AvalonEdit: Cascading HighlightingColorizers

Utworzono więc nowy HighlightingColorizer z drugim językiem i dodano go do LineTransformers. Ale drugi język jest kolorem kompletnego dokumentu, a nie tylko lineparty z dyrektywami preprocesora: kod nieprocesowy jest czarny.

Podczas debugowania metody ColorizeLine -metody drugiego transformatora liniowego, wiersze nie podświetlonego kodu (= brak kodu preprocesora) nie były kolorowane zgodnie z oczekiwaniami. Ale kolor linii jest czarny.

Czy też HighlightingColorizer resetuje wszystkie poprzednie wyróżnienia całego dokumentu, zanim zacznie się koloryzować?

Co jeszcze może być problemem? Jak mogę prawidłowo kaskadować 2 HighlightingColorizers?

+8

Pracowałem trochę z AvalonEdit- i IIRC resetuje wszystkie podświetlanie po zastosowaniu innego kolorowania. Najlepszym sposobem na powtórzenie tego jest powtórna próba osadzenia drugiej gramatyki w pierwszej próbie polegającej na tym, że musiałbyś zadzierać z bazą kodu AvalonEdit, aby zmienić sposób interpretacji i ponownego zastosowania schematu kolorów.Ta ostatnia prawdopodobnie nie byłaby trywialna, ponieważ nie sądzę, że będzie ona tak łatwa i "komentująca reset", czy coś w tym stylu. –

+7

@ Xeno jest tutaj. Z pewnością będziesz musiał edytować podstawę kodu, jeśli nie chcesz korzystać z plików definicji XML. Jednak nie jestem pewien, dlaczego nie chciałbyś tego zrobić - mogą być tak długo, jak chcesz i mogą być używane do pokolorowania małych szczegółów. Właśnie napisałem plik, aby zrobić coś podobnego z wbudowanym SQL; jest szybki i działa dobrze ... – MoonKnight

Odpowiedz

6

Problem polega na tym, że HighlightingColorizer nie zapisuje bezpośrednio odwołania do DocumentHighlighter, lecz przechowuje je przez TextView.Services. Dzieje się tak, aby umożliwić dołączenie tego samego koloratora do wielu edytorów, tak aby każdy edytor uzyskał własne DocumentHighlighter.

Po podłączeniu drugiego koloratora, zastępuje on IHighlighter przechowywany w kontenerze serwisowym; i oba koloryery kończą z użyciem nowego zakreślacza.

Należy również zauważyć, że logika "kopiuj do schowka" pod numerem HtmlClipboard zapewnia bezpośredni dostęp do usługi IHighlighter, nie używa żadnych koloratorów. (Kopiując tekst do programu Word zachowuje tylko podświetlanie składni, jak żadne inne transformacje krotnych markerów)

Istnieją zasadniczo dwa podejścia do tego problemu: rozwiązać

  1. Nie przechowywać dodatkowe wyróżnienia jako usługa. Możesz to zrobić, tworząc własną kopię klasy HighlightingColorizer i użyj pola w tej klasie zamiast dostępu do textView.Services. Jest to łatwa zmiana, ale dodatkowe zakreślacze nie będą używane podczas kopiowania tekstu do schowka.

  2. Utwórz implementację IHighlighter, która łączy w sobie HighlightedLine s z wielu DocumentHighlighter s. Jest to podejście, którego używamy do podkreślania semantycznego C# w SharpDevelop 5, który działa jako dodatkowy wyróżnik rozszerzający istniejące podświetlanie C# oparte na .shsh. Jednak takie podejście jest skomplikowane (połączenie HighlightedLine s jest nietrywialne, biorąc pod uwagę ograniczenia dotyczące porządkowania i zagnieżdżania w sekcjach) i wymaga zmiany interfejsu API w interfejsie IHighlighter w celu zaadresowania powiadomienia OnHighlightStateChanged (AvalonEdit 4.x używa wyprowadzonego klasa zagnieżdżona w HighlightingColorizer, aby uzyskać dostęp do tego wywołania zwrotnego, AvalonEdit 5.0 użyje zdarzenia).

+0

+1 bardzo fajna i pouczająca odpowiedź – Wh1T3h4Ck5

Powiązane problemy