Introducing ElixirLS, the Elixir Language Server

Am I incorrect in thinking once the org is setup the vscode plugin (and its PRs) could be forked / renamed / released for those waiting on the PRs? Sounds like the language server itself will require a tad more work.

Hi everyone,

I apologize for being incommunicado. I don’t have a really good reason besides feeling burnt out and procrastinating about working on it. I know that’s frustrating to everyone who’s tried to contribute in the past couple months.

I’m going to work through the current PRs, and then I think I’m going to try a schedule of working on PRs and major bugs for 1-2 days at the start of each month. That way I don’t get tired of it and avoid it completely. If I fail to hold to that schedule, feel free to badger me here. I am happy that people are using it and I do want it to continue to improve!


@JakeBecker pop into the #language-server room in slack. We’d like to combine forces. We have several folks carrying the torch now on the fork.


Just wanted to thank you for your work. A big part of my enjoyment in using Elixir with VSCode has been because of what you’ve been doing.


Thanks for your tips, but I cannot get it to work…

So when sublime starts the elixir-ls server it outputs this in the console:

startup, version: 3200 linux x64 channel: stable
executable: /opt/sublime_text/sublime_text
working dir: /
packages path: /home/elixir/.config/sublime-text-3/Packages
state path: /home/elixir/.config/sublime-text-3/Local
zip path: /opt/sublime_text/Packages
zip path: /home/elixir/.config/sublime-text-3/Installed Packages
ignored_packages: ["Vintage"]
pre session restore time: 0.124293
startup time: 0.169236
git: tracking working dir /home/elixir/workspace/elixir-for-programmers
first paint time: 0.197519
reloading plugin Default.arithmetic
reloading plugin Default.auto_indent_tag
reloading plugin Default.block
reloading plugin Default.colors
reloading plugin Default.comment
reloading plugin Default.convert_color_scheme
reloading plugin Default.convert_syntax
reloading plugin Default.copy_path
reloading plugin Default.detect_indentation
reloading plugin Default.echo
reloading plugin Default.exec
reloading plugin Default.fold
reloading plugin Default.font
reloading plugin Default.goto_line
reloading plugin Default.history_list
reloading plugin Default.indentation
reloading plugin Default.install_package_control
reloading plugin Default.kill_ring
reloading plugin Default.mark
reloading plugin Default.new_templates
reloading plugin Default.open_context_url
reloading plugin Default.open_in_browser
reloading plugin Default.pane
reloading plugin Default.paragraph
reloading plugin Default.paste_from_history
reloading plugin Default.profile
reloading plugin Default.quick_panel
reloading plugin Default.rename
reloading plugin Default.run_syntax_tests
reloading plugin Default.save_on_focus_lost
reloading plugin Default.scroll
reloading plugin Default.set_unsaved_view_name
reloading plugin Default.settings
reloading plugin Default.show_scope_name
reloading plugin Default.side_bar
reloading plugin Default.sort
reloading plugin Default.switch_file
reloading plugin Default.symbol
reloading plugin Default.transform
reloading plugin Default.transpose
reloading plugin Default.ui
reloading plugin CSS.css_completions
reloading plugin Diff.diff
reloading plugin HTML.encode_html_entities
reloading plugin HTML.html_completions
reloading plugin ShellScript.ShellScript
reloading plugin 0_package_control_loader.00-package_control
reloading plugin 0_package_control_loader.01-pygments
reloading plugin 0_package_control_loader.50-markupsafe
reloading plugin 0_package_control_loader.50-pymdownx
reloading plugin 0_package_control_loader.50-python-markdown
reloading plugin 0_package_control_loader.50-pyyaml
reloading plugin 0_package_control_loader.51-python-jinja2
reloading plugin 0_package_control_loader.55-mdpopups
reloading plugin Package Control.1_reloader
reloading plugin Package Control.2_bootstrap
reloading plugin Package Control.Package Control
reloading plugin LSP.boot
plugins loaded
LSP: global configs ['lsp-tsserver=False', 'javascript-typescript-langserver=False', 'reason=False', 'haskell-ide-engine=False', 'eslint=False', 'elixir-ls=True', 'clangd=False', 'jdtls=False', 'ocaml=False', 'pyls=False', 'polymer-ide=False', 'typescript-language-server=False', 'rls=False', 'cquery=False', 'phpls=False', 'golsp=False']
LSP: window 2 starting 1 initial views
Package Control: Skipping automatic upgrade, last run at 2019-04-06 10:48:14, next run at 2019-04-06 11:48:14 or after
LSP: window 2 requests elixir-ls for /home/elixir/workspace/elixir-for-programmers/hangman/lib/hangman.ex
LSP: starting in /home/elixir/workspace/elixir-for-programmers
LSP: starting ['elixir-ls']
LSP:  --> initialize
LSP: window 2 added session elixir-ls
server: warning: variable "deps" does not exist and is being expanded to "deps()", please use parentheses to remove the ambiguity or change the variable name
server: /home/elixir/elixir-ls/deps/erl2ex/mix.exs:14
server: warning: variable "docs" does not exist and is being expanded to "docs()", please use parentheses to remove the ambiguity or change the variable name
server: /home/elixir/elixir-ls/deps/erl2ex/mix.exs:15
server: warning: variable "description" does not exist and is being expanded to "description()", please use parentheses to remove the ambiguity or change the variable name
server: /home/elixir/elixir-ls/deps/erl2ex/mix.exs:16
server: warning: variable "package" does not exist and is being expanded to "package()", please use parentheses to remove the ambiguity or change the variable name
server: /home/elixir/elixir-ls/deps/erl2ex/mix.exs:17

