Emacs - Elixir Setup Configuration Wiki

spacemacs
wiki
emacs
code-editors
language-server-protocol

#1

This post is a wiki (feel free to hit the edit button near the bottom right of this post to add your own changes!)

This post collects concrete information about configuring Emacs to be an Elixir editing environment.

Related posts/info:

Overview

  • Alchemist - Very full featured but development has stalled, not currently recommended
  • elixir-mode - Provides the basic font-locking, indentation and navigation support
    • Should be used as the baseline of support
  • Elixir Language Server backend
    • elixir-ls - Original Elixir LSP server implementation, development has currently stalled in Oct. 2018
    • elixir-ls elixir-lsp fork - Fork of @JakeBecker’s elixir-ls that is currently (as of Jan. 2019) being actively developed
  • Language Server Emacs Frontend (choose 1)
    • lsp-mode - General LSP (Language Server Protocol) mode, use it together with a language server implementation
    • eglot - an Emacs LSP client that stays out of your way
  • exunit.el - Simple test runner for ex_unit tests

Configuration Examples/Instructions

Installing elixir language server

Note: Elixir 1.6.6 (compiled on otp 20) and Erlang 20.2.4 are recommended. If you use asdf, then this will be taken care of for you with a asdf install.

  • Clone the elixir-lsp elixir-ls fork locally
    • git clone https://github.com/elixir-lsp/elixir-ls.git
  • cd elixir-ls (that you just cloned)
  • mix deps.get
  • mix elixir_ls.release

This will create a release/language_server.sh (and .bat for windows) file that you will need for the Emacs integration, so note down this path (referred to later as path-to-elixir-ls/release).

eglot Configuration

(package-install 'eglot)
(add-to-list 'eglot-server-programs (elixir-mode "path-to-elixir-ls/release"))

Note: if you’re using spacemacs you’ll probably want to disable alchemist.el with dotspacemacs-excluded-packages '(alchemist)

And then type M-x eglot in any elixir file.

(You may also want to view this alternative configuration example which used to be recommended here)

lsp-mode Configuration

With spacemacs:

Add lsp to your dotspacemacs-configuration-layers

Add alchemist to your excluded package list dotspacemacs-excluded-packages '(alchemist) so that it is not loaded (since we’re using lsp-mode instead)

With vanilla emacs:

  • Add lsp-mode via MELPA
    • M-x package-install [RET] lsp-mode [RET]
  (use-package lsp-mode
    :commands lsp
    :ensure t
    :diminish lsp-mode
    :hook
    (elixir-mode . lsp)
    :init
    (add-to-list 'exec-path "path-to-elixir-ls/release"))

Verify that it is working by opening up a file in an elixir project (you should receive a prompt like mix.exs is not part of any project. Select action:. To which you probably want to respond Import project root. Then if there are no errors you can run M-x lsp-describe-session which will show you all of your lsp server sessions. On this screen you can press RET on the "diamond’ icon next to Capabilities to see the detected capabilities of the server.

Note: there is also https://github.com/Trevoke/lsp-elixir.el that will manage the elixir-ls installation for you, but by installing it manually (as above) you can more easily contribute to elixir-ls.

Note: if you already have lsp-mode installed make sure it is up-to date (version 5.0 had many breaking changes)

Optionally enable DAP (Debug Adapter Protocol) (requires installing dap-mode from MELPA):

(require 'dap-elixir)
(dap-ui-mode)
(dap-mode)

exunit.el configuration

Note: this is recommended because the LSP protocol does not currently include running tests (so this is a good supplement to lsp-mode and eglot)

Install by cloning locally:

Add this to your emacs configuration:

  (add-to-list 'load-path "~/path_to_exunit.el")
  (require 'exunit)

Or Install via melpa:

M-x package-install [RET] exunit [RET]

Optional key binding examples with Spacemacs:

  (with-eval-after-load 'elixir-mode
    (spacemacs/declare-prefix-for-mode 'elixir-mode
      "mt" "tests" "testing related functionality")
    (spacemacs/set-leader-keys-for-major-mode 'elixir-mode
      "tb" 'exunit-verify-all
      "ta" 'exunit-verify
      "tk" 'exunit-rerun
      "tt" 'exunit-verify-single))

Emacs lsp-mode (language server) + elixir-ls anyone?
How to get code completion in IEx programmatically?
#2

exunit is available in melpa, so it could be installed via package-install


#3

Thanks for putting this together! Is it recommended for Spacemacs users to add dotspacemacs-excluded-packages '(alchemist) ?

I know there was also an attempt to update Alchemist to use elixir-ls, maybe the alternative is to add an option to the spacemacs layer that would implement most of this.


#4

Thanks! I’ve updated the instructions to include that.


#5

Your welcome! Yes it is (at least IMO), and I realized that I forgot that portion of the required configuration. Adding it to the wiki now.

There were actually two attempts by @trevoke:

But they ultimately became stale and were never merged into alchemist.el (hence not being recommended in this wiki).

It is a good idea to update the spacemacs +lang/elixir layer to switch from alchemist to a properly configured lsp-mode (which had completely slipped my mind until you mentioned it). I would assume it’s okay for +lang/elixir to depend on the lsp layer but we’ll have to see if that flies with the spacemacs team.


#6

I’m Eglot’s author. I stumbled upon this. Just wanted to say here that it is nonsense to call the section “Eglot configuration”, because Eglot is a completely different LSP client for Emacs. It’s setup is also much simpler, it’s probably just

(package-install 'eglot)
(add-to-list 'eglot-server-programs (elixir-mode "path-to-exilir-ls-executable"))

And then type M-x eglot in any elixir file.


#7

Welcome to the forum and thanks for contributing :slight_smile:. I have restructured the sections to make it more obvious that you should use either Eglot or lsp-mode since they provide the same functionality. Looks like I initially missed eglot in the overview section as well (which I have now rectified).

Thanks! That is much simpler, so I’ve updated the instructions to that. Since I haven’t tried using eglot I just copied the configuration instructions from this other forum post which links to this gist (which it looks like you found already :smile:).


#8

@axelson lsp-mode also have debugger support for Elixir via dap-mode. The configuration is simple as the configuration of lsp-mode:

Install dap-mode and then:

(require 'dap-elixir)
(dap-ui-mode)
(dap-mode)


#9

Thanks! Added! And welcome to the forum as well :slight_smile:


#10

Hello, instructions regarding eglot half-worked for me. With OTP 21 elixir_ls server crashes, looks like it’s required OTP 20. I recompiled it and now eglot connected to the language_server (ran from release/language_server.sh (not dist folder)

EDIT: I also created the release with MIX_ENV=prod mix elixir_ls.release – not sure if that helps :slight_smile:


#11

Thanks! I committed an asdf .tool-versions file and added elixir and erlang versions to the readme. I’m using 1.6.6 with erlang 20.2.4. Updated the instructions (changed dist to release as well).