ElixirLS - the Elixir Language Server

I pushed a couple of patches; hope they’re useful to you. I was hoping to find test suites that I could inspect to find out about the API, but I can’t find any. Help?

-r

Ahh, yeah, I have the ref: stuff because I install elixir from source so that ElixirLS can find the Elixir source code.

I’m not sure what do you mean with the API. The only public api ElixirLS implements are https://microsoft.github.io/language-server-protocol/specifications/lsp/3.18 and Specification. We do have test coverage for various LSP and DAP API calls - please look for apps/language_server/test/server_test.exs, apps/elixir_ls_debugger/test/debugger_test.exs and all test in the apps/language_server/test/providers subdir

Edit:
I can provide more info on the capabilities of the providers. Let me know what do you need.

1 Like

Thanks for all the links! Looks like I have a lot of reading to do…

On a related note, the Language Server Index Format (LSIF) purports to:

… define a standard format for language servers or other programming tools to dump their knowledge about a workspace

… support rich code navigation in development tools or a Web UI without needing a local copy of the source code

See also: https://lsif.dev/

Is there any plan for ElixirLS to support LSIF?

FWIW, I’d like to create Livebooks that document and demonstrate use of the LSP and DAP APIs from Elixir. I’m hoping that the test code will make a good starting point.

However, I have no clue how to start up the servers, point them at sample file trees, connect up to them, etc. Pointers and suggestions welcome!

Version 0.16.0 has been released :rocket:

Highlights:

  • Added support for rtx version manager.
  • Language server now returns diagnostics in config files for current configuration. Previously when there were compilation errors in config files an error with stacktrace would be returned on mix.exs instead of the config file.
  • Configuration management has been refactored and migrated to pull based approach. This addresses recent problem on VSCode when the server would start with default settings after a restart. Pull based workspace/configuration request has been added in LSP 3.6 and the pull based workspace/didChangeConfiguration with params is deprecated.
  • Language server now uses call arity in definition, implementation, references and hover providers. This means that if there are multiple arity variants, the documentation for correct ones will be presented. In case of incomplete code all variants with arity greater or equal to the number of arguments are considered.

See full release notes

ElixirLS elixir-ls/CHANGELOG.md at v0.16.0 · elixir-lsp/elixir-ls · GitHub
vscode extension vscode-elixir-ls/CHANGELOG.md at v0.16.0 · elixir-lsp/vscode-elixir-ls · GitHub

20 Likes

Version 0.17.0 has been released :rocket:

Highlights:

  • Language Server now emit parser errors and warnings on type in .ex, .exs and .eex files
  • Language Server provides better completions for elixir reserved words. Thanks Kevin Kalb for initial work
  • Debugger now automatically breaks on Kernel.dbg macro. This allows inspecting variables, evaluating expressions and stepping through piped function calls. A setting breakOnDbg defaulting to true can be used to turn off that behaviour
  • Progress reports and cancel support added in debugger. This can be used to terminate long running evaluate requests.
  • Improved rendering of documentation in hover provider
  • Improved support for Unicode identifiers and atoms. Elixir supports Unicode identifiers since v1.5 and now all ElixirLS features should work with them
  • When running a debug session from Test UI in VSCode test result is now passed to the test controller and UI updates accordingly

See full release notes

ElixirLS elixir-ls/CHANGELOG.md at v0.17.0 · elixir-lsp/elixir-ls · GitHub
vscode extension vscode-elixir-ls/CHANGELOG.md at v0.17.0 · elixir-lsp/vscode-elixir-ls · GitHub

16 Likes

Very happy to see the fish shell support! I ran into the lack of that as an issue a few weeks ago and saw that it was due for this release.

I just updated the GIT repo of elixirls and my editor (NeoVim + LunarVim) started failing to start it. So I tried launching it in the terminal and got this:

# cd into the GIT repo directory of ElixirLS first.
$ release/language_server.sh --help

