Skip to content

Commit 2f79ce4

Browse files
ilya-bobyrompugao
authored andcommitted
LspStopServer: Stop all and stop specific (prabirshrestha#1491)
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.
1 parent a3cb943 commit 2f79ce4

File tree

4 files changed

+110
-14
lines changed

4 files changed

+110
-14
lines changed

autoload/lsp.vim

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ function! lsp#get_server_names() abort
9595
return keys(s:servers)
9696
endfunction
9797

98+
function! lsp#is_valid_server_name(name) abort
99+
return has_key(s:servers, a:name)
100+
endfunction
101+
98102
function! lsp#get_server_info(server_name) abort
99103
return get(get(s:servers, a:server_name, {}), 'server_info', {})
100104
endfunction
@@ -128,6 +132,19 @@ function! s:server_status(server_name) abort
128132
return 'not running'
129133
endfunction
130134

135+
function! lsp#is_server_running(name) abort
136+
if !has_key(s:servers, a:name)
137+
return 0
138+
endif
139+
140+
let l:server = s:servers[a:name]
141+
142+
return has_key(l:server, 'init_result')
143+
\ && !has_key(l:server, 'exited')
144+
\ && !has_key(l:server, 'init_callbacks')
145+
\ && !has_key(l:server, 'failed')
146+
endfunction
147+
131148
" Returns the current status of all servers (if called with no arguments) or
132149
" the given server (if given an argument). Can be one of "unknown server",
133150
" "exited", "starting", "failed", "running", "not running"
@@ -1364,6 +1381,13 @@ function! lsp#server_complete(lead, line, pos) abort
13641381
return filter(sort(keys(s:servers)), 'stridx(v:val, a:lead)==0 && has_key(s:servers[v:val], "init_result")')
13651382
endfunction
13661383

1384+
function! lsp#server_complete_running(lead, line, pos) abort
1385+
let l:all_servers = sort(keys(s:servers))
1386+
return filter(l:all_servers, {idx, name ->
1387+
\ stridx(name, a:lead) == 0 && lsp#is_server_running(name)
1388+
\ })
1389+
endfunction
1390+
13671391
function! lsp#_new_command() abort
13681392
let s:last_command_id += 1
13691393
call lsp#stream(1, { 'command': 1 })

autoload/lsp/ui/vim.vim

Lines changed: 65 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -127,17 +127,78 @@ function! lsp#ui#vim#rename() abort
127127
call s:rename(l:server, input('new name: ', expand('<cword>')), lsp#get_position())
128128
endfunction
129129

130-
function! lsp#ui#vim#stop_server(...) abort
131-
let l:name = get(a:000, 0, '')
132-
for l:server in lsp#get_allowed_servers()
133-
if !empty(l:name) && l:server != l:name
130+
function! s:stop_all_servers() abort
131+
for l:server in lsp#get_server_names()
132+
if !lsp#is_server_running(l:server)
134133
continue
135134
endif
135+
136136
echo 'Stopping' l:server 'server ...'
137137
call lsp#stop_server(l:server)
138138
endfor
139139
endfunction
140140

141+
function! s:stop_named_server(name) abort
142+
if !lsp#is_valid_server_name(a:name)
143+
call lsp#utils#warning('No LSP servers named "' . a:name . '"')
144+
return
145+
endif
146+
147+
if lsp#is_server_running(a:name)
148+
echo 'Stopping "' . a:name . '" server...'
149+
call lsp#stop_server(a:name)
150+
else
151+
call lsp#utils#warning(
152+
\ 'Server "' . a:name . '" is not running: '
153+
\ . lsp#get_server_status(a:name)
154+
\ )
155+
endif
156+
endfunction
157+
158+
function! s:stop_buffer_servers() abort
159+
let l:servers = lsp#get_allowed_servers()
160+
let l:servers =
161+
\ filter(l:servers, {idx, name -> lsp#is_server_running(name)})
162+
163+
if empty(l:servers)
164+
call lsp#utils#warning('No active LSP servers for the current buffer')
165+
return
166+
endif
167+
168+
for l:server in l:servers
169+
echo 'Stopping "' . l:server . '" server ...'
170+
call lsp#stop_server(l:server)
171+
endfor
172+
endfunction
173+
174+
function! lsp#ui#vim#stop_server(stop_all, ...) abort
175+
if a:0 != 0 && a:0 != 1
176+
call lsp#utils#error(
177+
\ 'lsp#ui#vim#stop_server(): expected 1 optional "name" argument.'
178+
\ . ' Got: "' . join(a:000, '", "') . '".')
179+
return
180+
endif
181+
let l:stop_all = a:stop_all ==# '!'
182+
let l:name = get(a:000, 0, '')
183+
184+
if l:stop_all
185+
if !empty(l:name)
186+
call lsp#utils#error(
187+
\ '"!" stops all servers: name is ignored: "' . l:name . '"')
188+
endif
189+
190+
call s:stop_all_servers()
191+
return
192+
endif
193+
194+
if !empty(l:name)
195+
call s:stop_named_server(l:name)
196+
return
197+
endif
198+
199+
call s:stop_buffer_servers()
200+
endfunction
201+
141202
function! lsp#ui#vim#workspace_symbol(query) abort
142203
let l:servers = filter(lsp#get_allowed_servers(), 'lsp#capabilities#has_workspace_symbol_provider(v:val)')
143204
let l:command_id = lsp#_new_command()

doc/vim-lsp.txt

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1909,17 +1909,28 @@ Prints the status of all registered servers. Use `:verbose LspStatus` to
19091909
additionally show each server's workspace_config.
19101910
See also |vim-lsp-healthcheck|.
19111911

1912-
LspStopServer [name] *:LspStopServer*
1912+
LspStopServer[!] [name] *:LspStopServer*
19131913

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

1919-
When 'name' is provided, it acts as an additional restriction, only stopping
1920-
server that handles the current buffer type, if it also matches the specifie
1921-
name. 'name' value is compred to the 'name' property in the
1922-
|lsp#register_server()| call.
1916+
Stops all active servers that handle files matching the current buffer type
1917+
are stopped. This is often what you want. For example, if you have multiple
1918+
files of different types open, `LspStopServer` will only stop the server for
1919+
the current buffer. Shows an error if there are no active LSP servers for the
1920+
current buffer.
1921+
1922+
:LspStopServer!
1923+
1924+
Stops all active servers, regardless of the current buffer. Shows a message
1925+
for every stopped server.
1926+
1927+
:LspStopServer name
1928+
1929+
Stops a server named 'name', comparing the provided ID with the value of the
1930+
the 'name' property in the |lsp#register_server()| call. Shows an error if
1931+
'name' does not match a defined and currently running server.
1932+
1933+
Completion should list only currently running servers for the 'name' argument.
19231934

19241935
==============================================================================
19251936
Autocommands *vim-lsp-autocommands*

plugin/lsp.vim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ command! LspPeekImplementation call lsp#ui#vim#implementation(1)
153153
command! -nargs=0 LspStatus call lsp#print_server_status()
154154
command! LspNextReference call lsp#internal#document_highlight#jump(+1)
155155
command! LspPreviousReference call lsp#internal#document_highlight#jump(-1)
156-
command! -nargs=? -complete=customlist,lsp#server_complete LspStopServer call lsp#ui#vim#stop_server(<f-args>)
156+
command! -nargs=? -bang -complete=customlist,lsp#server_complete_running LspStopServer call lsp#ui#vim#stop_server("<bang>", <f-args>)
157157
command! -nargs=? -complete=customlist,lsp#utils#empty_complete LspSignatureHelp call lsp#ui#vim#signature_help#get_signature_help_under_cursor()
158158
command! LspDocumentFold call lsp#ui#vim#folding#fold(0)
159159
command! LspDocumentFoldSync call lsp#ui#vim#folding#fold(1)

0 commit comments

Comments
 (0)