@JakeBecker does it look ok the start of the server to you?

But I cannot get it to work with this LSP settings:

	"auto_show_diagnostics_panel_level": 4,
			"enabled": true,
			"languageId": "elixir",
	"diagnostics_highlight_style": "box",
	"log_debug": true,
	"log_payloads": true,
	"log_stderr": true,
	"only_show_lsp_completions": true,
	"resolve_completion_for_snippets": true,
	"show_code_actions_bulb": true,
	"show_diagnostics_phantoms": true,
	"show_diagnostics_severity_level": 4

My bash script to start elixir-ls the is in my path at ~/bin:


set -eu

cd ~/elixir-ls && mix run --no-halt

So if I start it form the command line:

╭─elixir@043149b4ce3c ~  
╰─$ elixir-ls
warning: variable "deps" does not exist and is being expanded to "deps()", please use parentheses to remove the ambiguity or change the variable name

warning: variable "docs" does not exist and is being expanded to "docs()", please use parentheses to remove the ambiguity or change the variable name

warning: variable "description" does not exist and is being expanded to "description()", please use parentheses to remove the ambiguity or change the variable name

warning: variable "package" does not exist and is being expanded to "package()", please use parentheses to remove the ambiguity or change the variable name

  Warning: the `dialyxir` application's start function was called, which likely means you
  did not add the dependency with the `runtime: false` flag. This is not recommended because
  it will mean that unnecessary applications are started, and unnecessary applications are most
  likely being added to your PLT file, increasing build time.
  Please add `runtime: false` in your `mix.exs` dependency section e.g.:
  {:dialyxir, "~> 0.5", only: [:dev], runtime: false}

It does not give me back the shell prompt… is that the expected behaviour @JakeBecker?


Sublime version:

╭─elixir@043149b4ce3c ~  
╰─$ subl --version                                                                                                                              127 ↵
Sublime Text Build 3200

Elixir version:

╭─elixir@043149b4ce3c ~  
╰─$ elixir --version                                                                                                                            
Erlang/OTP 21 [erts-10.3.2] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:1] [hipe]

Elixir 1.7.4 (compiled with Erlang/OTP 21)

Checking the syntax package to use in settings:

>>> sublime.active_window().active_view().settings().get("syntax")

So this is the same I have declared in LSP settings, and I already tried to use a different package for syntax, but makes no difference to get LSP working.

What bothers me is that I cannot find that file:

