Skip to content

Commit

Permalink
LspStopServer: Stop all and stop specific
Browse files Browse the repository at this point in the history
It is convenient to be able to stop all LSP servers, regardless of the
currently active buffer.

Also, it seems confusing that when a server name is specified, it is
only stopped if it is also one handling the current buffer type.  I
would imagine it is quite rare to have more than one server handing a
specific buffer type.  And if one explicitly specified a name, it seems
reasonable to stop this particular server, regardless of the currently
active buffer.
  • Loading branch information
ilya-bobyr committed Sep 8, 2023
1 parent d802909 commit 92ebd4a
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 14 deletions.
24 changes: 24 additions & 0 deletions autoload/lsp.vim
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ function! lsp#get_server_names() abort
return keys(s:servers)
endfunction

function! lsp#is_valid_server_name(name) abort
return has_key(s:servers, a:name)
endfunction

function! lsp#get_server_info(server_name) abort
return get(get(s:servers, a:server_name, {}), 'server_info', {})
endfunction
Expand Down Expand Up @@ -128,6 +132,19 @@ function! s:server_status(server_name) abort
return 'not running'
endfunction

function! lsp#is_server_running(name) abort
if !has_key(s:servers, a:name)
return 0
endif

let l:server = s:servers[a:name]

return has_key(l:server, 'init_result')
\ && !has_key(l:server, 'exited')
\ && !has_key(l:server, 'init_callbacks')
\ && !has_key(l:server, 'failed')
endfunction

" Returns the current status of all servers (if called with no arguments) or
" the given server (if given an argument). Can be one of "unknown server",
" "exited", "starting", "failed", "running", "not running"
Expand Down Expand Up @@ -1329,6 +1346,13 @@ function! lsp#server_complete(lead, line, pos) abort
return filter(sort(keys(s:servers)), 'stridx(v:val, a:lead)==0 && has_key(s:servers[v:val], "init_result")')
endfunction

function! lsp#server_complete_running(lead, line, pos) abort
let l:all_servers = sort(keys(s:servers))
return filter(l:all_servers, {idx, name ->
\ stridx(name, a:lead) == 0 && lsp#is_server_running(name)
\ })
endfunction

function! lsp#_new_command() abort
let s:last_command_id += 1
call lsp#stream(1, { 'command': 1 })
Expand Down
69 changes: 65 additions & 4 deletions autoload/lsp/ui/vim.vim
Original file line number Diff line number Diff line change
Expand Up @@ -127,17 +127,78 @@ function! lsp#ui#vim#rename() abort
call s:rename(l:server, input('new name: ', expand('<cword>')), lsp#get_position())
endfunction

function! lsp#ui#vim#stop_server(...) abort
let l:name = get(a:000, 0, '')
for l:server in lsp#get_allowed_servers()
if !empty(l:name) && l:server != l:name
function! s:stop_all_servers() abort
for l:server in lsp#get_server_names()
if !lsp#is_server_running(l:server)
continue
endif

echo 'Stopping' l:server 'server ...'
call lsp#stop_server(l:server)
endfor
endfunction

function! s:stop_named_server(name) abort
if !lsp#is_valid_server_name(a:name)
call lsp#utils#warning('No LSP servers named "' . a:name . '"')
return
endif

if lsp#is_server_running(a:name)
echo 'Stopping "' . a:name . '" server...'
call lsp#stop_server(a:name)
else
call lsp#utils#warning(
\ 'Server "' . a:name . '" is not running: '
\ . lsp#get_server_status(a:name)
\ )
endif
endfunction

