From 7eae7812915602ece637714e6f82d4551e9697b6 Mon Sep 17 00:00:00 2001 From: Jon Parise Date: Fri, 28 Sep 2018 11:42:50 -0700 Subject: [PATCH] Add elixir-ls language server support ElixirLS (https://github.com/JakeBecker/elixir-ls) is an LSP server for Elixir. It's distributed as a release package that can be downloaded from https://github.com/JakeBecker/elixir-ls/releases or built locally. The easiest way to start it is via Unix- and Win32-specific helper scripts, so that's the basis of this command integration. Alternatively, we could implement the contents of those platform-specific scripts in the linter's command callback in a language-neutral way, but there isn't any benefit to doing that aside from eliminating the platform check, and that could prove to be too tight of a coupling going forward. --- README.md | 2 +- ale_linters/elixir/elixir_ls.vim | 19 ++++++++++++ doc/ale-elixir.txt | 13 +++++++++ doc/ale.txt | 3 +- .../test_elixir_ls_command_callbacks.vader | 29 +++++++++++++++++++ 5 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 ale_linters/elixir/elixir_ls.vim create mode 100644 test/command_callback/test_elixir_ls_command_callbacks.vader diff --git a/README.md b/README.md index 80768f07..ec9092b9 100644 --- a/README.md +++ b/README.md @@ -117,7 +117,7 @@ formatting. | Dafny | [dafny](https://rise4fun.com/Dafny) !! | | Dart | [dartanalyzer](https://github.com/dart-lang/sdk/tree/master/pkg/analyzer_cli) !!, [language_server](https://github.com/natebosch/dart_language_server), [dartfmt](https://github.com/dart-lang/sdk/tree/master/utils/dartfmt) | | Dockerfile | [hadolint](https://github.com/hadolint/hadolint) | -| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!| +| Elixir | [credo](https://github.com/rrrene/credo), [dialyxir](https://github.com/jeremyjh/dialyxir), [dogma](https://github.com/lpil/dogma), [mix](https://hexdocs.pm/mix/Mix.html) !!, [elixir-ls](https://github.com/JakeBecker/elixir-ls) | | Elm | [elm-format](https://github.com/avh4/elm-format), [elm-make](https://github.com/elm-lang/elm-make) | | Erb | [erb](https://apidock.com/ruby/ERB), [erubi](https://github.com/jeremyevans/erubi), [erubis](https://github.com/kwatch/erubis) | | Erlang | [erlc](http://erlang.org/doc/man/erlc.html), [SyntaxErl](https://github.com/ten0s/syntaxerl) | diff --git a/ale_linters/elixir/elixir_ls.vim b/ale_linters/elixir/elixir_ls.vim new file mode 100644 index 00000000..d5ad7cfc --- /dev/null +++ b/ale_linters/elixir/elixir_ls.vim @@ -0,0 +1,19 @@ +" Author: Jon Parise +" Description: elixir-ls integration (https://github.com/JakeBecker/elixir-ls) + +call ale#Set('elixir_elixir_ls_release', 'elixir-ls') + +function! ale_linters#elixir#elixir_ls#GetExecutable(buffer) abort + let l:dir = ale#path#Simplify(ale#Var(a:buffer, 'elixir_elixir_ls_release')) + let l:cmd = ale#Has('win32') ? '\language_server.bat' : '/language_server.sh' + + return l:dir . l:cmd +endfunction + +call ale#linter#Define('elixir', { +\ 'name': 'elixir-ls', +\ 'lsp': 'stdio', +\ 'executable_callback': 'ale_linters#elixir#elixir_ls#GetExecutable', +\ 'command_callback': 'ale_linters#elixir#elixir_ls#GetExecutable', +\ 'project_root_callback': 'ale#handlers#elixir#FindMixProjectRoot', +\}) diff --git a/doc/ale-elixir.txt b/doc/ale-elixir.txt index ac0ec605..769842a4 100644 --- a/doc/ale-elixir.txt +++ b/doc/ale-elixir.txt @@ -40,5 +40,18 @@ configured on your project's `mix.exs`. See https://github.com/jeremyjh/dialyxir#with-explaining-stuff for more information. +=============================================================================== +elixir-ls *ale-elixir-elixir-ls* + +Elixir Language Server (https://github.com/JakeBecker/elixir-ls) + +g:ale_elixir_elixir_ls_release *g:ale_elixir_elixir_ls_release* + *b:ale_elixir_elixir_ls_release* + Type: |String| + Default: `'elixir-ls'` + + Location of the elixir-ls release directory. This directory must contain + the language server scripts (language_server.sh and language_server.bat). + =============================================================================== vim:tw=78:ts=2:sts=2:sw=2:ft=help:norl: diff --git a/doc/ale.txt b/doc/ale.txt index 3c561e2f..27334b9d 100644 --- a/doc/ale.txt +++ b/doc/ale.txt @@ -77,6 +77,7 @@ CONTENTS *ale-contents* mix.................................|ale-elixir-mix| mix_format..........................|ale-elixir-mix-format| dialyxir............................|ale-elixir-dialyxir| + elixir-ls...........................|ale-elixir-elixir-ls| elm...................................|ale-elm-options| elm-format..........................|ale-elm-elm-format| elm-make............................|ale-elm-elm-make| @@ -397,7 +398,7 @@ Notes: * Dafny: `dafny`!! * Dart: `dartanalyzer`!!, `language_server`, dartfmt!! * Dockerfile: `hadolint` -* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!! +* Elixir: `credo`, `dialyxir`, `dogma`, `mix`!!, `elixir-ls` * Elm: `elm-format, elm-make` * Erb: `erb`, `erubi`, `erubis` * Erlang: `erlc`, `SyntaxErl` diff --git a/test/command_callback/test_elixir_ls_command_callbacks.vader b/test/command_callback/test_elixir_ls_command_callbacks.vader new file mode 100644 index 00000000..0d00354b --- /dev/null +++ b/test/command_callback/test_elixir_ls_command_callbacks.vader @@ -0,0 +1,29 @@ +Before: + call ale#assert#SetUpLinterTest('elixir', 'elixir_ls') + + let g:ale_has_override['win32'] = 0 + +After: + let g:ale_has_override = {} + + call ale#assert#TearDownLinterTest() + +Execute(should set correct defaults (unix)): + AssertLinter 'elixir-ls/language_server.sh', 'elixir-ls/language_server.sh' + +Execute(should set correct defaults (win32)): + let g:ale_has_override['win32'] = 1 + + AssertLinter 'elixir-ls\language_server.bat', 'elixir-ls\language_server.bat' + +Execute(should configure elixir-ls release location): + let b:ale_elixir_elixir_ls_release = 'boo' + + AssertLinter 'boo/language_server.sh', 'boo/language_server.sh' + +Execute(should set correct LSP values): + call ale#test#SetFilename('mix_paths/wrapped_project/lib/app.ex') + + AssertLSPLanguage 'elixir' + AssertLSPOptions {} + AssertLSPProject ale#path#Simplify(g:dir . '/mix_paths/wrapped_project')