╭─elixir@043149b4ce3c ~  
╰─$ l ~/.config/sublime-text-3/Packages/ElixirSyntax/Elixir.sublime-syntax
ls: cannot access '/home/elixir/.config/sublime-text-3/Packages/ElixirSyntax/Elixir.sublime-syntax': No such file or directory
╭─elixir@043149b4ce3c ~  
╰─$ l ~/.config/sublime-text-3/Packages/                                                                                                          
total 56K
drwxr-xr-x 1 elixir elixir 4.0K Apr  5 22:18 .
drwxr-xr-x 1 elixir elixir 4.0K Apr  5 22:16 ..
drwxr-xr-x 1 elixir elixir 4.0K Apr  5 21:59 LSP
drwxr-xr-x 3 elixir elixir 4.0K Apr  5 22:18 markupsafe
drwxr-xr-x 6 elixir elixir 4.0K Apr  5 22:18 mdpopups
drwxr-xr-x 3 elixir elixir 4.0K Apr  5 22:18 pygments
drwxr-xr-x 3 elixir elixir 4.0K Apr  5 22:18 pymdownx
drwxr-xr-x 3 elixir elixir 4.0K Apr  5 22:18 python-jinja2
drwxr-xr-x 3 elixir elixir 4.0K Apr  5 22:18 python-markdown
drwxr-xr-x 4 elixir elixir 4.0K Apr  5 22:18 pyyaml
drwx------ 3 elixir elixir 4.0K Apr  5 22:20 User

So in the packages folder I don’t have the ElixirSyntax package, but is installed:

╭─elixir@043149b4ce3c ~  
╰─$ l ~/.config/sublime-text-3/Installed\ Packages 
total 304K
drwx------ 2 elixir elixir 4.0K Apr  6 11:21 .
drwxr-xr-x 1 elixir elixir 4.0K Apr  5 22:16 ..
-rw-r--r-- 1 elixir elixir 3.9K Apr  5 22:18 0_package_control_loader.sublime-package
-rw-r--r-- 1 elixir elixir 7.8K Apr  6 11:21 ElixirSyntax.sublime-package
-rw-r--r-- 1 elixir elixir 280K Apr  5 22:13 Package Control.sublime-package

and I can see cache for it:

╭─elixir@043149b4ce3c ~  
╰─$ l ~/.config/sublime-text-3/Cache/ElixirSyntax
total 40K
drwx------  2 elixir elixir 4.0K Apr  6 11:21 .
drwx------ 51 elixir elixir 4.0K Apr  6 11:21 ..
-rw-r--r--  1 elixir elixir 4.4K Apr  6 11:21 Elixir.sublime-syntax.cache
-rw-r--r--  1 elixir elixir  15K Apr  6 11:21 Elixir.sublime-syntax.rcache
-rw-r--r--  1 elixir elixir 4.2K Apr  6 11:21 HTML (EEx).sublime-syntax.cache

Am I missing something in my steps?

P.S: This is running from docker with Debian, but this should not be the problem.

Has anyone had issues with environment variables? Recently we added Application.fetch_env!() in our mix.env to catch improperly set env vars early on. So we now source our .env file before running mix whatever. But can we tell elixir-ls to do that to? I cannot really find it inside the docs, and we now get Formatting failed a lot :frowning: due to some env variable that was not set.

ps axww|grep elixir-ls
7398 S 0:00 sh /home/am/.vscode/extensions/elixir-lsp.elixir-ls-0.2.27/elixir-ls-release/

That’s not the best approach whatsoever (it’d probably suffer overwrites and require to be reapplied after each update,) but sourcing your .env from there should definitely do the trick.

elixir-ls compiles and runs on :test environment. The way we use it here is to fill those config envs on test.exs only and then it won’t misbehave. Most of the time those variables are not meant for test environment.

Hi everyone! Long time no see!

If you’ve been using ElixirLS, you may have noticed that I haven’t really maintained it in a year or so. All my work for a while has been on hardware that doesn’t run Elixir, mainly 2x4s and drywall, and I told myself ElixirLS was on the backburner because I didn’t want to think of it as “abandoned”. But after a year of neglect, I’m ready to admit that I’m not going to be working on it in the near future.

I have excellent news though: While I’ve been away, a few proactive volunteers from the Elixir community started a fork and have put major work into actively maintaining it. I had long since routed my Github notifications somewhere they wouldn’t bother me, so I didn’t really realize how much work they’d been doing in my absence, and @axelson, @lukaszsamson, and other contributors have my gratitude and respect.