Running /Users/dimi/bin/elixir-ls/release/launch.sh
Preferred shell is zsh, relaunching
Looking for ASDF install
ASDF not found
Looking for rtx executable
rtx executable found in /usr/local/bin/rtx, activating
Installing ElixirLS release v0.17.2
Running in /Users/dimi/bin/elixir-ls
* Updating elixir_ls (https://github.com/elixir-lsp/elixir-ls.git - v0.17.2)
Mix.install failed with ** (Mix.Error) Command "git --git-dir=.git checkout --quiet v0.17.2" failed with reason: error: pathspec 'v0.17.2' did not match any file(s) known to git

    (mix 1.15.7) lib/mix.ex:577: Mix.raise/2
    (mix 1.15.7) lib/mix/scm/git.ex:136: Mix.SCM.Git.checkout/2
    (elixir 1.15.7) lib/file.ex:1624: File.cd!/2
    (mix 1.15.7) lib/mix/dep/fetcher.ex:61: Mix.Dep.Fetcher.do_fetch/3
    (mix 1.15.7) lib/mix/dep/converger.ex:229: Mix.Dep.Converger.all/8
    (mix 1.15.7) lib/mix/dep/converger.ex:162: Mix.Dep.Converger.init_all/8
    (mix 1.15.7) lib/mix/dep/converger.ex:110: Mix.Dep.Converger.all/4
    (mix 1.15.7) lib/mix/dep/converger.ex:89: Mix.Dep.Converger.converge/4

Retrying Mix.install with force: true
Installing ElixirLS release v0.17.2
Running in /Users/dimi/bin/elixir-ls
* Getting elixir_ls (https://github.com/elixir-lsp/elixir-ls.git - v0.17.2)
** (Mix.Error) Command "git --git-dir=.git checkout --quiet v0.17.2" failed with reason: error: pathspec 'v0.17.2' did not match any file(s) known to git

    (mix 1.15.7) lib/mix.ex:577: Mix.raise/2
    (mix 1.15.7) lib/mix/scm/git.ex:136: Mix.SCM.Git.checkout/2
    (elixir 1.15.7) lib/file.ex:1624: File.cd!/2
    (mix 1.15.7) lib/mix/dep/fetcher.ex:64: Mix.Dep.Fetcher.do_fetch/3
    (mix 1.15.7) lib/mix/dep/converger.ex:229: Mix.Dep.Converger.all/8
    (mix 1.15.7) lib/mix/dep/converger.ex:162: Mix.Dep.Converger.init_all/8
    (mix 1.15.7) lib/mix/dep/converger.ex:110: Mix.Dep.Converger.all/4
    (mix 1.15.7) lib/mix/dep/converger.ex:89: Mix.Dep.Converger.converge/4

What should I do to have it work again?

EDIT 1: I am using rtx and the latest Erlang (26.1.2) and Elixir at this time (1.15.7-otp-26).

EDIT 2: I also tried running the command inside the release directory, the error stays the same.

EDIT 3: I realized it’s trying to find tag v0.17.2 but it really doesn’t exist remotely so that’s why it fails. This is likely because I am keeping the local repo on the master branch and do a git pull daily. I did this because I am not seeing any other branch or tag that reflects latest stable release (I mean a meta name like stable, not with an absolute release name like v0.17.1).

How would you recommend a guy like me update and always use the latest and greatest? I can devise a script that has knowledge of semver and just have it always return the biggest version to me and do git checkout on that and use it but I’d like to see if there is another way. If not, then I’ll opt for doing that.

Sure enough, I found a way to discover and use the latest version.

If you have Rust’s toolchain installed (and there is no strong reason for you to not have it just for cases like these), then install semverator and ripgrep like so:

cargo install semverator
cargo install ripgrep

If not, oh well, your OS’ package manager should have them.

Then:

cd ~/path/to/elixirls
semverator max '*' $(git tag --list | rg 'v(\d.+)' -r '$1')

The ripgrep part throws away anything that does not start with a v and has a number afterwards; it also removes the leading v because semverator does not find those to be valid semantic versions – and they are indeed not. The filtering out part was necessary because there are tags in the repo that don’t adhere to semantic versioning.

Currently this snippet yields 0.17.1.

And this is what I just put in my script that updates everything on my system, ElixirLS included, tested it and it works fine:

(
  pushd ~/bin/elixir-ls && # 👈 ‼️ REPLACE THIS WITH YOUR PATH ‼️
  git switch master --force &&
  git pull --force &&
  latest_version=$(semverator max '*' $(git tag --list | rg 'v(\d.+)' -r '$1')) &&
  git switch --detach "tags/v$latest_version" &&
  mix deps.get &&
  MIX_ENV=prod mix do compile, elixir_ls.release2 &&
  popd || return
)

The entire script, of which this is now part, is ran daily. So every day I’ll have this to always jump to the latest release (the one that’s properly semver-tagged anyway but I don’t expect ElixirLS maintainers to suddently forget about semver so :smiley:).

If you find this useful, use and enjoy!

3 Likes

Version 0.18.0 has been released :rocket:

Highlights:

  • Elixir 1.16 support added
  • Diagnostics provider now returns related info with code positions. This feature works best with elixir 1.16 allowing for navigation to invalid syntax elements like mismatched brackets
  • On type parser has been improved and extended. It now keeps a cache of parsed AST and extracted document metadata. Most of the providers have been updated to reuse this metadata eliminating the need for on demand parsing. This should make completions, hover, etc more snappy. The previous implementation was particularly not efficient for completions provider that would parse the file twice for each request
  • Phoenix integration improved. Go To Definition can now navigate to controllers when inside a Phoenix scope. Complete suggestions in Phoenix.Router now return controllers and actions

See full release notes

ElixirLS elixir-ls/CHANGELOG.md at v0.18.0 · elixir-lsp/elixir-ls · GitHub
vscode extension vscode-elixir-ls/CHANGELOG.md at v0.18.0 · elixir-lsp/vscode-elixir-ls · GitHub

24 Likes

Looks like there’s a problem with 0.18.0 and mason.nvim.

image

ElixirLS has felt much more stable in recent releases, and I’ve not had to fight with new versions for the Spark plugin (which backs Ash’s DSL tooling). Thanks for all your hard work!

15 Likes

Version 0.19.0 has been released :rocket:

Highlights:

  • On type parsing and diagnostics for phoenix .heex files
  • Workspace symbols provider has been reimplemented. Previously the workspace symbols index was build from all available symbols. To make it more focused and helpful now only symbols from the project are considered. This change made it much quicker and improved the quality of returned results. Fuzzy matching engine was also improved and made consistent with how complete provider works.
  • [VSCode] Test UI is now able to run multiple tests at once. This is made possible with running mix test command via debug adapter with a custom ExUnit formatter streaming test suite progress via DAP output events. Running multiple tests is supported on workspace folder, file, module, describe blocka and doctest level

See full release notes

ElixirLS elixir-ls/CHANGELOG.md at v0.19.0 · elixir-lsp/elixir-ls · GitHub
vscode extension vscode-elixir-ls/CHANGELOG.md at v0.19.0 · elixir-lsp/vscode-elixir-ls · GitHub

23 Likes

This is very welcome. It was detracting from the usefulness of the tool. Glad to see it addressed.

1 Like

This release seems much more responsive that previous ones.

Thanks for your hard work, ElixirLS team!

6 Likes

Did token scopes change again with 19 or the Jan vscode update? My theme is unpleasant again. :frowning:

There were 2 changes:

  1. do-end and <<>> bracket matching landed. It can be disabled with editor.bracketPairColorization.enabled: false or configured with editor.language.colorizedBracketPairs, see Syntax highlighting broken in "Darcula theme for Elixir" · Issue #404 · elixir-lsp/vscode-elixir-ls · GitHub
  2. Invalid scope assigned to charlists has been fixed
2 Likes

Hi,

I recently upgraded to vscode 1.86.1 and all of a sudden the beam VM that vscode starts randomly hits 500% or more CPU. It’s been running great until I upgraded.

Any ideas?

Here are my specs:

Erlang: 26.2.1
Elixir: 1.16.0-otp-26
VcCode: 1.86.1
ElixirLS: v0.19.0
MacOS: ventura 13.5

Thanks for the reply. I don’t think this wouldn’t account for the changes in my theme. I will have to figure out if it is my overrides I added for 1.17. Maybe. VSCode changed something. That updated for me yesterday as well. :-/

1 Like