Add a command for stopping all LSP clients
This commit is contained in:
parent
b7363bef7d
commit
0a0535546f
@ -19,6 +19,10 @@ function! ale#definition#Execute(expr) abort
|
|||||||
execute a:expr
|
execute a:expr
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! ale#definition#ClearLSPData() abort
|
||||||
|
let s:go_to_definition_map = {}
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! ale#definition#Open(options, filename, line, column) abort
|
function! ale#definition#Open(options, filename, line, column) abort
|
||||||
if a:options.open_in_tab
|
if a:options.open_in_tab
|
||||||
call ale#definition#Execute('tabedit ' . fnameescape(a:filename))
|
call ale#definition#Execute('tabedit ' . fnameescape(a:filename))
|
||||||
|
@ -76,6 +76,11 @@ function! ale#engine#InitBufferInfo(buffer) abort
|
|||||||
return 0
|
return 0
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Clear LSP linter data for the linting engine.
|
||||||
|
function! ale#engine#ClearLSPData() abort
|
||||||
|
let s:lsp_linter_map = {}
|
||||||
|
endfunction
|
||||||
|
|
||||||
" This function is documented and part of the public API.
|
" This function is documented and part of the public API.
|
||||||
"
|
"
|
||||||
" Return 1 if ALE is busy checking a given buffer
|
" Return 1 if ALE is busy checking a given buffer
|
||||||
@ -144,7 +149,7 @@ function! s:GatherOutput(job_id, line) abort
|
|||||||
endif
|
endif
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleLoclist(linter_name, buffer, loclist) abort
|
function! ale#engine#HandleLoclist(linter_name, buffer, loclist) abort
|
||||||
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
let l:info = get(g:ale_buffer_info, a:buffer, {})
|
||||||
|
|
||||||
if empty(l:info)
|
if empty(l:info)
|
||||||
@ -223,7 +228,7 @@ function! s:HandleExit(job_id, exit_code) abort
|
|||||||
|
|
||||||
let l:loclist = ale#util#GetFunction(l:linter.callback)(l:buffer, l:output)
|
let l:loclist = ale#util#GetFunction(l:linter.callback)(l:buffer, l:output)
|
||||||
|
|
||||||
call s:HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
call ale#engine#HandleLoclist(l:linter.name, l:buffer, l:loclist)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
function! s:HandleLSPDiagnostics(conn_id, response) abort
|
||||||
@ -237,7 +242,7 @@ function! s:HandleLSPDiagnostics(conn_id, response) abort
|
|||||||
|
|
||||||
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
|
let l:loclist = ale#lsp#response#ReadDiagnostics(a:response)
|
||||||
|
|
||||||
call s:HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
call ale#engine#HandleLoclist(l:linter_name, l:buffer, l:loclist)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
function! s:HandleTSServerDiagnostics(response, error_type) abort
|
||||||
@ -262,7 +267,7 @@ function! s:HandleTSServerDiagnostics(response, error_type) abort
|
|||||||
let l:loclist = get(l:info, 'semantic_loclist', [])
|
let l:loclist = get(l:info, 'semantic_loclist', [])
|
||||||
\ + get(l:info, 'syntax_loclist', [])
|
\ + get(l:info, 'syntax_loclist', [])
|
||||||
|
|
||||||
call s:HandleLoclist('tsserver', l:buffer, l:loclist)
|
call ale#engine#HandleLoclist('tsserver', l:buffer, l:loclist)
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
function! s:HandleLSPErrorMessage(error_message) abort
|
function! s:HandleLSPErrorMessage(error_message) abort
|
||||||
|
@ -325,6 +325,20 @@ function! ale#lsp#ConnectToAddress(address, project_root, callback) abort
|
|||||||
return 1
|
return 1
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
" Stop all LSP connections, closing all jobs and channels, and removing any
|
||||||
|
" queued messages.
|
||||||
|
function! ale#lsp#StopAll() abort
|
||||||
|
for l:conn in s:connections
|
||||||
|
if has_key(l:conn, 'channel')
|
||||||
|
call ch_close(l:conn.channel)
|
||||||
|
else
|
||||||
|
call ale#job#Stop(l:conn.id)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
let s:connections = []
|
||||||
|
endfunction
|
||||||
|
|
||||||
function! s:SendMessageData(conn, data) abort
|
function! s:SendMessageData(conn, data) abort
|
||||||
if has_key(a:conn, 'executable')
|
if has_key(a:conn, 'executable')
|
||||||
call ale#job#SendRaw(a:conn.id, a:data)
|
call ale#job#SendRaw(a:conn.id, a:data)
|
||||||
|
25
autoload/ale/lsp/reset.vim
Normal file
25
autoload/ale/lsp/reset.vim
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
" Stop all LSPs and remove all of the data for them.
|
||||||
|
function! ale#lsp#reset#StopAllLSPs() abort
|
||||||
|
call ale#lsp#StopAll()
|
||||||
|
|
||||||
|
if exists('*ale#definition#ClearLSPData')
|
||||||
|
" Clear the mapping for connections, etc.
|
||||||
|
call ale#definition#ClearLSPData()
|
||||||
|
endif
|
||||||
|
|
||||||
|
if exists('*ale#engine#ClearLSPData')
|
||||||
|
" Clear the mapping for connections, etc.
|
||||||
|
call ale#engine#ClearLSPData()
|
||||||
|
|
||||||
|
" Remove the problems for all of the LSP linters in every buffer.
|
||||||
|
for l:buffer_string in keys(g:ale_buffer_info)
|
||||||
|
let l:buffer = str2nr(l:buffer_string)
|
||||||
|
|
||||||
|
for l:linter in ale#linter#Get(getbufvar(l:buffer, '&filetype'))
|
||||||
|
if !empty(l:linter.lsp)
|
||||||
|
call ale#engine#HandleLoclist(l:linter.name, l:buffer, [])
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
endif
|
||||||
|
endfunction
|
@ -1871,6 +1871,15 @@ ALEResetBuffer *ALEResetBuffer*
|
|||||||
|ALEDisableBuffer|.
|
|ALEDisableBuffer|.
|
||||||
|
|
||||||
|
|
||||||
|
ALEStopAllLSPs *ALEStopAllLSPs*
|
||||||
|
|
||||||
|
`ALEStopAllLSPs` will close and stop all channels and jobs for all LSP-like
|
||||||
|
clients, including tsserver, remove all of the data stored for them, and
|
||||||
|
delete all of the problems found for them, updating every linted buffer.
|
||||||
|
|
||||||
|
This command can be used when LSP clients mess up and need to be restarted.
|
||||||
|
|
||||||
|
|
||||||
===============================================================================
|
===============================================================================
|
||||||
9. API *ale-api*
|
9. API *ale-api*
|
||||||
|
|
||||||
|
@ -249,6 +249,8 @@ command! -bar ALEToggleBuffer :call ale#toggle#ToggleBuffer(bufnr(''))
|
|||||||
command! -bar ALEEnableBuffer :call ale#toggle#EnableBuffer(bufnr(''))
|
command! -bar ALEEnableBuffer :call ale#toggle#EnableBuffer(bufnr(''))
|
||||||
command! -bar ALEDisableBuffer :call ale#toggle#DisableBuffer(bufnr(''))
|
command! -bar ALEDisableBuffer :call ale#toggle#DisableBuffer(bufnr(''))
|
||||||
command! -bar ALEResetBuffer :call ale#toggle#ResetBuffer(bufnr(''))
|
command! -bar ALEResetBuffer :call ale#toggle#ResetBuffer(bufnr(''))
|
||||||
|
" A command to stop all LSP-like clients, including tsserver.
|
||||||
|
command! -bar ALEStopAllLSPs :call ale#lsp#reset#StopAllLSPs()
|
||||||
|
|
||||||
" A command for linting manually.
|
" A command for linting manually.
|
||||||
command! -bar ALELint :call ale#Queue(0, 'lint_file')
|
command! -bar ALELint :call ale#Queue(0, 'lint_file')
|
||||||
|
90
test/lsp/test_reset_lsp.vader
Normal file
90
test/lsp/test_reset_lsp.vader
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
Before:
|
||||||
|
Save g:ale_enabled
|
||||||
|
Save g:ale_set_signs
|
||||||
|
Save g:ale_set_quickfix
|
||||||
|
Save g:ale_set_loclist
|
||||||
|
Save g:ale_set_highlights
|
||||||
|
Save g:ale_echo_cursor
|
||||||
|
|
||||||
|
let g:ale_enabled = 0
|
||||||
|
let g:ale_set_signs = 0
|
||||||
|
let g:ale_set_quickfix = 0
|
||||||
|
let g:ale_set_loclist = 0
|
||||||
|
let g:ale_set_highlights = 0
|
||||||
|
let g:ale_echo_cursor = 0
|
||||||
|
|
||||||
|
function EmptyString() abort
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
call ale#engine#InitBufferInfo(bufnr(''))
|
||||||
|
|
||||||
|
call ale#linter#Define('testft', {
|
||||||
|
\ 'name': 'lsplinter',
|
||||||
|
\ 'lsp': 'tsserver',
|
||||||
|
\ 'executable_callback': 'EmptyString',
|
||||||
|
\ 'command_callback': 'EmptyString',
|
||||||
|
\ 'project_root_callback': 'EmptyString',
|
||||||
|
\ 'language_callback': 'EmptyString',
|
||||||
|
\})
|
||||||
|
|
||||||
|
call ale#linter#Define('testft', {
|
||||||
|
\ 'name': 'otherlinter',
|
||||||
|
\ 'callback': 'TestCallback',
|
||||||
|
\ 'executable': has('win32') ? 'cmd': 'true',
|
||||||
|
\ 'command': 'true',
|
||||||
|
\ 'read_buffer': 0,
|
||||||
|
\})
|
||||||
|
|
||||||
|
After:
|
||||||
|
Restore
|
||||||
|
|
||||||
|
unlet! b:ale_save_event_fired
|
||||||
|
|
||||||
|
delfunction EmptyString
|
||||||
|
call ale#linter#Reset()
|
||||||
|
|
||||||
|
Given testft(Some file with an imaginary filetype):
|
||||||
|
Execute(ALEStopAllLSPs should clear the loclist):
|
||||||
|
let g:ale_buffer_info[bufnr('')].loclist = [
|
||||||
|
\ {
|
||||||
|
\ 'text': 'a',
|
||||||
|
\ 'lnum': 10,
|
||||||
|
\ 'col': 0,
|
||||||
|
\ 'bufnr': bufnr(''),
|
||||||
|
\ 'vcol': 0,
|
||||||
|
\ 'type': 'E',
|
||||||
|
\ 'nr': -1,
|
||||||
|
\ 'linter_name': 'lsplinter',
|
||||||
|
\ },
|
||||||
|
\ {
|
||||||
|
\ 'text': 'a',
|
||||||
|
\ 'lnum': 10,
|
||||||
|
\ 'col': 0,
|
||||||
|
\ 'bufnr': bufnr(''),
|
||||||
|
\ 'vcol': 0,
|
||||||
|
\ 'type': 'E',
|
||||||
|
\ 'nr': -1,
|
||||||
|
\ 'linter_name': 'otherlinter',
|
||||||
|
\ },
|
||||||
|
\]
|
||||||
|
let g:ale_buffer_info[bufnr('')].active_linter_list = ['lsplinter', 'otherlinter']
|
||||||
|
|
||||||
|
ALEStopAllLSPs
|
||||||
|
|
||||||
|
" The loclist should be updated.
|
||||||
|
AssertEqual g:ale_buffer_info[bufnr('')].loclist, [
|
||||||
|
\ {
|
||||||
|
\ 'text': 'a',
|
||||||
|
\ 'lnum': 10,
|
||||||
|
\ 'col': 0,
|
||||||
|
\ 'bufnr': bufnr(''),
|
||||||
|
\ 'vcol': 0,
|
||||||
|
\ 'type': 'E',
|
||||||
|
\ 'nr': -1,
|
||||||
|
\ 'linter_name': 'otherlinter',
|
||||||
|
\ },
|
||||||
|
\]
|
||||||
|
|
||||||
|
" The LSP linter should be removed from the active linter list.
|
||||||
|
AssertEqual g:ale_buffer_info[bufnr('')].active_linter_list, ['otherlinter']
|
Loading…
Reference in New Issue
Block a user