#2132 - Make most foo_callback options work as foo
This commit is contained in:
parent
ffa45fa3fb
commit
f8aeb5c5a4
@ -195,9 +195,16 @@ function! ale#linter#PreProcess(filetype, linter) abort
|
|||||||
endif
|
endif
|
||||||
|
|
||||||
if !l:needs_address
|
if !l:needs_address
|
||||||
if has_key(a:linter, 'address_callback')
|
if has_key(a:linter, 'address') || has_key(a:linter, 'address_callback')
|
||||||
throw '`address_callback` cannot be used when lsp != ''socket'''
|
throw '`address` or `address_callback` cannot be used when lsp != ''socket'''
|
||||||
endif
|
endif
|
||||||
|
elseif has_key(a:linter, 'address')
|
||||||
|
if type(a:linter.address) isnot v:t_string
|
||||||
|
\&& type(a:linter.address) isnot v:t_func
|
||||||
|
throw '`address` must be a String or Function if defined'
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:obj.address = a:linter.address
|
||||||
elseif has_key(a:linter, 'address_callback')
|
elseif has_key(a:linter, 'address_callback')
|
||||||
let l:obj.address_callback = a:linter.address_callback
|
let l:obj.address_callback = a:linter.address_callback
|
||||||
|
|
||||||
@ -205,7 +212,7 @@ function! ale#linter#PreProcess(filetype, linter) abort
|
|||||||
throw '`address_callback` must be a callback if defined'
|
throw '`address_callback` must be a callback if defined'
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
throw '`address_callback` must be defined for getting the LSP address'
|
throw '`address` or `address_callback` must be defined for getting the LSP address'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if l:needs_lsp_details
|
if l:needs_lsp_details
|
||||||
@ -222,14 +229,17 @@ function! ale#linter#PreProcess(filetype, linter) abort
|
|||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
" Default to using the filetype as the language.
|
" Default to using the filetype as the language.
|
||||||
let l:obj.language = get(a:linter, 'language', a:filetype)
|
let l:Language = get(a:linter, 'language', a:filetype)
|
||||||
|
|
||||||
if type(l:obj.language) isnot v:t_string
|
|
||||||
throw '`language` must be a string'
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
if type(l:Language) is v:t_string
|
||||||
" Make 'language_callback' return the 'language' value.
|
" Make 'language_callback' return the 'language' value.
|
||||||
|
let l:obj.language = l:Language
|
||||||
let l:obj.language_callback = function('s:LanguageGetter')
|
let l:obj.language_callback = function('s:LanguageGetter')
|
||||||
|
elseif type(l:Language) is v:t_func
|
||||||
|
let l:obj.language_callback = l:Language
|
||||||
|
else
|
||||||
|
throw '`language` must be a String or Funcref'
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:obj.project_root_callback = get(a:linter, 'project_root_callback')
|
let l:obj.project_root_callback = get(a:linter, 'project_root_callback')
|
||||||
@ -259,6 +269,11 @@ function! ale#linter#PreProcess(filetype, linter) abort
|
|||||||
endif
|
endif
|
||||||
elseif has_key(a:linter, 'initialization_options')
|
elseif has_key(a:linter, 'initialization_options')
|
||||||
let l:obj.initialization_options = a:linter.initialization_options
|
let l:obj.initialization_options = a:linter.initialization_options
|
||||||
|
|
||||||
|
if type(l:obj.initialization_options) isnot v:t_dict
|
||||||
|
\&& type(l:obj.initialization_options) isnot v:t_func
|
||||||
|
throw '`initialization_options` must be a String or Function if defined'
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if has_key(a:linter, 'lsp_config_callback')
|
if has_key(a:linter, 'lsp_config_callback')
|
||||||
@ -273,7 +288,8 @@ function! ale#linter#PreProcess(filetype, linter) abort
|
|||||||
endif
|
endif
|
||||||
elseif has_key(a:linter, 'lsp_config')
|
elseif has_key(a:linter, 'lsp_config')
|
||||||
if type(a:linter.lsp_config) isnot v:t_dict
|
if type(a:linter.lsp_config) isnot v:t_dict
|
||||||
throw '`lsp_config` must be a Dictionary'
|
\&& type(a:linter.lsp_config) isnot v:t_func
|
||||||
|
throw '`lsp_config` must be a Dictionary or Function if defined'
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let l:obj.lsp_config = a:linter.lsp_config
|
let l:obj.lsp_config = a:linter.lsp_config
|
||||||
@ -501,7 +517,11 @@ endfunction
|
|||||||
|
|
||||||
" Given a buffer and linter, get the address for connecting to the server.
|
" Given a buffer and linter, get the address for connecting to the server.
|
||||||
function! ale#linter#GetAddress(buffer, linter) abort
|
function! ale#linter#GetAddress(buffer, linter) abort
|
||||||
return has_key(a:linter, 'address_callback')
|
let l:Address = has_key(a:linter, 'address_callback')
|
||||||
\ ? ale#util#GetFunction(a:linter.address_callback)(a:buffer)
|
\ ? function(a:linter.address_callback)
|
||||||
\ : a:linter.address
|
\ : a:linter.address
|
||||||
|
|
||||||
|
return type(l:Address) is v:t_func
|
||||||
|
\ ? l:Address(a:buffer)
|
||||||
|
\ : l:Address
|
||||||
endfunction
|
endfunction
|
||||||
|
@ -129,27 +129,39 @@ function! ale#lsp_linter#HandleLSPResponse(conn_id, response) abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp_linter#GetOptions(buffer, linter) abort
|
function! ale#lsp_linter#GetOptions(buffer, linter) abort
|
||||||
let l:initialization_options = {}
|
|
||||||
|
|
||||||
if has_key(a:linter, 'initialization_options_callback')
|
if has_key(a:linter, 'initialization_options_callback')
|
||||||
let l:initialization_options = ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer)
|
return ale#util#GetFunction(a:linter.initialization_options_callback)(a:buffer)
|
||||||
elseif has_key(a:linter, 'initialization_options')
|
|
||||||
let l:initialization_options = a:linter.initialization_options
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
return l:initialization_options
|
if has_key(a:linter, 'initialization_options')
|
||||||
|
let l:Options = a:linter.initialization_options
|
||||||
|
|
||||||
|
if type(l:Options) is v:t_func
|
||||||
|
let l:Options = l:Options(a:buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:Options
|
||||||
|
endif
|
||||||
|
|
||||||
|
return {}
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp_linter#GetConfig(buffer, linter) abort
|
function! ale#lsp_linter#GetConfig(buffer, linter) abort
|
||||||
let l:config = {}
|
|
||||||
|
|
||||||
if has_key(a:linter, 'lsp_config_callback')
|
if has_key(a:linter, 'lsp_config_callback')
|
||||||
let l:config = ale#util#GetFunction(a:linter.lsp_config_callback)(a:buffer)
|
return 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
|
endif
|
||||||
|
|
||||||
return l:config
|
if has_key(a:linter, 'lsp_config')
|
||||||
|
let l:Config = a:linter.lsp_config
|
||||||
|
|
||||||
|
if type(l:Config) is v:t_func
|
||||||
|
let l:Config = l:Config(a:buffer)
|
||||||
|
endif
|
||||||
|
|
||||||
|
return l:Config
|
||||||
|
endif
|
||||||
|
|
||||||
|
return {}
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
|
function! ale#lsp_linter#FindProjectRoot(buffer, linter) abort
|
||||||
|
28
doc/ale.txt
28
doc/ale.txt
@ -3231,8 +3231,9 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
|
|
||||||
When this argument is set to `'socket'`, then the
|
When this argument is set to `'socket'`, then the
|
||||||
linter will be defined as an LSP linter via a TCP
|
linter will be defined as an LSP linter via a TCP
|
||||||
socket connection. `address_callback` must be set
|
socket connection. Either `address` or
|
||||||
with a callback returning an address to connect to.
|
`address_callback` must be set.
|
||||||
|
|
||||||
ALE will not start a server automatically.
|
ALE will not start a server automatically.
|
||||||
|
|
||||||
When this argument is not empty
|
When this argument is not empty
|
||||||
@ -3255,6 +3256,13 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
An optional `lsp_config` or `lsp_config_callback` may
|
An optional `lsp_config` or `lsp_config_callback` may
|
||||||
be defined to pass configuration settings to the LSP.
|
be defined to pass configuration settings to the LSP.
|
||||||
|
|
||||||
|
`address` A |String| representing an address to connect to,
|
||||||
|
or a |Funcref| accepting a buffer number and
|
||||||
|
returning the |String|.
|
||||||
|
|
||||||
|
This argument must only be set if the `lsp` argument
|
||||||
|
is set to `'socket'`.
|
||||||
|
|
||||||
`address_callback` A |String| or |Funcref| for a callback function
|
`address_callback` A |String| or |Funcref| for a callback function
|
||||||
accepting a buffer number. A |String| should be
|
accepting a buffer number. A |String| should be
|
||||||
returned with an address to connect to.
|
returned with an address to connect to.
|
||||||
@ -3273,8 +3281,10 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
is also set to a non-empty string.
|
is also set to a non-empty string.
|
||||||
|
|
||||||
`language` A |String| representing the name of the language
|
`language` A |String| representing the name of the language
|
||||||
being checked. This string will be sent to the LSP to
|
being checked, or a |Funcref| accepting a buffer
|
||||||
tell it what type of language is being checked.
|
number and returning the |String|. This string will
|
||||||
|
be sent to the LSP to tell it what type of language
|
||||||
|
is being checked.
|
||||||
|
|
||||||
If this or `language_callback` isn't set, the
|
If this or `language_callback` isn't set, the
|
||||||
language will default to the value of the filetype
|
language will default to the value of the filetype
|
||||||
@ -3304,7 +3314,10 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
setting can make it easier to guess the linter name
|
setting can make it easier to guess the linter name
|
||||||
by offering a few alternatives.
|
by offering a few alternatives.
|
||||||
|
|
||||||
`initialization_options` A |Dictionary| of initialization options for LSPs.
|
`initialization_options` A |Dictionary| of initialization options for LSPs,
|
||||||
|
or a |Funcref| for a callback function accepting
|
||||||
|
a buffer number and returning the |Dictionary|.
|
||||||
|
|
||||||
This will be fed (as JSON) to the LSP in the
|
This will be fed (as JSON) to the LSP in the
|
||||||
initialize command.
|
initialize command.
|
||||||
|
|
||||||
@ -3315,7 +3328,10 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
|
|||||||
This can be used in place of `initialization_options`
|
This can be used in place of `initialization_options`
|
||||||
when more complicated processing is needed.
|
when more complicated processing is needed.
|
||||||
|
|
||||||
`lsp_config` A |Dictionary| of configuration settings for LSPs.
|
`lsp_config` A |Dictionary| for configuring a language server,
|
||||||
|
or a |Funcref| for a callback function accepting
|
||||||
|
a buffer number and returning the |Dictionary|.
|
||||||
|
|
||||||
This will be fed (as JSON) to the LSP in the
|
This will be fed (as JSON) to the LSP in the
|
||||||
workspace/didChangeConfiguration command.
|
workspace/didChangeConfiguration command.
|
||||||
|
|
||||||
|
@ -461,6 +461,18 @@ Execute(PreProcess should complain about using language and language_callback to
|
|||||||
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
||||||
AssertEqual 'Only one of `language` or `language_callback` should be set', g:vader_exception
|
AssertEqual 'Only one of `language` or `language_callback` should be set', g:vader_exception
|
||||||
|
|
||||||
|
Execute(PreProcess should complain about invalid language values):
|
||||||
|
let g:linter = {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address_callback': 'X',
|
||||||
|
\ 'language': 0,
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\}
|
||||||
|
|
||||||
|
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
||||||
|
AssertEqual '`language` must be a String or Funcref', g:vader_exception
|
||||||
|
|
||||||
Execute(PreProcess should use the filetype as the language string by default):
|
Execute(PreProcess should use the filetype as the language string by default):
|
||||||
let g:linter = {
|
let g:linter = {
|
||||||
\ 'name': 'x',
|
\ 'name': 'x',
|
||||||
@ -471,6 +483,17 @@ Execute(PreProcess should use the filetype as the language string by default):
|
|||||||
|
|
||||||
AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language_callback(0)
|
AssertEqual 'testft', ale#linter#PreProcess('testft', g:linter).language_callback(0)
|
||||||
|
|
||||||
|
Execute(PreProcess should allow language to be set to a callback):
|
||||||
|
let g:linter = {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address_callback': 'X',
|
||||||
|
\ 'language': {-> 'foo'},
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\}
|
||||||
|
|
||||||
|
AssertEqual 'foo', ale#linter#PreProcess('testft', g:linter).language_callback(0)
|
||||||
|
|
||||||
Execute(PreProcess should require an address_callback for LSP socket configurations):
|
Execute(PreProcess should require an address_callback for LSP socket configurations):
|
||||||
let g:linter = {
|
let g:linter = {
|
||||||
\ 'name': 'x',
|
\ 'name': 'x',
|
||||||
@ -478,7 +501,7 @@ Execute(PreProcess should require an address_callback for LSP socket configurati
|
|||||||
\}
|
\}
|
||||||
|
|
||||||
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
||||||
AssertEqual '`address_callback` must be defined for getting the LSP address', g:vader_exception
|
AssertEqual '`address` or `address_callback` must be defined for getting the LSP address', g:vader_exception
|
||||||
|
|
||||||
Execute(PreProcess should complain about address_callback for non-LSP linters):
|
Execute(PreProcess should complain about address_callback for non-LSP linters):
|
||||||
let g:linter = {
|
let g:linter = {
|
||||||
@ -490,7 +513,50 @@ Execute(PreProcess should complain about address_callback for non-LSP linters):
|
|||||||
\}
|
\}
|
||||||
|
|
||||||
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
AssertThrows call ale#linter#PreProcess('testft', g:linter)
|
||||||
AssertEqual '`address_callback` cannot be used when lsp != ''socket''', g:vader_exception
|
AssertEqual '`address` or `address_callback` cannot be used when lsp != ''socket''', g:vader_exception
|
||||||
|
|
||||||
|
Execute(PreProcess accept valid address_callback values):
|
||||||
|
let g:linter = ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address_callback': {-> 'foo:123'},
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\})
|
||||||
|
|
||||||
|
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
|
||||||
|
|
||||||
|
Execute(PreProcess accept address as a String):
|
||||||
|
let g:linter = ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': 'foo:123',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\})
|
||||||
|
|
||||||
|
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
|
||||||
|
|
||||||
|
Execute(PreProcess accept address as a Function):
|
||||||
|
let g:linter = ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': {-> 'foo:123'},
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\})
|
||||||
|
|
||||||
|
AssertEqual 'foo:123', ale#linter#GetAddress(0, g:linter)
|
||||||
|
|
||||||
|
Execute(PreProcess should complain about invalid address values):
|
||||||
|
AssertThrows call ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address': 0,
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\})
|
||||||
|
AssertEqual '`address` must be a String or Function 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 = {
|
||||||
@ -517,6 +583,41 @@ Execute(PreProcess should throw when initialization_options_callback is not a ca
|
|||||||
\})
|
\})
|
||||||
AssertEqual '`initialization_options_callback` must be a callback if defined', g:vader_exception
|
AssertEqual '`initialization_options_callback` must be a callback if defined', g:vader_exception
|
||||||
|
|
||||||
|
Execute(PreProcess should throw when initialization_options is not a Dictionary or callback):
|
||||||
|
AssertThrows call ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'foo',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address_callback': 'X',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\ 'initialization_options': 0,
|
||||||
|
\})
|
||||||
|
AssertEqual '`initialization_options` must be a String or Function if defined', g:vader_exception
|
||||||
|
|
||||||
|
Execute(PreProcess should accept initialization_options as a Dictionary):
|
||||||
|
let g:linter = ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'foo',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address_callback': 'X',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\ 'initialization_options': {'foo': v:true},
|
||||||
|
\})
|
||||||
|
|
||||||
|
AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter)
|
||||||
|
|
||||||
|
Execute(PreProcess should accept initialization_options as a Funcref):
|
||||||
|
let g:linter = ale#linter#PreProcess('testft', {
|
||||||
|
\ 'name': 'foo',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address_callback': 'X',
|
||||||
|
\ 'language': 'x',
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\ 'initialization_options': {-> {'foo': v:true}},
|
||||||
|
\})
|
||||||
|
|
||||||
|
AssertEqual {'foo': v:true}, ale#lsp_linter#GetOptions(0, g:linter)
|
||||||
|
|
||||||
Execute(PreProcess should complain about using lsp_config and lsp_config_callback together):
|
Execute(PreProcess should complain about using lsp_config and lsp_config_callback together):
|
||||||
let g:linter = {
|
let g:linter = {
|
||||||
\ 'name': 'x',
|
\ 'name': 'x',
|
||||||
@ -543,22 +644,30 @@ Execute(PreProcess should throw when lsp_config_callback is not a callback):
|
|||||||
AssertEqual '`lsp_config_callback` must be a callback if defined', g:vader_exception
|
AssertEqual '`lsp_config_callback` must be a callback if defined', g:vader_exception
|
||||||
|
|
||||||
Execute(PreProcess should accept LSP configuration options via lsp_config):
|
Execute(PreProcess should accept LSP configuration options via lsp_config):
|
||||||
let g:ale_lsp_configuration = {
|
|
||||||
\ 'foo': 'bar'
|
|
||||||
\}
|
|
||||||
|
|
||||||
let g:linter = {
|
let g:linter = {
|
||||||
\ 'name': 'x',
|
\ 'name': 'x',
|
||||||
\ 'lsp': 'socket',
|
\ 'lsp': 'socket',
|
||||||
\ 'address_callback': 'X',
|
\ 'address_callback': 'X',
|
||||||
\ 'language_callback': 'x',
|
\ 'language_callback': 'x',
|
||||||
\ 'project_root_callback': 'x',
|
\ 'project_root_callback': 'x',
|
||||||
\ 'lsp_config': g:ale_lsp_configuration,
|
\ 'lsp_config': {'foo': 'bar'},
|
||||||
\}
|
\}
|
||||||
|
|
||||||
AssertEqual {'foo': 'bar'}, ale#linter#PreProcess('testft', g:linter).lsp_config
|
AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter)
|
||||||
|
|
||||||
Execute(PreProcess should throw when lsp_config is not a Dictionary):
|
Execute(PreProcess should accept LSP configuration options via lsp_config as a function):
|
||||||
|
let g:linter = {
|
||||||
|
\ 'name': 'x',
|
||||||
|
\ 'lsp': 'socket',
|
||||||
|
\ 'address_callback': 'X',
|
||||||
|
\ 'language_callback': 'x',
|
||||||
|
\ 'project_root_callback': 'x',
|
||||||
|
\ 'lsp_config': {-> {'foo': 'bar'}},
|
||||||
|
\}
|
||||||
|
|
||||||
|
AssertEqual {'foo': 'bar'}, ale#lsp_linter#GetConfig(0, g:linter)
|
||||||
|
|
||||||
|
Execute(PreProcess should throw when lsp_config is not a Dictionary or Function):
|
||||||
AssertThrows call ale#linter#PreProcess('testft', {
|
AssertThrows call ale#linter#PreProcess('testft', {
|
||||||
\ 'name': 'foo',
|
\ 'name': 'foo',
|
||||||
\ 'lsp': 'socket',
|
\ 'lsp': 'socket',
|
||||||
@ -567,4 +676,4 @@ Execute(PreProcess should throw when lsp_config is not a Dictionary):
|
|||||||
\ 'project_root_callback': 'x',
|
\ 'project_root_callback': 'x',
|
||||||
\ 'lsp_config': 'x',
|
\ 'lsp_config': 'x',
|
||||||
\})
|
\})
|
||||||
AssertEqual '`lsp_config` must be a Dictionary', g:vader_exception
|
AssertEqual '`lsp_config` must be a Dictionary or Function if defined', g:vader_exception
|
||||||
|
Loading…
Reference in New Issue
Block a user