Introducing ElixirLS, the Elixir Language Server

Took me some fighting until I pinpoint where and what to put in ~/.spacemacs but it looks like it’s working now. Thank you for the pointer!

Is there an option to run mix format on a file after save?

Yes:

2 Likes

Thanks. I’m using Spacemacs casually for several months and still haven’t learned to properly customize it. Any idea where exactly in its init file should I put this block?

You do not need the full block, I just posted the full area because it was simpler for me :smiley: And sadly I can not tell where to put that in spacemacs.

Its basically the reason why I dropped spacemacs. All packages READMEs assumed vanilla emacs + use-package. It usually took me hours to find out where to put stuff.

After I dropped spacemacs and did a free form emacs config, which I later split into many files, organized similar to how Steve Purcell did, it became a lot easier. Eventually I got to the point where I had everything I need in my emacs config, and even though I did not leverage lazy loading, the config loaded within 5 to 7 seconds, while spacemacs never really got below 20, despite the fact that it advertised itself as “fast”.

Also, perhaps its time that someone opens an issue at spacemacs and tells them that Alchemist is not state of the art anymore but anyone uses lsp-mode/eglot + the LS.

PS: The important part is actually this:

(add-hook 'elixir-mode-hook ;; when we enter elixir mode
          (lambda ()        ;; call this function
            ;; Format on save, this buffer only.
            (add-hook 'before-save-hook #'lsp-format-buffer nil t)))

If you use eglot rather than lsp-mode you need to figure out what function you have to put there in the hook.

3 Likes

Thank you. Only added that last block to Spacemacs’ dotspacemacs/user-config function so now it looks like this:

