AvalonEdit: Cascading HighlightingColorizers
The problem is that the HighlightingColorizer
does not directly store a reference to the DocumentHighlighter
, but instead stores it via TextView.Services
. This is done to allow attaching the same colorizer to multiple editors, so that each editor gets its own DocumentHighlighter
.
When you attach a second colorizer, it overwrites the IHighlighter
stored in the service container; and both colorizers end up using the new highlighter.
Also, note that the 'copy to clipboard' logic in HtmlClipboard
directly accesses the IHighlighter
service, it does not use any colorizers. (copying text to Word preserves the syntax highlighting only, no other transformations like fold markers)
There are essentially two approaches to solve this issue:
Do not store the additional highlighter as a service. You can do this by creating your own copy of the
HighlightingColorizer
class, and use a field in that class instead of accessingtextView.Services
. This is an easy change, but additional highlighters will not be used when copying text to the clipboard.Create an
IHighlighter
implementation that combines theHighlightedLine
s from multipleDocumentHighlighter
s. This is the approach we are using for the C# semantic highlighting in SharpDevelop 5, which works as an additional highlighter that extends the existing .xshd-based C# highlighting. However, this approach is complex (mergingHighlightedLine
s is non-trivial given the ordering and nesting constraints on the sections), and requires an API change to theIHighlighter
interface in order to deal with theOnHighlightStateChanged
notification (AvalonEdit 4.x uses a derived class nested inHighlightingColorizer
to get access to this callback; AvalonEdit 5.0 will use an event).