function! s:stop_buffer_servers() abort
let l:servers = lsp#get_allowed_servers()
let l:servers =
\ filter(l:servers, {idx, name -> lsp#is_server_running(name)})

if empty(l:servers)
call lsp#utils#warning('No active LSP servers for the current buffer')
return
endif

for l:server in l:servers
echo 'Stopping "' . l:server . '" server ...'
call lsp#stop_server(l:server)
endfor
endfunction

function! lsp#ui#vim#stop_server(stop_all, ...) abort
if a:0 != 0 && a:0 != 1
call lsp#utils#error(
\ 'lsp#ui#vim#stop_server(): expected 1 optional "name" argument.'
\ . ' Got: "' . join(a:000, '", "') . '".')
return
endif
let l:stop_all = a:stop_all == '!'

Check failure on line 181 in autoload/lsp/ui/vim.vim

View workflow job for this annotation

GitHub Actions / runner / vint

[vint] reported by reviewdog 🐶 Use robust operators `==#` or `==?` instead of `==` (see Google VimScript Style Guide (Matching)) Raw Output: autoload/lsp/ui/vim.vim:181:33: Use robust operators `==#` or `==?` instead of `==` (see Google VimScript Style Guide (Matching))
let l:name = get(a:000, 0, '')

if l:stop_all
if !empty(l:name)
call lsp#utils#error(
\ '"!" stops all servers: name is ignored: "' . l:name . '"')
endif

call s:stop_all_servers()
return
endif

if !empty(l:name)
call s:stop_named_server(l:name)
return
endif

call s:stop_buffer_servers()
endfunction

function! lsp#ui#vim#workspace_symbol(query) abort
let l:servers = filter(lsp#get_allowed_servers(), 'lsp#capabilities#has_workspace_symbol_provider(v:val)')
let l:command_id = lsp#_new_command()
Expand Down
29 changes: 20 additions & 9 deletions doc/vim-lsp.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1909,17 +1909,28 @@ Prints the status of all registered servers. Use `:verbose LspStatus` to
additionally show each server's workspace_config.
See also |vim-lsp-healthcheck|.

LspStopServer [name] *:LspStopServer*
LspStopServer[!] [name] *:LspStopServer*

If 'name' is not specified, then all active servers that handle files matching
the current buffer type are stopped. This is often what you want. For
example, if you have multiple files of different types open, `LspStopServer`
will only stop the server for the current buffer.
:LspStopServer

When 'name' is provided, it acts as an additional restriction, only stopping
server that handles the current buffer type, if it also matches the specifie
name. 'name' value is compred to the 'name' property in the
|lsp#register_server()| call.
Stops all active servers that handle files matching the current buffer type
are stopped. This is often what you want. For example, if you have multiple
files of different types open, `LspStopServer` will only stop the server for
the current buffer. Shows an error if there are no active LSP servers for the
current buffer.

:LspStopServer!

Stops all active servers, regardless of the current buffer. Shows a message
for every stopped server.

:LspStopServer name

Stops a server named 'name', comparing the provided ID with the value of the
the 'name' property in the |lsp#register_server()| call. Shows an error if
'name' does not match a defined and currently running server.

Completion should list only currently running servers for the 'name' argument.

==============================================================================
Autocommands *vim-lsp-autocommands*
Expand Down
2 changes: 1 addition & 1 deletion plugin/lsp.vim
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ command! LspPeekImplementation call lsp#ui#vim#implementation(1)
command! -nargs=0 LspStatus call lsp#print_server_status()
command! LspNextReference call lsp#internal#document_highlight#jump(+1)
command! LspPreviousReference call lsp#internal#document_highlight#jump(-1)
command! -nargs=? -complete=customlist,lsp#server_complete LspStopServer call lsp#ui#vim#stop_server(<f-args>)
command! -nargs=? -bang -complete=customlist,lsp#server_complete_running LspStopServer call lsp#ui#vim#stop_server("<bang>", <f-args>)
command! -nargs=? -complete=customlist,lsp#utils#empty_complete LspSignatureHelp call lsp#ui#vim#signature_help#get_signature_help_under_cursor()
command! LspDocumentFold call lsp#ui#vim#folding#fold(0)
command! LspDocumentFoldSync call lsp#ui#vim#folding#fold(1)
Expand Down

0 comments on commit 92ebd4a

Please sign in to comment.