(defun dotspacemacs/user-config ()
  (use-package lsp-mode
    :commands lsp
    :ensure t
    :diminish lsp-mode
    :hook
    (elixir-mode . lsp)
    :init
    (add-to-list 'exec-path "/Users/dimi/bin/elixir-ls/release"))

  (add-hook 'elixir-mode-hook
            (lambda ()
              (add-hook 'before-save-hook #'lsp-format-buffer nil t)))
  )

lsp-mode plus elixir-ls work, and so does formatting on save.

Very grateful for the assist. :023:

1 Like

Version 0.6.2 was released today! :tada:

Here are the highlights.

Improvements:

  • Add setup.bat support for windows (thanks E14) #374
  • Add a message when done fetching deps #380

Changes:

  • Remove query prefixes from workspace symbol search (the functionality is now longer supported by VSCode) (thanks Łukasz Samson) #396

Bug Fixes:

  • Improve formatting speed (thanks Matt Baker) #390
  • Fix warnings and errors around starting wx (thanks Łukasz Samson) #388
    • This fixes an issue when running ElixirLS in VSCode remote dev containers
  • Fix formatting on windows (thanks Po Chen) #375

VSCode:

Also:

As always, I want to give a huge thanks to all the contributors to this release! :heart:

Full changelog

9 Likes

The patch is open on vim-lsp-settings https://github.com/mattn/vim-lsp-settings/pull/341. :slight_smile:

1 Like

Did a git pull the other day and then git checkout v0.6.2. Both Elixir and Rust language servers fail with reasons I can’t find. Where should I look?

With Elixir I get “Server <…> status:starting exited with status exit. Do you want to restart it?”-- even if I press Y the same things happens until I press N.

Can anyone help?

EDIT: Sorry, had a bad day. It was as simple as asdf local erlang 23.1.5 because my project used an older version that I’ve since deleted. Apologies for polluting the thread.

2 Likes

Version 0.6.3 was released today! :confetti_ball:

Here are the highlights:

Major changes:

Improvements:

Bug Fixes:

Housekeeping:

VSCode:

As always, I want to give a huge thanks to all the contributors to this release! :heart:

Full changelog

33 Likes

0.6.4 was released today which has a hotfix for a startup issue that was primarily affecting macOS:

7 Likes

0.6.5 was released to which has a hotfix for a regression introduced in 0.6.3:

This would often manifest when VSCode had staged or unstaged changes.

10 Likes

Version 0.7.0 was released today! :confetti_ball:

Here are the highlights:

Major Changes:

  • Support auto-generating folding ranges (textDocument/foldingRange) (thanks billylanchantin (inspired by an initial PR by Thanabodee Charoenpiriyakij) #492

    • Example: Screenshot 2021-03-29 08.15.31
    • For VSCode this will work automatically, other editors may need to enable LSP folding range support explicitly
  • Use fuzzy matching for function completion (thanks Po Chen) #491

    • For example: “valp” will match validate_password and “Enum.chub” will match Enum.chunk_by/2
    • Note: the plan is to extend this fuzzy matching to other types of completion in the future, please try it out and give us feedback!

Improvements:

Bug Fixes:

  • Make expandMacro a custom command (thanks Łukasz Samson) #498
    • Will need to be bound in your editor to make use of it
  • Suppress setup script stdout output on windows(thanks Po Chen) #497

Housekeeping:

  • Improved support for OTP 24 (thanks Tom Crossland) #504
    • Note that OTP 24 isn’t officially supported since it is not yet released

VSCode:

Deprecations
Deprecate non-standard elixirDocument/macroExpansion command. It is being replaced with the expandMacro custom command. See #498 for details. It is planned to be fully removed in 0.8

As always, I want to give a huge thanks to all the contributors to this release! :heart:

Full changelog

27 Likes

Hi Jason,

There is a minor error in the description about the fuzzy matching. valword will actually match validate_password. The first character restriction is only applied to the very first character of the whole function name. If the trigger word doesn’t start with v it would not match, like if one types dw wouldn’t get validate_password, but vpw, vp or vw will.

5 Likes

Thanks, updated!

1 Like

Tried to scan the issue tracker for what I am experiencing for a week or two now, can’t find anything (might be me though, I am not sure what exactly to search with).

But basically using Erlang 24.0.2 and Elixir 1.12.1-otp-24 reliably crashes ElixirLS as far as I can tell. Here’s a hopefully relevant excerpt from my Spacemacs’ *lsp-log* buffer:

19:39:41.324 [error] Task #PID<0.261.0> started from #PID<0.217.0> terminating
** (ArithmeticError) bad argument in arithmetic expression
    (language_server 0.6.0) lib/language_server/providers/workspace_symbols.ex:519: ElixirLS.LanguageServer.Providers.WorkspaceSymbols.build_range/1
    (language_server 0.6.0) lib/language_server/providers/workspace_symbols.ex:487: ElixirLS.LanguageServer.Providers.WorkspaceSymbols.build_result/4
    (language_server 0.6.0) lib/language_server/providers/workspace_symbols.ex:397: anonymous fn/4 in ElixirLS.LanguageServer.Providers.WorkspaceSymbols.index/1
    (elixir 1.12.1) lib/enum.ex:2356: Enum."-reduce/3-lists^foldl/2-0-"/3
    (language_server 0.6.0) lib/language_server/providers/workspace_symbols.ex:386: anonymous fn/1 in ElixirLS.LanguageServer.Providers.WorkspaceSymbols.index/1
    (elixir 1.12.1) lib/task/supervised.ex:90: Task.Supervised.invoke_mfa/2
    (elixir 1.12.1) lib/task/supervised.ex:35: Task.Supervised.reply/5
    (stdlib 3.15.1) proc_lib.erl:226: :proc_lib.init_p_do_apply/3
Function: #Function<32.57814553/0 in ElixirLS.LanguageServer.Providers.WorkspaceSymbols.do_process_chunked/2>
    Args: []
** (exit) exited in: GenServer.call(ElixirLS.LanguageServer.JsonRpc, {:packet, %{"id" => 137, "jsonrpc" => "2.0", "method" => "textDocument/hover", "params" => %{"position" => %{"character" => 19, "line" => 7}, "textDocument" => %{"uri" => "file:///Users/dimi/kod/square-many/mix.exs"}}}}, 5000)
    ** (EXIT) no process: the process is not alive or there's no process currently associated with the given name, possibly because its application isn't started
    (elixir 1.12.1) lib/gen_server.ex:1014: GenServer.call/3
    (elixir 1.12.1) lib/stream.ex:441: anonymous fn/4 in Stream.each/2
    (elixir 1.12.1) lib/stream.ex:1559: Stream.do_element_resource/6
    (elixir 1.12.1) lib/stream.ex:1719: Enumerable.Stream.do_each/4
    (elixir 1.12.1) lib/stream.ex:649: Stream.run/1
    (stdlib 3.15.1) erl_eval.erl:685: :erl_eval.do_apply/6
Cleaning up watches for folder /Users/dimi/kod/square-many. There is no workspace watching this folder...

(The first part ([error] Task #PID ...) is repeated several times.)

This is a brand new bare-bones project, without application.ex even. But the same happens with any other projects I tried with.

Anything I can do? I am always using elixir-lsp/elixir-ls GitHub HEAD btw, and I am updating it daily from there. Maybe I shouldn’t and I should just latest stable release? Or maybe ElixirLS isn’t yet compatible with Erlang 24 / Elixir 1.12?

Can you confirm which specific commit that you are using? Perhaps you didn’t run mix elixir_ls.release after running git pull. I ask because ElixirLS is currently on 0.7.0 (your stack trace lists 0.6.0) and it looks like you’re running into this OTP 24 compatibility error: Compatibility with OTP 24 · Issue #503 · elixir-lsp/elixir-ls · GitHub

Which was fixed in March:

1 Like

Sure:

* be0af9d - (HEAD -> master, origin/master, origin/HEAD) Update README troubleshooting and known issues (#554) (3 days ago) <Jason Axelson>

Had to run mix deps.get first. After running mix elixir_ls.release, I got this:

# ...
# compiling other deps before this finishes successfully
# ...
==> elixir_sense
Compiling 54 files (.ex)
Generated elixir_sense app
warning: Building with Erlang/OTP 24. Make sure to build with OTP 21 if publishing the compiled packages because modules built with higher versions are not backwards-compatible.

** (ErlangError) Erlang error: {:invalid_status, :compile}
    (mix_task_archive_deps 0.4.0) lib/mix/tasks/archive/build.deps.ex:78: anonymous fn/3 in Mix.Tasks.Archive.Build.Deps.list/1
    (elixir 1.12.1) lib/enum.ex:1553: Enum."-map/2-lists^map/1-0-"/2
    (elixir 1.12.1) lib/enum.ex:1553: Enum."-map/2-lists^map/1-0-"/2
    (mix_task_archive_deps 0.4.0) lib/mix/tasks/archive/build.deps.ex:53: Mix.Tasks.Archive.Build.Deps.build_archives/1
    (mix 1.12.1) lib/mix/task.ex:394: anonymous fn/3 in Mix.Task.run_task/3
    lib/mix.tasks.elixir_ls.release.ex:17: Mix.Tasks.ElixirLs.Release.run/1
    (mix 1.12.1) lib/mix/task.ex:394: anonymous fn/3 in Mix.Task.run_task/3
    (mix 1.12.1) lib/mix/cli.ex:84: Mix.CLI.run_task/2

asdf current returns:

elixir          1.12.1-otp-24   /Users/dimi/.tool-versions
erlang          24.0.2          /Users/dimi/.tool-versions
nodejs          15.14.0         /Users/dimi/.tool-versions

That’s a bug in the archive does library. I think it’s fixed with a rm -r _build, although you might have to remove some tmp directories from the individual applications. There’s a closed issue for it but I don’t have the link handy.

1 Like

Okay, removing _build worked. I got a bunch of .ez archives in the release directory now. Anything else I should do?

I am asking this because I am after a daily script that updates ElixirLS and want to have all the steps put there.