Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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