#2132 - Implement project_root as a replacement for project_root_callback
This commit is contained in:
parent
f8aeb5c5a4
commit
f53b25d256
4 changed files with 98 additions and 8 deletions
|
@ -242,10 +242,21 @@ function! ale#linter#PreProcess(filetype, linter) abort
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:obj.project_root_callback = get(a:linter, 'project_root_callback')
|
if has_key(a:linter, 'project_root')
|
||||||
|
let l:obj.project_root = a:linter.project_root
|
||||||
|
|
||||||
if !s:IsCallback(l:obj.project_root_callback)
|
if type(l:obj.project_root) isnot v:t_string
|
||||||
throw '`project_root_callback` must be a callback for LSP linters'
|
\&& type(l:obj.project_root) isnot v:t_func
|
||||||
|
throw '`project_root` must be a String or Function if defined'
|
||||||
|
endif
|
||||||
|
elseif has_key(a:linter, 'project_root_callback')
|
||||||
|
let l:obj.project_root_callback = a:linter.project_root_callback
|
||||||
|
|
||||||
|
if !s:IsCallback(l:obj.project_root_callback)
|
||||||
|
throw '`project_root_callback` must be a callback if defined'
|
||||||
|
endif
|
||||||
|
else
|
||||||
|
throw '`project_root` or `project_root_callback` must be defined for LSP linters'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if has_key(a:linter, 'completion_filter')
|
if has_key(a:linter, 'completion_filter')
|
||||||
|
|
|
@ -194,6 +194,12 @@ function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Fall back to the linter-specific configuration
|
" Fall back to the linter-specific configuration
|
||||||
|
if has_key(a:linter, 'project_root')
|
||||||
|
let l:Root = a:linter.project_root
|
||||||
|
|
||||||
|
return type(l:Root) is v:t_func ? l:Root(a:buffer) : l:Root
|
||||||
|
endif
|
||||||
|
|
||||||
return ale#util#GetFunction(a:linter.project_root_callback)(a:buffer)
|
return ale#util#GetFunction(a:linter.project_root_callback)(a:buffer)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
|
15
doc/ale.txt
15
doc/ale.txt
|
@ -3270,16 +3270,21 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
||||||
This argument must only be set if the `lsp` argument
|
This argument must only be set if the `lsp` argument
|
||||||
is set to `'socket'`.
|
is set to `'socket'`.
|
||||||
|
|
||||||
`project_root_callback` A |String| or |Funcref| for a callback function
|
`project_root` A |String| representing a path to the project for
|
||||||
accepting a buffer number. A |String| should be
|
the file being checked with the language server, or
|
||||||
returned representing the path to the project for the
|
a |Funcref| accepting a buffer number and returning
|
||||||
file being checked with the language server. If an
|
the |String|.
|
||||||
empty string is returned, the file will not be
|
|
||||||
|
If an empty string is returned, the file will not be
|
||||||
checked at all.
|
checked at all.
|
||||||
|
|
||||||
This argument must only be set if the `lsp` argument
|
This argument must only be set if the `lsp` argument
|
||||||
is also set to a non-empty string.
|
is also set to a non-empty string.
|
||||||
|
|
||||||
|
`project_root_callback` A |String| or |Funcref| for a callback function
|
||||||
|
accepting a buffer number and returning the
|
||||||
|
`project_root` |String| as documented above.
|
||||||
|
|
||||||
`language` A |String| representing the name of the language
|
`language` A |String| representing the name of the language
|
||||||
being checked, or a |Funcref| accepting a buffer
|
being checked, or a |Funcref| accepting a buffer
|
||||||
number and returning the |String|. This string will
|
number and returning the |String|. This string will
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
Before:
|
Before:
|
||||||
|
Save g:ale_lsp_root
|
||||||
|
Save b:ale_lsp_root
|
||||||
|
|
||||||
|
let g:ale_lsp_root = {}
|
||||||
|
unlet! b:ale_lsp_root
|
||||||
|
|
||||||
let g:linter = {}
|
let g:linter = {}
|
||||||
|
|
||||||
After:
|
After:
|
||||||
|
@ -558,6 +564,68 @@ Execute(PreProcess should complain about invalid address values):
|
||||||
\})
|
\})
|
||||||
AssertEqual '`address` must be a String or Function if defined', g:vader_exception
|
AssertEqual '`address` must be a String or Function if defined', g:vader_exception
|
||||||
|
|
||||||
|
Execute(PreProcess should accept allow the project root be set as a String):
|
||||||
|
let g:linter = ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': 'foo:123',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root': '/foo/bar',
|
||||||
|
\})
|
||||||
|
|
||||||
|
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
|
||||||
|
|
||||||
|
Execute(PreProcess should accept allow the project root be set as a Function):
|
||||||
|
let g:linter = ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': 'foo:123',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root': {-> '/foo/bar'},
|
||||||
|
\})
|
||||||
|
|
||||||
|
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
|
||||||
|
|
||||||
|
Execute(PreProcess should complain when the project_root valid is invalid):
|
||||||
|
AssertThrows call ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': 'foo:123',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root': 0,
|
||||||
|
\})
|
||||||
|
AssertEqual '`project_root` must be a String or Function if defined', g:vader_exception
|
||||||
|
|
||||||
|
Execute(PreProcess should accept project_root_callback as a String):
|
||||||
|
call ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': 'foo:123',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 'Foobar',
|
||||||
|
\})
|
||||||
|
|
||||||
|
Execute(PreProcess should accept project_root_callback as a Function):
|
||||||
|
let g:linter = ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': 'foo:123',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': {-> '/foo/bar'},
|
||||||
|
\})
|
||||||
|
|
||||||
|
AssertEqual '/foo/bar', ale#lsp_linter#FindProjectRoot(0, g:linter)
|
||||||
|
|
||||||
|
Execute(PreProcess should complain when the project_root_callback valid is invalid):
|
||||||
|
AssertThrows call ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': 'foo:123',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 0,
|
||||||
|
\})
|
||||||
|
AssertEqual '`project_root_callback` must be a callback if defined', g:vader_exception
|
||||||
|
|
||||||
Execute(PreProcess should complain about using initialization_options and initialization_options_callback together):
|
Execute(PreProcess should complain about using initialization_options and initialization_options_callback together):
|
||||||
let g:linter = {
|
let g:linter = {
|
||||||
\ 'name': 'x',
|
\ 'name': 'x',
|
||||||
|
|
Reference in a new issue