I’m retiring my Github repo in favor of theirs over at elixir-lsp/elixir-ls. They’ll continue publishing to the original VS Code extension, so if you’re using the original ElixirLS for VS Code, you can keep using it. If you’ve been using their fork, you can switch back to the original extension. Any issues or PRs should happen on the new repo. Starting an open-source project is more fun than maintaining one, so if you file an issue over on that repo, make sure to say thanks for their hard work.

I do hope to go back to coding Elixir at some point once my house has walls and toilets and everything. In the meantime, I’m happy the project is in good hands. Thanks for using ElixirLS!


Thanks so much Jake for all of your extremely hard work on ElixirLS and for being willing to merge the two projects back together :heart:, we wouldn’t have been able to accomplish so much without you. I do hope that eventually you can get back to Elixir coding and work as part of the ElixirLS core team :blush:. And I also hope that you get to enjoy working with your hands on your house (and some physical labor does sound like a nice break from coding).


Awesome to hear there will be one ElixirLS to rule them all. Any ETA when we should move from the fork back to the OG plugin?

Thanks to all those who started and who continue to work on ElixirLS!

1 Like

You can move from the fork back to the original plugin now:

There was a new release yesterday. Here’s a link to the changelog:


To avoid future confusion, I might suggest archiving the JakeBecker repository and contacting GitHub support to convert the elixir-lsp repository from a “fork” to a “normal” repository.


It’s a good news!

Just a little confused that the extension name is JakeBecker.elixir-ls while the Github repo is elixir-lsp/elixir-ls.

And maybe doing the same by contacting VSCode so that the new extension name keep the stats of the old one.

Also, does anyone know how to handle the Plugin when working with a Phoenix umbrella app ?
I guessed that pointing to the root of the umbrella would be the things to do, but when doing this I got some errors/warning on the child apps.
Currently I set the mix directory to the Phoenix App (e.g. my_app_web)

Unfortunately it’s my understanding that isn’t possible to rename the VSCode extension publisher to match.

Version 0.4.0 was released today! :confetti_ball:

(Note that there are some potentially breaking changes for VSCode users)
(Note: if you’re using the “ElixirLS Fork” version of the VSCode plugin you should switch back to ElixirLS)

Here are the highlights:


Major changes:


  • Add all core elixir apps to the Dialyzer PLT. (thanks Eric Entin) #225
  • Change “did not receive workspace/didChangeConfiguration” log level from warning to info (thanks Jason Axelson) #222
  • Automatically create a .gitignore file inside the .elixir-ls dir so that users do not need to manually add it to their gitignore (thanks Thanabodee Charoenpiriyakij) #232
  • Load all modules after first build (thanks Akash Hiremath) #227
    • This means that dialyzer is no longer needed for workspace symbol support :tada:

Bug Fixes:

  • Don’t return snippets to clients that don’t declare snippetSupport (such as vim) (thanks Jeffrey Xiao) #223


  • Better phoenix templates support (thanks Marlus Saraiva) #93
  • Add basic support for .html.leex files for Phoenix LiveView (thanks oskarkook) #82
  • Add filetype and watcher for .html.leex files for Phoenix LiveView (thanks Byron Hambly) #83

VSCode potentially breaking changes:

  • Change language id to be lowercase kebab-case in accordance with VSCode guidelines. This also fixes an issue displaying the elixir logo for html.eex files. (thanks Matt Furden) #87
    • This changes the language id’s EEx->eex and HTML (EEx)->html-eex
    • If you have customized your emmet configuration configuration then you need to update it:
    • Open VSCode and hit Ctrl+Shift+P or Cmd+Shift+P and type "Preference: Open Settings (JSON)"
    • Add or edit your emmet.includedLanguages to include the new Language Id:
      "emmet.includeLanguages": {
        "html-eex": "html"

Full changelog

I want to give a huge thanks to all the contributors to this release! :heart: As you can see from the changelog there are quite a few!


Wow, solid update. Great work everyone! :orange_heart:

1 Like

Thank you so much everyone - ElixirLS is a huge productive boost, and sweating all these details and improvements makes a massive difference! :blush:


For vim and vim-lsp users, I opened PR for upgrade elixir-ls to vim-lsp-settings here.


Thanks @wingyplus.