mirror of
https://github.com/dense-analysis/ale.git
synced 2025-12-06 20:54:26 +08:00
Add erlang_ls linter for Erlang files (#4346)
This commit is contained in:
committed by
GitHub
parent
d02e58b404
commit
06efbdd25a
49
ale_linters/erlang/erlang_ls.vim
Normal file
49
ale_linters/erlang/erlang_ls.vim
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
" Author: Dmitri Vereshchagin <dmitri.vereshchagin@gmail.com>
|
||||||
|
" Description: LSP linter for Erlang files
|
||||||
|
|
||||||
|
call ale#Set('erlang_erlang_ls_executable', 'erlang_ls')
|
||||||
|
call ale#Set('erlang_erlang_ls_log_dir', '')
|
||||||
|
call ale#Set('erlang_erlang_ls_log_level', 'info')
|
||||||
|
|
||||||
|
function! s:GetCommand(buffer) abort
|
||||||
|
let l:log_dir = ale#Var(a:buffer, 'erlang_erlang_ls_log_dir')
|
||||||
|
let l:log_level = ale#Var(a:buffer, 'erlang_erlang_ls_log_level')
|
||||||
|
|
||||||
|
let l:command = '%e'
|
||||||
|
|
||||||
|
if !empty(l:log_dir)
|
||||||
|
let l:command .= ' --log-dir=' . ale#Escape(l:log_dir)
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:command .= ' --log-level=' . ale#Escape(l:log_level)
|
||||||
|
|
||||||
|
return l:command
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:FindProjectRoot(buffer) abort
|
||||||
|
let l:markers = ['_build/', 'erlang_ls.config', 'rebar.lock']
|
||||||
|
|
||||||
|
" This is a way to find Erlang/OTP root (the one that is managed
|
||||||
|
" by kerl or asdf). Useful if :ALEGoToDefinition takes us there.
|
||||||
|
let l:markers += ['.kerl_config']
|
||||||
|
|
||||||
|
for l:marker in l:markers
|
||||||
|
let l:path = l:marker[-1:] is# '/'
|
||||||
|
\ ? ale#path#FindNearestDirectory(a:buffer, l:marker)
|
||||||
|
\ : ale#path#FindNearestFile(a:buffer, l:marker)
|
||||||
|
|
||||||
|
if !empty(l:path)
|
||||||
|
return ale#path#Dirname(l:path)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#linter#Define('erlang', {
|
||||||
|
\ 'name': 'erlang_ls',
|
||||||
|
\ 'executable': {b -> ale#Var(b, 'erlang_erlang_ls_executable')},
|
||||||
|
\ 'command': function('s:GetCommand'),
|
||||||
|
\ 'lsp': 'stdio',
|
||||||
|
\ 'project_root': function('s:FindProjectRoot'),
|
||||||
|
\})
|
||||||
@@ -51,6 +51,31 @@ g:ale_erlang_elvis_executable *g:ale_erlang_elvis_executable*
|
|||||||
This variable can be changed to specify the elvis executable.
|
This variable can be changed to specify the elvis executable.
|
||||||
|
|
||||||
|
|
||||||
|
-------------------------------------------------------------------------------
|
||||||
|
erlang_ls *ale-erlang-erlang_ls*
|
||||||
|
|
||||||
|
g:ale_erlang_erlang_ls_executable *g:ale_erlang_erlang_ls_executable*
|
||||||
|
*b:ale_erlang_erlang_ls_executable*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'erlang_ls'`
|
||||||
|
|
||||||
|
This variable can be changed to specify the erlang_ls executable.
|
||||||
|
|
||||||
|
g:ale_erlang_erlang_ls_log_dir *g:ale_erlang_erlang_ls_log_dir*
|
||||||
|
*b:ale_erlang_erlang_ls_log_dir*
|
||||||
|
Type: |String|
|
||||||
|
Default: `''`
|
||||||
|
|
||||||
|
If set this variable overrides default directory where logs will be written.
|
||||||
|
|
||||||
|
g:ale_erlang_erlang_ls_log_level *g:ale_erlang_erlang_ls_log_level*
|
||||||
|
*b:ale_erlang_erlang_ls_log_level*
|
||||||
|
Type: |String|
|
||||||
|
Default: `'info'`
|
||||||
|
|
||||||
|
This variable can be changed to specify log level.
|
||||||
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
-------------------------------------------------------------------------------
|
||||||
erlc *ale-erlang-erlc*
|
erlc *ale-erlang-erlc*
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,7 @@ Notes:
|
|||||||
* `SyntaxErl`
|
* `SyntaxErl`
|
||||||
* `dialyzer`!!
|
* `dialyzer`!!
|
||||||
* `elvis`!!
|
* `elvis`!!
|
||||||
|
* `erlang_ls`
|
||||||
* `erlc`
|
* `erlc`
|
||||||
* `erlfmt`
|
* `erlfmt`
|
||||||
* Fish
|
* Fish
|
||||||
|
|||||||
@@ -2885,6 +2885,7 @@ documented in additional help files.
|
|||||||
erlang..................................|ale-erlang-options|
|
erlang..................................|ale-erlang-options|
|
||||||
dialyzer..............................|ale-erlang-dialyzer|
|
dialyzer..............................|ale-erlang-dialyzer|
|
||||||
elvis.................................|ale-erlang-elvis|
|
elvis.................................|ale-erlang-elvis|
|
||||||
|
erlang_ls.............................|ale-erlang-erlang_ls|
|
||||||
erlc..................................|ale-erlang-erlc|
|
erlc..................................|ale-erlang-erlc|
|
||||||
erlfmt................................|ale-erlang-erlfmt|
|
erlfmt................................|ale-erlang-erlfmt|
|
||||||
syntaxerl.............................|ale-erlang-syntaxerl|
|
syntaxerl.............................|ale-erlang-syntaxerl|
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ formatting.
|
|||||||
* [SyntaxErl](https://github.com/ten0s/syntaxerl)
|
* [SyntaxErl](https://github.com/ten0s/syntaxerl)
|
||||||
* [dialyzer](http://erlang.org/doc/man/dialyzer.html) :floppy_disk:
|
* [dialyzer](http://erlang.org/doc/man/dialyzer.html) :floppy_disk:
|
||||||
* [elvis](https://github.com/inaka/elvis) :floppy_disk:
|
* [elvis](https://github.com/inaka/elvis) :floppy_disk:
|
||||||
|
* [erlang_ls](https://github.com/erlang-ls/erlang_ls)
|
||||||
* [erlc](http://erlang.org/doc/man/erlc.html)
|
* [erlc](http://erlang.org/doc/man/erlc.html)
|
||||||
* [erlfmt](https://github.com/WhatsApp/erlfmt)
|
* [erlfmt](https://github.com/WhatsApp/erlfmt)
|
||||||
* Fish
|
* Fish
|
||||||
|
|||||||
48
test/linter/test_erlang_erlang_ls.vader
Normal file
48
test/linter/test_erlang_erlang_ls.vader
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
Before:
|
||||||
|
let b:files = '../test-files/erlang'
|
||||||
|
call ale#assert#SetUpLinterTest('erlang', 'erlang_ls')
|
||||||
|
|
||||||
|
After:
|
||||||
|
call ale#assert#TearDownLinterTest()
|
||||||
|
|
||||||
|
Execute(The default command should be correct):
|
||||||
|
AssertLinter 'erlang_ls',
|
||||||
|
\ ale#Escape('erlang_ls') . ' --log-level=' . ale#Escape('info')
|
||||||
|
|
||||||
|
Execute(Executable should be configurable):
|
||||||
|
let b:ale_erlang_erlang_ls_executable = '/path/to/erlang_ls'
|
||||||
|
|
||||||
|
AssertLinter '/path/to/erlang_ls',
|
||||||
|
\ ale#Escape('/path/to/erlang_ls') . ' --log-level=' . ale#Escape('info')
|
||||||
|
|
||||||
|
Execute(Log level should be configurable):
|
||||||
|
let b:ale_erlang_erlang_ls_log_level = 'debug'
|
||||||
|
|
||||||
|
AssertLinter 'erlang_ls',
|
||||||
|
\ ale#Escape('erlang_ls') . ' --log-level=' . ale#Escape('debug')
|
||||||
|
|
||||||
|
Execute(Log directory should be configurable):
|
||||||
|
let b:ale_erlang_erlang_ls_log_dir = '/path/to/logs'
|
||||||
|
|
||||||
|
AssertLinter 'erlang_ls',
|
||||||
|
\ ale#Escape('erlang_ls')
|
||||||
|
\ . ' --log-dir=' . ale#Escape('/path/to/logs')
|
||||||
|
\ . ' --log-level=' . ale#Escape('info')
|
||||||
|
|
||||||
|
Execute(Project root should be detected using erlang_ls.config):
|
||||||
|
call ale#test#SetFilename(b:files . '/app_with_erlang_ls_config/src/app.erl')
|
||||||
|
AssertLSPProject ale#test#GetFilename(b:files . '/app_with_erlang_ls_config')
|
||||||
|
|
||||||
|
call ale#test#SetFilename(b:files . '/app_with_erlang_ls_config/_build/default/lib/dep/src/dep.erl')
|
||||||
|
AssertLSPProject ale#test#GetFilename(b:files . '/app_with_erlang_ls_config')
|
||||||
|
|
||||||
|
Execute(Root of Rebar3 project should be detected):
|
||||||
|
call ale#test#SetFilename(b:files . '/app/src/app.erl')
|
||||||
|
AssertLSPProject ale#test#GetFilename(b:files . '/app')
|
||||||
|
|
||||||
|
call ale#test#SetFilename(b:files . '/app/_build/default/lib/dep/src/dep.erl')
|
||||||
|
AssertLSPProject ale#test#GetFilename(b:files . '/app')
|
||||||
|
|
||||||
|
Execute(Root of kerl managed Erlang/OTP installation should be detected):
|
||||||
|
call ale#test#SetFilename(b:files . '/kerl_otp_root/lib/stdlib-4.1.1/array.erl')
|
||||||
|
AssertLSPProject ale#test#GetFilename(b:files . '/kerl_otp_root')
|
||||||
0
test/test-files/erlang/app/rebar.lock
Normal file
0
test/test-files/erlang/app/rebar.lock
Normal file
0
test/test-files/erlang/app/src/app.erl
Normal file
0
test/test-files/erlang/app/src/app.erl
Normal file
0
test/test-files/erlang/kerl_otp_root/.kerl_config
Normal file
0
test/test-files/erlang/kerl_otp_root/.kerl_config
Normal file
Reference in New Issue
Block a user