Add a lsp_config_callback linter option

This is the callback-based variant of the existing `lsp_config` linter
option. It serves the same purpose but can be used when more complicated
processing is needed.

`lsp_config` and `lsp_config_callback` are mutually exclusive options;
if both an given, a linter preprocessing error will be raised.

The runtime logic has been wrapped in `ale#lsp_linter#GetConfig` for
convenience, similar to `ale#lsp_linter#GetOptions`.

This also adds documentation and an `AssertLSPConfig` test function for
completeness.
This commit is contained in:
Jon Parise
2018-10-30 08:54:40 -07:00
parent 20e4e3f9db
commit b5a7593577
9 changed files with 85 additions and 7 deletions

View File

@@ -85,6 +85,14 @@ function! ale#assert#LSPOptions(expected_options) abort
AssertEqual a:expected_options, l:initialization_options
endfunction
function! ale#assert#LSPConfig(expected_config) abort
let l:buffer = bufnr('')
let l:linter = s:GetLinter()
let l:config = ale#lsp_linter#GetConfig(l:buffer, l:linter)
AssertEqual a:expected_config, l:config
endfunction
function! ale#assert#LSPLanguage(expected_language) abort
let l:buffer = bufnr('')
let l:linter = s:GetLinter()
@@ -147,6 +155,7 @@ function! ale#assert#SetUpLinterTest(filetype, name) abort
command! -nargs=+ AssertLinter :call ale#assert#Linter(<args>)
command! -nargs=0 AssertLinterNotExecuted :call ale#assert#LinterNotExecuted()
command! -nargs=+ AssertLSPOptions :call ale#assert#LSPOptions(<args>)
command! -nargs=+ AssertLSPConfig :call ale#assert#LSPConfig(<args>)
command! -nargs=+ AssertLSPLanguage :call ale#assert#LSPLanguage(<args>)
command! -nargs=+ AssertLSPProject :call ale#assert#LSPProject(<args>)
command! -nargs=+ AssertLSPAddress :call ale#assert#LSPAddress(<args>)
@@ -172,6 +181,10 @@ function! ale#assert#TearDownLinterTest() abort
delcommand AssertLSPOptions
endif
if exists(':AssertLSPConfig')
delcommand AssertLSPConfig
endif
if exists(':AssertLSPLanguage')
delcommand AssertLSPLanguage
endif

View File

@@ -257,7 +257,17 @@ function! ale#linter#PreProcess(filetype, linter) abort
let l:obj.initialization_options = a:linter.initialization_options
endif
if has_key(a:linter, 'lsp_config')
if has_key(a:linter, 'lsp_config_callback')
if has_key(a:linter, 'lsp_config')
throw 'Only one of `lsp_config` or `lsp_config_callback` should be set'
endif
let l:obj.lsp_config_callback = a:linter.lsp_config_callback
if !s:IsCallback(l:obj.lsp_config_callback)
throw '`lsp_config_callback` must be a callback if defined'
endif
elseif has_key(a:linter, 'lsp_config')
if type(a:linter.lsp_config) isnot v:t_dict
throw '`lsp_config` must be a Dictionary'
endif

View File

@@ -140,6 +140,18 @@ function! ale#lsp_linter#GetOptions(buffer, linter) abort
return l:initialization_options
endfunction
function! ale#lsp_linter#GetConfig(buffer, linter) abort
let l:config = {}
if has_key(a:linter, 'lsp_config_callback')
let l:config = ale#util#GetFunction(a:linter.lsp_config_callback)(a:buffer)
elseif has_key(a:linter, 'lsp_config')
let l:config = a:linter.lsp_config
endif
return l:config
endfunction
" Given a buffer, an LSP linter, start up an LSP linter and get ready to
" receive messages for the document.
function! ale#lsp_linter#StartLSP(buffer, linter) abort
@@ -188,14 +200,16 @@ function! ale#lsp_linter#StartLSP(buffer, linter) abort
call ale#lsp#MarkConnectionAsTsserver(l:conn_id)
endif
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer)
let l:config = ale#lsp_linter#GetConfig(a:buffer, a:linter)
if !empty(get(a:linter, 'lsp_config'))
if !empty(l:config)
" set LSP configuration options (workspace/didChangeConfiguration)
let l:config_message = ale#lsp#message#DidChangeConfiguration(a:buffer, a:linter.lsp_config)
let l:config_message = ale#lsp#message#DidChangeConfiguration(a:buffer, l:config)
call ale#lsp#Send(l:conn_id, l:config_message)
endif
let l:language_id = ale#util#GetFunction(a:linter.language_callback)(a:buffer)
let l:details = {
\ 'buffer': a:buffer,
\ 'connection_id': l:conn_id,