This post describes the prerequisites to get my Emacs config to work
with Scala, sbt
, Metals and lsp-mode
on macOS.
On Mac we need Java 8 for Metals (see SO):
brew tap adoptopenjdk/openjdk
brew cask install adoptopenjdk8
brew cask info adoptopenjdk/openjdk/adoptopenjdk8
Install coursier
:
brew install coursier/formulas/coursier
Coming from Python, coursier
seems pretty nice and well thought
out. coursier bootstrap
seems to be similar to pipx
, pipsi
or shiv
-
creating a small jar
file that fetches dependencies on first run.
coursier is a dependency resolver / fetcher à la Maven / Ivy, entirely rewritten from scratch in Scala. It aims at being fast and easy to embed in other contexts. Its core embraces functional programming principles.
It handles many features of the Maven model, and is able to fetch metadata and artifacts from both Maven and Ivy repositories. It handles parallel downloads out-of-the-box without resorting to global locks.
We can also tell sbt
to use coursier
for fetching dependencies.
Anyway, let’s install scalafmt
using coursier bootstrap
:
coursier bootstrap org.scalameta:scalafmt-cli_2.12:2.2.2 \
-r sonatype:snapshots \
-o /usr/local/bin/scalafmt --standalone --main org.scalafmt.cli.Cli
You might consider changing -o
- -o ~/bin/scalafmt
would be a safe
bet.
I use reformatter.el to easily run scalafmt
on every save:
(use-package reformatter
:config (reformatter-define scalafmt :program "scalafmt" :args '("--stdin")))
This creates the functions scalafmt-buffer
and scalafmt-on-save-mode
among others. So I set it up with a hook:
(use-package scala-mode
:mode "\\.s\\(cala\\|bt\\)$"
:gfhook '(scalafmt-on-save-mode))
See my Emacs config for more details.
Now run a even stranger coursier
command to install metals-emacs
(the
Language Server Protocol server):
coursier bootstrap \
--java-opt -Xss4m \
--java-opt -Xms100m \
--java-opt -Dmetals.client=emacs \
org.scalameta:metals_2.12:0.7.6 \
-r bintray:scalacenter/releases \
-r sonatype:snapshots \
-o /usr/local/bin/metals-emacs
You might want to consider changing -o
- maybe -o ~/bin/metals-emacs
.
Now, lsp-mode
knows how to look for metals-emacs
as long as its in
your PATH
.
Before trying Emacs, I tested with VS Code and noticed it complained
about not being able to find Java 8. So I figured it will probably
also fail with lsp-mode
. I found the lsp-metals-java-home
variable and
set it as such:
(setq lsp-metals-java-home "/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home")
I don’t know how to know about that folder, I just came across it
while searching the web. Later I have learnt that you can run
/usr/libexec/java_home -V
to see all your Java homes. This tool is
included in macOS.
Confusion settles.