While the standard ElixirLS installation works well for most developers, running it from source provides access to the latest features and improvements. Recently, after discussing this setup with a colleague, I realized others might benefit from learning how to implement this configuration.
Before proceeding, ensure you have Erlang and Elixir installed on your system. While I personally use Mise for version management, asdf works as well.
Begin by cloning the ElixirLS repository and installing its dependencies:
git clone [email protected]:elixir-lsp/elixir-ls.git
cd elixir-ls
mix deps.get
Next, compile and install ElixirLS. I recommend storing it in ~/.local/share
for better organization. The installation commands vary slightly depending on your shell:
For Fish shell users:
env MIX_ENV=prod mix compile
env MIX_ENV=prod mix elixir_ls.release2 -o ~/.local/share/elixir-ls
For Bash or ZSH users:
MIX_ENV=prod mix compile
MIX_ENV=prod mix elixir_ls.release2 -o ~/.local/share/elixir-ls
Editor Configuration
After installation, the executables will be available in ~/.local/share/elixir-ls
. You’ll need to configure your editor to use this installation.
For Zed, add the following to your configuration:
"lsp": {
"elixir-ls": {
"binary": {
"path": "/Users/<you>/.local/share/elixir-ls/language_server.sh"
}
}
}
- Neovim users can reference my configuration on GitHub.
- VSCode users should update the
elixirLS.languageServerOverridePath
setting.
To maintain the latest version of ElixirLS, simply pull the latest changes from the repository and recompile:
cd elixir-ls
git pull
MIX_ENV=prod mix compile
MIX_ENV=prod mix elixir_ls.release -o ~/.local/share/elixir-ls
This setup ensures you always have access to the most recent ElixirLS features and improvements while maintaining a clean, organized development environment.
In my previous note Shorter feedback loops with Elixir tests I already described how to run tests in Elixir, where it only runs the failed tests. Below is what I put in my mix.exs
file to have faster feedback loops when testing:
defp aliases do
[
...
"test.failed": ["test --failed --max-failures 1"],
]
end
# Make sure the alias runs in the test MIX_ENV environment.
def cli do
[preferred_envs: ["test.failed": :test]]
end
This will create a new alias test.failed
that will run only the failed tests and stop after the first failure. This is useful when you are working on a specific test and you want to run it quickly without running all the tests.
For an exercism exercise I wanted to do multiplication with the pipe operator, and simply using *
does not work, neither does (*)
.
Now, it turns out the arithmetic operations are functions part of the Kernel
module, and you can also call them as an actual function with Kernel.*(2, 2)
, which is equal to writing 2 * 2
.
This enables you do do arithmetic as part of the pipe operation, see:
def monthly_rate(hourly_rate, discount) do
hourly_rate
|> daily_rate
|> apply_discount(discount)
|> Kernel.*(22)
|> ceil()
end
In Ruby, you have the --fail-fast
flag, which stops running the test suite at the first failed test. Convenient to get shorter feedback loops, with a long running test suite.
In Elixir, you can achieve the same with:
mix test --max-failures 1
And then when a test fails, you fix it, and make sure that it works with:
mix test --failed
That makes for shorter feedback loops!
The following is what I use to setup Elixir on my machines, where I want to make sure that I can jump to all definitions of Elixir library functions.
First, I install asdf. I go the Homebrew and Fish route, but you can also do it from the source and use your shell of choice.
Before I install Erlang, I make sure to set the right flags, because I don’t want Java or build any GUI stuff:
KERL_BUILD_DOCS="yes"
KERL_CONFIGURE_OPTIONS="--disable-debug --without-javac --without-wx"
After that, I go to the asdf-erlang repository, check that I have all the build requirements and install Erlang with:
asdf plugin add erlang https://github.com/asdf-vm/asdf-erlang.git
# check available Erlang versions
asdf list all erlang
# install the latest version
asdf install erlang 26.2.4
# enable it globally
asdf global erlang 26.2.4
Now, let’s install Elixir. Go to the asdf-elixir repository, make sure you have unzip installed, and do the following.
asdf plugin-add elixir https://github.com/asdf-vm/asdf-elixir.git
# check all available versions
asdf list all elixir
# install the latest version, but! Install by source, so we can jump to the definition of Elixir functions
asdf install elixir ref:v1.16.2
# enable elixir globally
asdf global elixir ref:v1.16.2
Now, it says it in the comments, but the important difference is that I install Elixir by reference instead of the pre-compiled versions because I also like to be able to jump to definitions of Elixir library functions.