Making the world a better place, one line of code at a time

Syntax-highlighted Markdown Code Blocks in Web Essentials

Posted on Tuesday, December 10, 2013

After over two months of work, I rewrote the Markdown editor in Web Essentials to support syntax highlighting & IntelliSense for embedded code blocks.

If you add a GitHub-style fenced code block with a language identifier, Visual Studio will now provide full language services within that code block. You get the full editing experience you’re used to in Visual Studio, including syntax highlighting, IntelliSense, outlining, error checking, code snippets, and Peek Definition.

Markdown Code Blocks Markdown IntelliSense & Errors

This is perfect for writing Readmes or documentation for open-source projects on GitHub, or for any other Markdown files you may write.

How it works

Visual Studio 2010 rewrote the editor from the ground up in WPF. This new editor has a powerful feature called Projection Buffers, which allow a single editor to seamlessly mix text from different sources. This can be used to make a virtual editor that mixes code from different files (eg, Debugger Canvas), or to mix different languages within a single file (eg, Javascript and CSS blocks within an HTML file).

My Markdown editor uses this feature to project code blocks in your Markdown files using Visual Studio’s built-in editor services

What languages are supported?

Any language that Visual Studio can highlight, including any custom extensions you’ve installed.

All languages services built for the new WPF-based editor should work perfectly with projection buffers. This includes HTML (sort of), CSS, Javascript, and any languages from extensions that only work in VS2010 or later. The language service itself needs to work properly with projection buffers; if it makes unwarranted assumptions about text buffers always having files on disk or only one TextView, things may not work.

If the language service needs to initialize things for its services to work (eg, a project system), I can still support it using an ICodeLanguageEmbedder, which Web Essentials will call to initialize whatever is necessary. If you have such a language service, feel free to send a pull request.

Before VS2010, an older system called contained languages allowed editors to be mixed like this. However, this system needed explicit integration from the language service being embedded. As far as I know, the only langauge services that support contained languages are C# & VB. I added an adapter layer to make these languages work as well (thanks to Jason Malinowski for spending lots of time getting this to work). If you have a different language that implements IVsContainedLanguageFactory, get in touch with me & I’ll add support.

To specify the language, use either the name of the ContentType or any extension (without the .) recognized by Visual Studio. If there are other names that should be recognized, send a pull request to add them to the map in ContentTypeExtensions.ContentTypeAliases.

Known Issues

What's Next

So far, all I’ve done is provide the foundation for a modern Markdown editing experience. There are lots of other features that would make the Markdown editor more complete. If you would like to work on to any of these features, tweet me and I’ll give you advice.

Categories: visual-studio-2013, web-essentials, markdown Tweet this post

comments powered by Disqus