Navigating Elixir Standard Library in Emacs
Short answer : Compile Elixir yourself
Long answer :
Many times I find myself exploring Elixir source code in a separate frame. Either to learn how something is implemented or to know how something is used. What is a better reference to learn a language than the language source itself?
I'm using elixir-ls language server with Eglot as LSP
front-end. elixir-ls internally use elixir-sense to get relevant
information from source. A quick look at elixir-sense revealed that
every module has source
metadata attached to it. This metadata points
to the source file from which beam file is generated. Since its done
by Erlang, both Erlang and Elixir modules have this information as
metadata. You can check this in iex
.
iex(3)> Enum.module_info(:compile)
[
version: '7.2.6',
options: [],
source: '/private/tmp/elixir-20181026-69137-ms45yr/elixir-1.7.4/lib/elixir/lib/enum.ex'
]
Since brew by default installs pre-built binaries. The source
path is
invalid in my machine. So to have correct source
, we just have to
compile it locally.
It's fairly easy to compile with asdf
Install asdf
Follow the instructs at asdf
Install correct erlang/OTP plugin
Note that each version of elixir supports a specific version of
erlang/OTP version, make sure you install the correct version.
I wanted to use elixir 1.7.4
, I installed Erlang/OTP 21.2
. Check asdf-erlang.
Install elixir with ref tag
asdf-elixir installs pre-built binaries if you just use version tags.
you need to use ref:<commit_sha>
for compiling from source. see
releases to find the commit id for a particular release. Check
asdf-elixir.
In my case, it will be
asdf plugin-add elixir
asdf plugin-add erlang
asdf install erlang 21.2
asdf global erlang 21.2
asdf install elixir ref:eb5679b
asdf global elixir ref:eb5679b
Now source
should point to correct local path for both Elixir and Erlang modules
iex(2)> Enum.module_info(:compile)[:source]
'/Users/akash/.asdf/installs/elixir/ref-eb5679b/lib/elixir/lib/enum.ex'
iex(3)> :ets.module_info(:compile)[:source]
'/Users/akash/.asdf/plugins/erlang/kerl-home/builds/asdf_21.2/otp_src_21.2/lib/stdlib/src/ets.erl'
With this source code navigation works as expected in the Emacs
Bonus Tip
Mostly likely that you don't want to modify any of the elixir/Erlang
source files. You can use M-x projectile-toggle-project-read-only
to
always open these files with read-only mode.