AvalonEdit: каскадное выделение цветов - PullRequest
67 голосов
/ 24 января 2012

Я хочу каскадно подсвечивать синтаксис движка AvalonEdit.У меня 2 HighlightingDefinitions.Первый - это основной синтаксис.Второй - это сложный язык многострочного препроцессора-разметки.По этой причине слишком сложно встраивать вторую грамматику в первую.Более простой способ - визуализировать первый синтаксис и впоследствии изменить затронутые части строки (на основе второго синтаксиса).

Поэтому я создал новый HighlightingColorizer со вторым языком и добавил его в LineTransformers.Но второй язык раскрашивает весь документ, а не только строки с директивами препроцессора: код непроцессора черный.

Когда я отлаживал ColorizeLine -метод преобразователя второй строки,строки не подсвеченного кода (= без кода препроцессора) не были раскрашены, как ожидалось.Но цвет линий черный.

Так что же HighlightingColorizer сбрасывает все предыдущие выделения всего документа, прежде чем он начинает раскрашиваться?

Или в чем еще может быть проблема?Как правильно каскадировать 2 HighlightingColorizers?

1 Ответ

6 голосов
/ 18 октября 2012

Проблема в том, что HighlightingColorizer напрямую не хранит ссылку на DocumentHighlighter, а вместо этого сохраняет ее через TextView.Services.Это сделано для того, чтобы разрешить присоединять один и тот же колоризатор к нескольким редакторам, чтобы у каждого редактора был свой собственный DocumentHighlighter.

. При подключении второго колоризатора он перезаписывает IHighlighter, хранящийся в контейнере службы;и оба колоризатора заканчивают тем, что используют новый маркер.

Также обратите внимание, что логика «копировать в буфер» в HtmlClipboard напрямую обращается к сервису IHighlighter, она не использует никаких колоризаторов.(копирование текста в Word сохраняет только подсветку синтаксиса, никаких других преобразований, таких как маркеры сгиба) *

Существуют два основных подхода к решению этой проблемы:

  1. Не сохранятьдополнительный маркер как услуга.Вы можете сделать это, создав собственную копию класса HighlightingColorizer и использовать поле в этом классе вместо доступа к textView.Services.Это простое изменение, но дополнительные маркеры не будут использоваться при копировании текста в буфер обмена.

  2. Создание реализации IHighlighter, которая объединяет HighlightedLine s из нескольких DocumentHighlighters.Именно этот подход мы используем для семантической подсветки C # в SharpDevelop 5, которая работает как дополнительная подсветка, расширяющая существующую подсветку C # на основе .xshd.Однако этот подход сложен (объединение HighlightedLine s является нетривиальным заданным ограничением порядка и вложенности в разделах) и требует изменения API для интерфейса IHighlighter для обработки уведомления OnHighlightStateChanged (AvalonEdit4.x использует производный класс, вложенный в HighlightingColorizer, чтобы получить доступ к этому обратному вызову; AvalonEdit 5.0 будет использовать событие).

...