[erlang_ls] The origin

Roberto Aloi
About Erlang
Published in
4 min readAug 2, 2018
The Creation of Adam — Michelangelo

I am an Erlang developer and an affectionate Emacs user. For most of my professional career I have been using Emacs’s erlang-mode and, once available, the EDTS suite, whose author is a former colleague. These two tools, combined with a few extra customizations and additions, provided me with a decent development environment for Erlang. I felt quick and productive when writing and navigating Erlang code and I never really missed a more powerful IDE.

I occasionally experienced a few bugs with these tools and identified a few potential improvements, but nothing major that would trigger the quest for a better alternative. At some point I started consulting for a company which used comma-first indentation and Emacs’ automatic indentation started to break here and there. I started switching heavily between projects using different versions of the Erlang Runtime system and EDTS, even if in theory supported multiple OTP runtimes, occasionally started to crash and spam my EDTS buffer with error messages related to xref, the Erlang cross-reference tool. Reverting Emacs buffers, killing and restarting the EDTS process, became normal part of my developer workflow. After a recent upgrade, EDTS started to perform poorly. It would get occasionally stuck and I had to press C-g a few times to recover control of my Emacs. When working on huge projects (in terms of lines of code), EDTS was freezing my entire Emacs every time I was navigating into a newly-opened module.

It was 2018 when I contacted EDTS’ author to ask if I was the only one experiencing these issues. Some of these problems were apparently known, but not easily reproducible. Also, Thomas (EDTS’s author) was not using Erlang anymore, so he had very little incentive in improving or even maintaining EDTS. I shivered for a second, since I was relying so much on EDTS. It was at that point that Thomas asked me if I was interested in contributing to EDTS or even becoming a maintainer for it.

I started diving into the EDTS code-base and learnt about its architecture. It was surprisingly interesting. At start-up, EDTS would spin up a distributed Erlang node (named edts) and then a separate Erlang node for each project. The two Erlang nodes would communicate between each other using the standard Erlang Distribution Protocol. The edts node exposed an HTTP API that the Emacs client interacted with. This setup allowed (with some limitations) different versions of the Erlang runtime for different projects. The approach had a lot of potential. One could implement a lot of interesting features in an easy way by using the standard Erlang libraries. In principle, if one could make the HTTP API generic enough and not Emacs-specific, other editors could have leveraged these libraries. This would have been particularly beneficial in a small community like the Erlang one. Just think about it: a bug fix to the way return values for a spec are indented would automatically be available to users of all major text editors and IDEs. Unfortunately, the client part in EDTS was still quite heavy and a lot of functionalities (e.g. auto-completion) were too coupled with Emacs and implemented directly in Emacs Lisp. My interest, though, was growing.

A couple of weeks later I attended the Code Beam conference in Stockholm. I was sharing my ideas with a few attendees when Csaba (co-author of vim-erlang) told me that Vlad (co-author of the erlide Eclipse plugin) was working on a similar project. It was time for me to attend Vlad’s talk.

At Vlad’s talk I learnt that the idea of having a well defined API between text editors (or IDEs) on one side and language-specific servers on the other one was not so new. It was not surprising to see that the driver for such an approach was Microsoft, which obviously faced the problem of supporting multiple programming languages (e.g.. C, C++, C#, F#, TypeScript) in a common IDE (i.e. Visual Studio). What was surprising (at least for me) was that Microsoft actually defined and open-sourced a fully-bledged Language Server Protocol (aka LSP) to solve the problem, and that all major text editors and IDEs (including Emacs \o/) already implemented a client for it.

I started looking for implementations of Language Servers for Erlang and found a few ones (including one for Elixir), all at different development stages and using different approaches (a separate blog post will cover this aspect).

It was time to roll my own.

You can find the erlang_ls repo here. This very same blog post is part of its README.

--

--