Skip to content

Commit 3ed0e7a

Browse files
Workspace symbol search using quickpick (#1035)
1 parent bed4d52 commit 3ed0e7a

File tree

3 files changed

+106
-1
lines changed

3 files changed

+106
-1
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
" https://microsoft.github.io/language-server-protocol/specification#workspace_symbol
2+
" options - {
3+
" bufnr: bufnr('%') " optional
4+
" server - 'server_name' " optional
5+
" query: '' " optional
6+
" }
7+
function! lsp#internal#workspace_symbol#search#do(options) abort
8+
if has_key(a:options, 'server')
9+
let l:servers = [a:options['server']]
10+
else
11+
let l:servers = filter(lsp#get_allowed_servers(), 'lsp#capabilities#has_document_symbol_provider(v:val)')
12+
endif
13+
14+
if len(l:servers) == 0
15+
echom 'textDocument/workspaceSymbol not supported'
16+
call lsp#utils#error('textDocument/workspaceSymbol not supported')
17+
return
18+
endif
19+
20+
redraw | echo 'Retrieving workspace symbols ...'
21+
22+
let l:TextChangeSubject = lsp#callbag#makeSubject()
23+
24+
" use callbag debounce instead of quickpick debounce
25+
call lsp#internal#ui#quickpick#open({
26+
\ 'items': [],
27+
\ 'input': get(a:options, 'query', ''),
28+
\ 'key': 'text',
29+
\ 'debounce': 0,
30+
\ 'on_change': function('s:on_change', [l:TextChangeSubject]),
31+
\ 'on_accept': function('s:on_accept'),
32+
\ 'on_close': function('s:on_close'),
33+
\ })
34+
35+
let s:Dispose = lsp#callbag#pipe(
36+
\ l:TextChangeSubject,
37+
\ lsp#callbag#debounceTime(250),
38+
\ lsp#callbag#distinctUntilChanged(),
39+
\ lsp#callbag#switchMap({query->
40+
\ lsp#callbag#pipe(
41+
\ lsp#callbag#fromList(l:servers),
42+
\ lsp#callbag#tap({_->lsp#internal#ui#quickpick#busy(1)}),
43+
\ lsp#callbag#flatMap({server->
44+
\ lsp#callbag#pipe(
45+
\ lsp#request(server, {
46+
\ 'method': 'workspace/symbol',
47+
\ 'params': {
48+
\ 'query': query
49+
\ }
50+
\ }),
51+
\ lsp#callbag#map({x->{'server': server, 'request': x['request'], 'response': x['response']}}),
52+
\ )
53+
\ }),
54+
\ lsp#callbag#scan({acc, curr->add(acc, curr)}, []),
55+
\ lsp#callbag#tap({x->s:update_ui_items(x)}),
56+
\ lsp#callbag#tap({'complete': {->lsp#internal#ui#quickpick#busy(0)}}),
57+
\ )
58+
\ }),
59+
\ lsp#callbag#subscribe({
60+
\ 'error': {e->s:on_error(e)},
61+
\ }),
62+
\ )
63+
" Notify empty query. Some servers may not return results when query is empty
64+
call l:TextChangeSubject(1, '')
65+
endfunction
66+
67+
function! s:on_change(TextChangeSubject, data, ...) abort
68+
call a:TextChangeSubject(1, a:data['input'])
69+
endfunction
70+
71+
function! s:update_ui_items(x) abort
72+
let l:items = []
73+
for l:i in a:x
74+
let l:items += lsp#ui#vim#utils#symbols_to_loc_list(l:i['server'], l:i)
75+
endfor
76+
call lsp#internal#ui#quickpick#items(l:items)
77+
endfunction
78+
79+
function! s:on_accept(data, name) abort
80+
call lsp#internal#ui#quickpick#close()
81+
call lsp#utils#location#_open_vim_list_item(a:data['items'][0], '')
82+
endfunction
83+
84+
function! s:on_close(...) abort
85+
if exists('s:Dispose')
86+
call s:Dispose()
87+
unlet s:Dispose
88+
endif
89+
endfunction
90+
91+
function! s:on_error(e) abort
92+
call lsp#internal#ui#quickpick#close()
93+
call lsp#log('LspWorkspaceSymbolSearch error', a:e)
94+
endfunction

