#2132 - Implement project_root as a replacement for project_root_callback

This commit is contained in:
w0rp 2019-02-22 15:24:34 +00:00
parent f8aeb5c5a4
commit f53b25d256
No known key found for this signature in database
GPG key ID: 0FC1ECAA8C81CD83
4 changed files with 98 additions and 8 deletions

View file

@ -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')

View file

@ -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

View file

@ -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

View file

@ -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',