Close #1521 - Allow the language to be set with simple strings for LSP linters

This commit is contained in:
w0rp 2018-04-27 22:52:11 +01:00
parent d1d705cc84
commit 6ab3fdc4d0
No known key found for this signature in database
GPG Key ID: 0FC1ECAA8C81CD83
11 changed files with 65 additions and 45 deletions

View File

@ -7,10 +7,6 @@ function! ale_linters#dart#language_server#GetExecutable(buffer) abort
return ale#Var(a:buffer, 'dart_language_server_executable')
endfunction
function! ale_linters#dart#language_server#GetLanguage(buffer) abort
return 'dart'
endfunction
function! ale_linters#dart#language_server#GetProjectRoot(buffer) abort
" Note: pub only looks for pubspec.yaml, there's no point in adding
" support for pubspec.yml
@ -24,7 +20,6 @@ call ale#linter#Define('dart', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#dart#language_server#GetExecutable',
\ 'command_callback': 'ale_linters#dart#language_server#GetExecutable',
\ 'language_callback': 'ale_linters#dart#language_server#GetLanguage',
\ 'language': 'dart',
\ 'project_root_callback': 'ale_linters#dart#language_server#GetProjectRoot',
\})

View File

@ -18,10 +18,6 @@ function! ale_linters#glsl#glslls#GetCommand(buffer) abort
return ale#Escape(l:executable) . l:logfile_args . ' --stdin'
endfunction
function! ale_linters#glsl#glslls#GetLanguage(buffer) abort
return 'glsl'
endfunction
function! ale_linters#glsl#glslls#GetProjectRoot(buffer) abort
let l:project_root = ale#c#FindProjectRoot(a:buffer)
@ -33,6 +29,6 @@ call ale#linter#Define('glsl', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#glsl#glslls#GetExecutable',
\ 'command_callback': 'ale_linters#glsl#glslls#GetCommand',
\ 'language_callback': 'ale_linters#glsl#glslls#GetLanguage',
\ 'language': 'glsl',
\ 'project_root_callback': 'ale_linters#glsl#glslls#GetProjectRoot',
\})

View File

@ -14,10 +14,6 @@ function! ale_linters#php#langserver#GetCommand(buffer) abort
return 'php ' . ale#Escape(ale_linters#php#langserver#GetExecutable(a:buffer))
endfunction
function! ale_linters#php#langserver#GetLanguage(buffer) abort
return 'php'
endfunction
function! ale_linters#php#langserver#GetProjectRoot(buffer) abort
let l:git_path = ale#path#FindNearestDirectory(a:buffer, '.git')
@ -29,6 +25,6 @@ call ale#linter#Define('php', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#php#langserver#GetExecutable',
\ 'command_callback': 'ale_linters#php#langserver#GetCommand',
\ 'language_callback': 'ale_linters#php#langserver#GetLanguage',
\ 'language': 'php',
\ 'project_root_callback': 'ale_linters#php#langserver#GetProjectRoot',
\})

View File

@ -14,16 +14,12 @@ function! ale_linters#python#pyls#GetCommand(buffer) abort
return ale#Escape(l:executable)
endfunction
function! ale_linters#python#pyls#GetLanguage(buffer) abort
return 'python'
endfunction
call ale#linter#Define('python', {
\ 'name': 'pyls',
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#python#pyls#GetExecutable',
\ 'command_callback': 'ale_linters#python#pyls#GetCommand',
\ 'language_callback': 'ale_linters#python#pyls#GetLanguage',
\ 'language': 'python',
\ 'project_root_callback': 'ale#python#FindProjectRoot',
\ 'completion_filter': 'ale#completion#python#CompletionItemFilter',
\})

View File

@ -19,10 +19,6 @@ function! ale_linters#rust#rls#GetCommand(buffer) abort
endif
endfunction
function! ale_linters#rust#rls#GetLanguage(buffer) abort
return 'rust'
endfunction
function! ale_linters#rust#rls#GetProjectRoot(buffer) abort
let l:cargo_file = ale#path#FindNearestFile(a:buffer, 'Cargo.toml')
@ -34,6 +30,6 @@ call ale#linter#Define('rust', {
\ 'lsp': 'stdio',
\ 'executable_callback': 'ale_linters#rust#rls#GetExecutable',
\ 'command_callback': 'ale_linters#rust#rls#GetCommand',
\ 'language_callback': 'ale_linters#rust#rls#GetLanguage',
\ 'language': 'rust',
\ 'project_root_callback': 'ale_linters#rust#rls#GetProjectRoot',
\})

View File

