Semantic highlighting in OmniSharp and C# extension for VS Code

Two days ago I blogged about doing semantic classification of C# code using Roslyn. Today, I wanted to draw your attention to a new feature we have recently shipped in OmniSharp and which is now available as experimental feature in C# extension for VS Code, and that's improved OmniSharp semantic highlighting.

Semantic highlighting endpoint

The feature is builtt exactly according to the methodology and using the approach I described in my last post. It allows editors using OmniSharp to ask the OmniSharp language server to perform Roslyn-based semantic classification of the code (or a subset of code – a span). OmniSharp would then provide all the necessary classification information – types of classified spans and their locations, allowing the editors to do accurate and sophisticated, compiler-driven syntax highlighting.

This new revamped semantic highlighting feature shipped in OmniSharp 1.34.15 in March this year, as a /v2/highlight endpoint of OmniSharp. We already used to have /highlight endpoint for semantic highlighting, but the new one offers new data structures and support additional stuff, such as static modifiers, which justified the new version.

Client usage and adoption

Some of OmniSharp clients, such as omnisharp-vim, used the old highlighting already, but C# extension for VS Code never implemented that. In fact, there was no support for semantic highlighting in VS Code at all until version 1.42.0, when SemanticTokensProvider API was finally introduced.

Instead, up to that point, syntax highlighting in the extension (in all VS Code extensions, for that matter) was provided using a dedicated textMate grammar, which is a set of regular expressions corresponding to various language features. This approach was far from ideal, and caused a lot of problems – after all, it didn't have semantic understanding of the code, so the regular expressions were usually only close approximations of what we need to highlight. Additionally, the grammar had to be continually updated and maintained as the C# syntax and its features evolved – which, admittedly, we have not been most diligent about. This was actually the reason why recently in the C# extension for VS Code syntax highlighting would break completely, for example, with async enumerable.

The new semantic highlighting endpoint was adopted by the C# extension for VS Code, as an experimental feature, in release 1.22.0, from May this year. "Experimental" means in this case that it is an opt-in feature, and has to be enabled using the following setting:

csharp.semanticHighlighting.enabled controls enabling semantic highlighting with OmniSharp, and defaults to false. editor.semanticHighlighting.enabled controls enabling the semantic highlighting API in VS Code altogether, and defaults to true, however I wanted to explicitly mention it here, since if it was to be set to false for some reason, then the C# setting would have no effect.


The semantic highlighting is an exciting feature that improves the quality of syntax highlighting when working with C# in VS Code. I encourage you to enable this experimental setting and provide any bug report feedback in the extension repo or OmniSharp repo.