Graphical VS Code Extensions with Eclipse Sprotty
This post explains how to use Eclipse Sprotty to build VS Code extensions with diagrams.
Eclipse Sprotty is a web-based, open-source diagram framework that integrates nicely with the Language Server Protocol (LSP). In a prior post, we've shown you how to use Sprotty to add live diagrams to an Xtext-LSP-based domain-specific language in Eclipse Theia. Now we will re-use the same language server (LS) and Sprotty diagram to build a VS Code extension.
VS Code Extensions
Visual Studio Code provides an API for extensions. Extensions are separately installable plug-ins that add support for new languages, color themes, views and more. By the time of writing this article, the official marketplace already counted more than 15000 freely available VS Code extensions.
The LSP is part of this extension API. To add a new language to VS Code, you usually implement a language server. Then you wrap the LS in an extension that spawns it and connects it to the IDE. In addition, the extension can add stuff beyond the LSP, such as syntax highlighting, menu items, keybindings or code snippets.
By the way, Theia, the open-source framework for web-based IDEs, understands VS Code extensions directly. So you can run this example in Gitpod or other Theia-based IDEs, too.
If a VS Code extension wants to provide UI beyond the standard functionality it uses a webview. In the UI, a webview takes the same space as an editor, but it's free to render whatever it wants, e.g. a Sprotty diagram.
Wiring It Up
So to add support for a domain-specific language with Sprotty diagrams you need three components
- the language server,
- the webview and
- the extension.
The language server provides all the language intellisense (validation, content assist, etc) to VS Code's code editor via the LSP. We just re-use the Xtext-based LS from the Theia example that we enhanced to serve diagrams to a Sprotty client.
The webview contains the Sprotty client, i.e. it runs the rendering loop, creates the SVG for the webview's iframe, processes the user events. For all semantic operations, it exchanges Sprotty
Actions with the extension. We will re-use the Sprotty client code from the Theia example.
The extension connects to VS Code. It starts, connects, disconnects and stops the language server as demanded by the IDE. It adds syntax highlighting, code snippets etc., and a menu item to show a DSL model as a diagram. When the menu action is triggered, the extension creates a new webview and connects it to the language server. So the extension manages the lifecycles of the LS and the webviews, and relays messages between the IDE and the LS (LSP), and between the webviews and the LS (Sprotty
The code for this example can be found on GitHub.
To try it out, you can just open the repo in Gitpod. It has the VS Code extension already installed, so you can just open
example/workspace/MrsGrantsSecretCompartment.sm and choose Open in Diagram from the editor's context menu. The diagram is auto-layouted, updated as you edit the model, the selection is synchronized, etc.
In VS Code, you can install it from the marketplace: Go to View > Extensions, search for State Example and install it. An example DSL model can be found here.
Build Your Own
The repository sprotty-vscode provides some base-classes that do most of the wiring and initialization protocols as well as the management of the webviews. It works for scenarios with and without language servers. Some things like packaging the various components with debuggable source code are a bit tricky, but you can use the example to guide you while setting things up correctly. The code will be moved to Eclipse as a subcomponent of Sprotty as soon as it has passed IP review.
Graphical editing support like in the Theia example is not covered for VS Code extensions yet, but it shouldn't be a lot of effort to add it.