@ -10,10 +10,6 @@ function! ale_linters#typescript#tsserver#GetProjectRoot(buffer) abort
return ''
endfunction
function! ale_linters#typescript#tsserver#GetLanguage(buffer) abort
return ''
endfunction
function! ale_linters#typescript#tsserver#GetExecutable(buffer) abort
return ale#node#FindExecutable(a:buffer, 'typescript_tsserver', [
\ 'node_modules/.bin/tsserver',
@ -26,5 +22,5 @@ call ale#linter#Define('typescript', {
\ 'executable_callback': 'ale_linters#typescript#tsserver#GetExecutable',
\ 'command_callback': 'ale_linters#typescript#tsserver#GetExecutable',
\ 'project_root_callback': 'ale_linters#typescript#tsserver#GetProjectRoot',
\ 'language_callback': 'ale_linters#typescript#tsserver#GetLanguage',
\ 'language': '',
\})

View File

@ -51,6 +51,10 @@ function! s:IsBoolean(value) abort
return type(a:value) == type(0) && (a:value == 0 || a:value == 1)
endfunction
function! s:LanguageGetter(buffer) dict abort
return l:self.language
endfunction
function! ale#linter#PreProcess(linter) abort
if type(a:linter) != type({})
throw 'The linter object must be a Dictionary'
@ -185,11 +189,27 @@ function! ale#linter#PreProcess(linter) abort
endif
if l:needs_lsp_details
if has_key(a:linter, 'language')
if has_key(a:linter, 'language_callback')
throw 'Only one of `language` or `language_callback` '
\ . 'should be set'
endif
let l:obj.language = get(a:linter, 'language')
if type(l:obj.language) != type('')
throw '`language` must be a string'
endif
" Make 'language_callback' return the 'language' value.
let l:obj.language_callback = function('s:LanguageGetter')
else
let l:obj.language_callback = get(a:linter, 'language_callback')
if !s:IsCallback(l:obj.language_callback)
throw '`language_callback` must be a callback for LSP linters'
endif
endif
let l:obj.project_root_callback = get(a:linter, 'project_root_callback')

View File

@ -2272,9 +2272,9 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
process for a language server runnning, and
communicates with it directly via a |channel|.
When this argument is not empty, then the
`project_callback` and `language_callback` arguments
must also be defined.
When this argument is not empty, `project_callback`
must be defined, and only one of either `language` or
`language_callback` must be defined.
LSP linters handle diagnostics automatically, so
the `callback` argument must not be defined.
@ -2289,13 +2289,20 @@ ale#linter#Define(filetype, linter) *ale#linter#Define()*
This argument must only be set if the `lsp` argument
is also set to a non-empty string.
`language` A |String| representing the name of the language
being checked. This string will be sent to the LSP to
tell it what type of language is being checked.
This argument must only be set if the `lsp` argument
is also set to a non-empty string.
`language_callback` A |String| or |Funcref| for a callback function
accepting a buffer number. A |String| should be
returned representing the name of the language being
checked.
This argument must only be set if the `lsp` argument
is also set to a non-empty string.
This option can be used instead of `language` if a
linter can check multiple languages.
`aliases` A |List| of aliases for the linter name.

View File

@ -42,9 +42,6 @@ Execute(Vendor executables should be detected):
\ )),
\ ale_linters#php#langserver#GetCommand(bufnr(''))
Execute(The language string should be correct):
AssertEqual 'php', ale_linters#php#langserver#GetLanguage(bufnr(''))
Execute(The project path should be correct for .git directories):
call ale#test#SetFilename('php-langserver-project/test.php')
call mkdir(g:dir . '/.git')

View File

@ -35,9 +35,6 @@ Execute(The toolchain should be ommitted if not given):
\ ale#Escape('rls'),
\ ale_linters#rust#rls#GetCommand(bufnr(''))
Execute(The language string should be correct):
AssertEqual 'rust', ale_linters#rust#rls#GetLanguage(bufnr(''))
Execute(The project root should be detected correctly):
AssertEqual '', ale_linters#rust#rls#GetProjectRoot(bufnr(''))

View File

@ -421,6 +421,30 @@ Execute(PreProcess should accept LSP server configurations):
AssertEqual 'socket', ale#linter#PreProcess(g:linter).lsp
Execute(PreProcess should accept let you specify the language as just a string):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'foobar',
\ 'project_root_callback': 'x',
\}
AssertEqual 'foobar', ale#linter#PreProcess(g:linter).language_callback(0)
Execute(PreProcess should complain about using language and language_callback together):
let g:linter = {
\ 'name': 'x',
\ 'lsp': 'socket',
\ 'address_callback': 'X',
\ 'language': 'x',
\ 'language_callback': 'x',
\ 'project_root_callback': 'x',
\}
AssertThrows call ale#linter#PreProcess(g:linter)
AssertEqual 'Only one of `language` or `language_callback` should be set', g:vader_exception
Execute(PreProcess should require an address_callback for LSP socket configurations):
let g:linter = {
\ 'name': 'x',