doc/vim-lsp.txt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ CONTENTS *vim-lsp-contents*
119119
LspTypeDefinition |:LspTypeDefinition|
120120
LspTypeHierarchy |:LspTypeHierarchy|
121121
LspWorkspaceSymbol |:LspWorkspaceSymbol|
122+
LspWorkspaceSymbolSearch |:LspWorkspaceSymbolSearch|
122123
LspStatus |:LspStatus|
123124
LspStopServer |:LspStopServer|
124125
Autocommands |vim-lsp-autocommands|
@@ -1537,7 +1538,13 @@ Also see |:LspPeekTypeDefinition|.
15371538

15381539
LspWorkspaceSymbol *:LspWorkspaceSymbol*
15391540

1540-
Search and show workspace symbols.
1541+
Search and show workspace symbols in quickfix.
1542+
Servers may choose to return empty results if the search query is empty.
1543+
1544+
LspWorkspaceSymbolSearch *:LspWorkspaceSymbolSearch*
1545+
1546+
Search the workspace symbols for all servers and navigate using quickpick.
1547+
Servers may choose to return empty results if the search query is empty.
15411548

15421549
LspStatus *:LspStatus*
15431550

@@ -1633,6 +1640,7 @@ Available plug mappings are following:
16331640
nnoremap <plug>(lsp-definition)
16341641
nnoremap <plug>(lsp-peek-definition)
16351642
nnoremap <plug>(lsp-document-symbol)
1643+
nnoremap <plug>(lsp-document-symbol-search)
16361644
nnoremap <plug>(lsp-document-diagnostics)
16371645
nnoremap <plug>(lsp-hover)
16381646
nnoremap <plug>(lsp-next-diagnostic)
@@ -1654,6 +1662,7 @@ Available plug mappings are following:
16541662
nnoremap <plug>(lsp-references)
16551663
nnoremap <plug>(lsp-rename)
16561664
nnoremap <plug>(lsp-workspace-symbol)
1665+
nnoremap <plug>(lsp-workspace-symbol-search)
16571666
nnoremap <plug>(lsp-document-format)
16581667
vnoremap <plug>(lsp-document-format)
16591668
nnoremap <plug>(lsp-document-range-format)

plugin/lsp.vim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,7 @@ command! LspTypeDefinition call lsp#ui#vim#type_definition(0, <q-mods>)
106106
command! LspTypeHierarchy call lsp#internal#type_hierarchy#show()
107107
command! LspPeekTypeDefinition call lsp#ui#vim#type_definition(1)
108108
command! -nargs=? LspWorkspaceSymbol call lsp#ui#vim#workspace_symbol(<q-args>)
109+
command! -nargs=? LspWorkspaceSymbolSearch call lsp#internal#workspace_symbol#search#do({'query': <q-args>})
109110
command! -range LspDocumentFormat call lsp#internal#document_formatting#format({ 'bufnr': bufnr('%') })
110111
command! -range -nargs=? LspDocumentFormatSync call lsp#internal#document_formatting#format(
111112
\ extend({'bufnr': bufnr('%'), 'sync': 1 }, lsp#utils#args#_parse(<q-args>, {
@@ -159,6 +160,7 @@ nnoremap <plug>(lsp-type-definition) :<c-u>call lsp#ui#vim#type_definition(0)<cr
159160
nnoremap <plug>(lsp-type-hierarchy) :<c-u>call lsp#internal#type_hierarchy#show()<cr>
160161
nnoremap <plug>(lsp-peek-type-definition) :<c-u>call lsp#ui#vim#type_definition(1)<cr>
161162
nnoremap <plug>(lsp-workspace-symbol) :<c-u>call lsp#ui#vim#workspace_symbol('')<cr>
163+
nnoremap <plug>(lsp-workspace-symbol-search) :<c-u>call lsp#internal#workspace_symbol#search#do({})<cr>
162164
nnoremap <plug>(lsp-document-format) :<c-u>call lsp#internal#document_formatting#format({ 'bufnr': bufnr('%') })<cr>
163165
vnoremap <plug>(lsp-document-format) :<Home>silent <End>call lsp#internal#document_range_formatting#format({ 'bufnr': bufnr('%') })<cr>
164166
nnoremap <plug>(lsp-document-range-format) :<c-u>set opfunc=lsp#internal#document_range_formatting#opfunc<cr>g@

0 commit comments

Comments
 (0)