YANG-Tools: One Language Server for Four IDEs
There is a lot of hype around the Language Server Protocol: It allows language implementors to encapsulate the editor support for their language in a server that can talk to various clients through a JSON-based protocol. While initially designed for Visual Studio Code, lots of other editor clients started supporting it, and lots of language servers for all kind of languages have emerged. In this post we will showcase a single language server for the YANG language, implemented with Xtext, that is attached to three different client frameworks: VSCode, the Theia IDE and Eclipse. As Theia allows for both, a browser-based IDE and an Electron-based rich-client, this yields four different kinds of IDEs. All sources are openly available on Github.
The YANG Language Server
YANG is a data modeling language used to model configuration and state data manipulated by the NETCONF protocol, remote procedure calls, and notifications. In the project yang-lsp we implemented a YANG language server using Xtext. As Christian pointed out in a previous blogpost, Xtext can generate an LSP with little effort. Like almost every language, YANG has some pecularites that required to customize services like validation, scoping, and formatting. To improve the user experience, we also tweaked some language server IDE services such as content assist, code lens, symbols and more. Xtext’s dependency injection makes such customizations easy. Nevertheless, the extra effort is something you would like to avoid redoing for every IDE out there using the respective native APIs. The YANG language server is written in Xtend, a Java dialect, so you have to run Gradle to build it. A language server is typically run in its own process, so this build also creates some scripts to start the LS. The running server is then connected to the client via standard input/output or a socket.
The VSCode Client
VSCode is an extensible, lightweight, open source IDE from Microsoft. In yang-vscode, we implemented an extension for VSCode based on yang-lsp. It mostly consists of
- an activate method that starts the language server,
- the configuration for things like syntax highlighting and bracket matching, which in VSCode are always done by the client, and
- the config files for a VSCode extension.
See also Miro’s blogpost on VSCode extensions with Xtext for more details. You can install the yang extension directly from VSCode’s marketplace. If you want to build it from the sources, you have to have the yang-lsp project checked out and readily built in a folder next to the yang-vscode repo, as it will be copied during the build.
The Theia Client
Theia is a new framework for IDEs that run in the browser or as rich-clients using the same code. It is written in TypeScript, has first class support for the LSP and uses Microsoft’s editor widget Monaco. Theia is not officially released yet, but a beta 1.0 is scheduled for December 2017. The project yangster contains the Theia extension for the YANG language. The project is layouted as a mono-repo, containing various npm packages and linking in others as Git submodules. While this setup looks complicated at the first glance, it makes it possible to work on YANG, Theia, and sprotty at the same time. The yang-lsp will be copied from our Jenkins during build. The core package is the theia-yang-extension: It adds the bindings for the YANG specific services to Theia’s DI container, registers context menus, and sets up syntax highlighting for the frontend. It also starts the language server on demand in the backend. The packages yangster-app and yangster-app-electron contain the code to run Theia with the YANG extension as browser app or electron rich-client. Theia comes with a command line tool that will populate these packages with generated code during the build.
The Eclipse Client
Last but not least, we’ve integrated the yang-lsp into Eclipse. We are using the lsp4e here, which allows a generic Eclipse editor to be backed by a language server. The easiest way to install it is from the Eclipse Marketplace. The project yang-eclipse mainly contains a plug-in to adapt to lsp4e, i.e.
- start the yang-lsp,
- define syntax highlighting using TextMate syntax, and
- add some nice icons.
Note that event though the client is also written in Xtend/Java here, we start the language server using the same mechanisms as above in a separate process.
Xtext can of course generate a native Eclipse editor as well, which would usually have a few more features and a slightly better user experience. We refrained from this approach this time, not only for the sake of demoing an LSP in Eclipse, but also because we would have had to reimplement some IDE features using the native Eclipse APIs and as such have twice as much code to maintain.
And Where Do The Diagrams Come From?
If you have watched the screenshots closely or if you have browsed the code, you may have stumbled across the fancy diagrams. To keep the suspense, we will cover that in a separate blogpost.
In the post you have seen how a single language server implemented in Xtext is adding support for the YANG language to four different IDEs. Only little IDE specific boilerplate is necessary, mainly to start the server and to implement services that are considered client-only by the LSP, like syntax highlighting. We stopped at four IDEs, but there are also LSP bindings for sublime, Emacs, vim and more editors. It should be easy to serve these in the same way. I hope I convinced you that the combination of Xtext with the LSP is a viable way to add language support to more than one IDE.