DEV Community

Josiah
Josiah

Posted on

Integrating Scala Metals with Doom Emacs using LSP on Pop!_OS/Ubuntu 20.04 LTS

Why Yet Another HowTo For Integrating Metals with Doom Emacs???

A quick web-search will quickly reveal that there's at least two blog posts on this already (the ones I found were from 2019 and 2020). So... why am I creating another one? Believe it or not, despite the fact that both of these blog posts were incredibly useful in helping me to get up and running with Metals as the language server backend for Scala development in Doom Emacs, I did not find that either article covered everything necessary for me to be able to get things set-up properly on my machine without doing a fair amount of my own troubleshooting. In an attempt to save some people from some of the frustration I've had to go through I, therefore, decided to write this blog post in an attempt to fill in some more of the gaps.

For sections that I believe many of you may want to skip, I'll leave you a nice TLDR notification at the beginning indicating what the section contains and why some of you readers may not care to read it.

A Few Notes About this Article's Scope

(TLDR: this is mostly disclaimers. Please skip it if you don't care)

  • I only run Ubuntu 20.04 based Linux distros, currently. As such, this post only covers material that pertains to getting Metals integrated with Doom Emacs through the LSP on Ubuntu.
  • To help avoid needing to mess with the differences between different flavors and derivatives of Ubuntu 20.04, everything in this article will be done through the CLI. This is because the CLI is relatively consistent across Ubuntu-based distros when compared to the GUI desktop enviornments which could be anything from vanilla XFCE, Gnome, KDE, Maté, etc. to some customized version of any of those (for example, Pop!_OS ships with a fairly customized version of Gnome).
  • I will be covering my experience in getting this working, only. I have not done, nor do I plan to do, the leg-work necessary to tinker around and try to find all the things that could go wrong in Ubuntu 20.04 when trying to configure Doom Emacs to use Metals as the LSP backend.
  • For those of you that use Chemacs, you may be interested to know I use Chemacs 2 to switch between Doom Emacs, Spacemacs, and vanilla Emacs. As such, the instructions in this article will work even if you installed Doom Emacs to its own directory and not straight into the ~/.emacs.d/ directory.
  • I will be using this article for my own reference. Therefore, I will most likely be keeping it up-to-date according to what I need to work effectively as a Scala developer so long as I'm working regularly in Scala and still using Doom Emacs as my primary editor for Scala development. However, I make no promises or commitments to keep this article up-to-date in any case. I reserve the right to neglect updating this article, switch to another editor (like Vim or VSCode), stop working on Scala for a while, etc. without notice.

Installing Metals

I installed Metals using Coursier via the following process:

  1. You will need a JDK for this to work (hopefully you don't find this to be unexpected since Scala is a JVM language, so one would rightly expect Metals and potentially even Coursier to be using a JDK in its analysis of Scala files). I installed Open JDK 11 and then followed the instructions here to set the JAVA_HOME environment variable. However, so that this article can stand on its own, I'll copy the stepwise instructions from the aforementioned article below (Note that these instructions are for Ubuntu, you may need to do your own digging to figure out how to do this for a different Linux distribution if that's your need).
    1. In a terminal window, run sudo su.
    2. Run updatedb to update your system's database
    3. Run locate openjdk to find your Java installation. It's a bit of an art parsing through the wall of text this command outputs, but the instructions on the WikiHow site served me well - look at what base directory/prefix most of the outputs return, and use the majority output. For me, that was /usr/lib/jvm/java-11-openjdk-amd64.
    4. To permanently set $JAVA_HOME to this, add the line JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64 (or whatever your installation path was) to /etc/environment. If you don't have root access on your machine, you may alternatively add this to your shell's RC file (for example, ~/.bashrc).
    5. After this, you may log out of your session and back in again, or alternatively sourcing your shell's RC file would work if you took that approach in hte previous step (e.g. source ~/.bashrc).
  2. Install Coursier I found I had to follow the official site instructions to install Coursier and ignore what Siaw Young's article told me to do entirely.

    # first, let's check where this redirects to
    curl -sI https://git.io/coursier-cli-"$(uname | tr LD ld)" | grep Location
    # Should return something like "Location: https://github.com/coursier/launchers/raw/master/cs-x86_64-pc-linux"
    
    # Assuming all is good, proceed with the install
    curl -fLo cs https://git.io/coursier-cli-"$(uname | tr LD ld)"
    chmod +x cs
    ./cs install cs
    rm cs
    
  3. Next, you'll want to use Coursier to install Metals. I used the following command to perform the installation:

    sudo cs bootstrap \
    --java-opt -Xss4m \
    --java-opt -Xms100m \
    --java-opt -Dmetals.client=emacs \
    org.scalameta:metals_2.12:0.10.1 \
    -r bintray:scalacenter/releases \
    -r sonatype:snapshots \
    -o /usr/local/bin/metals-emacs -f -v -v -v
    
  • The 2020 article indicates that there used to be a bug which made it more difficult or impossible to install Metals via the Coursier CLI launcher for Linux. This issue seems to have been fixed by the community, I did not run into the problem Siaw Young did.

Installing/Updating Doom Emacs

  1. Of course, make sure you have a recent version of Emacs installed. I'm using Emacs version 28.0.50 on Pop!_OS 20.04 LTS, which is based on Ubuntu 20.04 LTS.
  2. From here, I have installed Chemacs 2 to my ~/.emacs.d directory as instructed in the Chemacs 2 README.
  3. Next, I cloned Doom Emacs into ~/.doom.emacs.d using the install instructions in the README

    1. NOTE: Actually, when I started this process of integratiing Metals with Doom Emacs, I had already had Doom Emacs and Chemacs 2 installed as described above and I found myself in need of actually updating Doom Emacs. When I tried doom upgrade however as specified in the README, I kept running into errors such as this one. As it turned out, I was able to fix the problem by running the following git commands to force a fresh pull from the Doom Emacs remote:

      git fetch
      git reset --hard origin/develop
      ./bin/doom install
      

      YMMV, and you may find that you may need to wipe your ~/.doom.emacs.d directory and do a fresh clone of the Doom Emacs git branch or tag into that directory depending how how messy or divergent your setup has become over time.

  4. You can then tell Chemacs 2 to switch between the Doom and vanilla Emacs versions by adding the following to your ~/.emacs-profiles.el

    (("default" . ((user-emacs-directory . "~/.emacs.d")))
     ("doom" . ((user-emacs-directory . "~/.doom.emacs.d")))
    )
    

Configuring Doom Emacs (a.k.a. the easy part)

  1. Finally, you'll want to configure Doom to use lsp. This was actually fairly straightforward. You can do this by opening ~/.doom.d/init.el (this file was created by doom install, earlier) and in the (doom! :input section/scope add lsp and (scala +lsp) to the list of plugins, there.
  2. Go back to ~/.doom.d/bin/ and run ./doom sync to make sure the new layers your configured in the previous step get downloaded and installed.
  3. Restart Doom Emacs and you should be good to go for having Doom Emacs use Metals as the LSP backend for analyzing Scala code.

Closing Remarks

All in all, I did not find the installation and configuration of Doom Emacs to use Metals as the LSP backend for Scala too difficult, but there were some gotchas that made it a bit less straightforward than just installing the Metals application and editing the Doom config files to use it. I hope by posting this article, here, somebody else's time can be saved and their life can be made just a bit easier by having this small instructional article, here.

If you benefited from this article, please give it a clap, or vote, or thumbs-up depending on the platform you encounter this on.


This article is replicated by me on Steemit, Medium, and write.as as well, for the sake of redundancy.

Top comments (1)

Collapse
 
frgomes profile image
Richard Gomes

Beware that Metals requires Java17 at the the time of this writing here.
It means that Metals will crash at start if you are using Java 8 or Java11.
You have to install Java17 or greater.

However, if you have projects which depend on Java8 or Java11, like code
based on Spark for example, you need to tell Metals (which is running on Java17)
that projects must be compiled under some other version of the JDK.

More information here:
github.com/scalameta/metals/issues...