AvalonEdit: каскадное выделение цветов

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

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

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

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

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

1 ответ

Решение

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

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

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

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

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

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

Другие вопросы по тегам