ElixirLS is the Elixir Language Server that provides IDE features like autocomplete, diagnostics, go-to-definition, and Dialyzer integration. This guide covers setting it up in Vim using coc.nvim.
Prerequisites
- Vim or Neovim with coc.nvim installed
- Elixir and Erlang installed (ideally managed via asdf)
Step 1: Install ElixirLS
Clone and build ElixirLS:
git clone https://github.com/elixir-lsp/elixir-ls.git ~/.elixir-ls
cd ~/.elixir-ls
mix deps.get
MIX_ENV=prod mix compile
MIX_ENV=prod mix elixir_ls.release2 -o release
The last command builds the executable language server to ~/.elixir-ls/release/, and that is the path we need to use in the coc.nvim configuration.
Step 2: Configure coc.nvim
Open your coc settings in Vim with :CocConfig and add:
{
"elixir.pathToElixirLS": "~/.elixir-ls/release/language_server.sh"
}
Step 3: Install coc-elixir
In Vim, run:
:CocInstall coc-elixir
This installs the coc.nvim extension that communicates with ElixirLS.
Step 4: Verify
Open an Elixir file in your project. You should see:
- Autocomplete suggestions
- Inline diagnostics and warnings
- Go-to-definition working (
:call CocAction('jumpDefinition'))
Understanding the .elixir_ls Directory
When you first open an Elixir project, ElixirLS creates a .elixir_ls/ directory and compiles your project. You might wonder why it doesn’t just use _build/.
ElixirLS maintains its own build for several reasons:
-
Avoids conflicts - Your
_build/uses your development environment. ElixirLS compiles separately so runningmix testdoesn’t invalidate the language server’s build. -
Different compile options - ElixirLS uses flags that capture additional metadata for IDE features. These would slow down normal development builds.
-
Dialyzer PLT files - ElixirLS caches Dialyzer’s Persistent Lookup Table here. Building PLTs is slow, so caching them per-project saves time.
-
Independence - If your
_build/breaks, ElixirLS keeps working.
Consider adding .elixir_ls/ to your global gitignore:
echo ".elixir_ls/" >> ~/.gitignore_global
git config --global core.excludesfile ~/.gitignore_global
Troubleshooting
If ElixirLS behaves unexpectedly, the simplest fix is to delete its cache and restart:
rm -rf .elixir_ls/
Then in Vim:
:CocRestart
ElixirLS automatically recreates the directory and recompiles when it restarts.
Common reasons to clear the cache:
- Upgraded Elixir or Erlang versions
- Dialyzer giving stale warnings
- Language server stuck or unresponsive
- Dependency changes not being picked up
Leave a comment