AvalonEdit: каскадное выделение цветов
Я хочу каскадно подсвечивать синтаксис движка AvalonEdit. у меня есть 2 HighlightingDefinitions
, Первый - это основной синтаксис. Второй - это сложный язык многострочного препроцессора-разметки. По этой причине слишком сложно встраивать вторую грамматику в первую. Более простой способ - визуализировать первый синтаксис и впоследствии изменить затронутые части строки (на основе второго синтаксиса).
Таким образом, я создал новый HighlightingColorizer
со вторым языком и добавил его к LineTransformers
, Но второй язык раскрашивает весь документ, а не только строки с директивами препроцессора: код непроцессора черный.
Как я отлаживал ColorizeLine
- метод преобразователя второй строки, строки невыделенного кода (= без кода препроцессора) не были раскрашены, как ожидалось. Но цвет линий черный.
Так же как и HighlightingColorizer
сбросить все предыдущие выделения всего документа, прежде чем он начнет раскрашиваться?
Или в чем еще может быть проблема? Как я могу правильно каскад 2 HighlightingColorizers
?
1 ответ
Проблема в том, что HighlightingColorizer
непосредственно не хранит ссылку на DocumentHighlighter
, но вместо этого сохраняет его через TextView.Services
, Это сделано для того, чтобы разрешить присоединение одного и того же колоризатора к нескольким редакторам, чтобы каждый редактор получил свой собственный DocumentHighlighter
,
Когда вы присоединяете второй колоризатор, он перезаписывает IHighlighter
хранится в служебном контейнере; и оба колоризатора заканчивают тем, что использовали новый маркер.
Также обратите внимание, что логика "копировать в буфер обмена" в HtmlClipboard
напрямую обращается к IHighlighter
Сервис, он не использует колоризаторы. (копирование текста в Word сохраняет только подсветку синтаксиса, никаких других преобразований, таких как маркеры сгиба)
Существуют два основных подхода к решению этой проблемы:
Не храните дополнительный маркер как сервис. Вы можете сделать это, создав собственную копию
HighlightingColorizer
класс, и использовать поле в этом классе вместо доступаtextView.Services
, Это легко изменить, но дополнительные маркеры не будут использоваться при копировании текста в буфер обмена.Создать
IHighlighter
реализация, которая объединяетHighlightedLine
с несколькихDocumentHighlighter
s. Именно этот подход мы используем для семантической подсветки C# в SharpDevelop 5, которая работает как дополнительная подсветка, расширяющая существующую подсветку C# на основе.xshd. Однако этот подход сложен (объединениеHighlightedLine
s нетривиально, учитывая ограничения на порядок и вложение разделов), и требует изменения API дляIHighlighter
интерфейс для того, чтобы иметь дело сOnHighlightStateChanged
уведомление (AvalonEdit 4.x использует производный класс, вложенный вHighlightingColorizer
получить доступ к этому обратному вызову; AvalonEdit 5.0 будет использовать событие).