Skip to content

Commit e699b0f

Browse files
add LspDocumentSymbolSearch using quickpick (#1029)
1 parent c1a9a73 commit e699b0f

File tree

4 files changed

+84
-0
lines changed

4 files changed

+84
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ function! s:on_lsp_buffer_enabled() abort
3030
setlocal signcolumn=yes
3131
if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif
3232
nmap <buffer> gd <plug>(lsp-definition)
33+
nmap <buffer> gs <plug>(lsp-document-symbol-search)
3334
nmap <buffer> gr <plug>(lsp-references)
3435
nmap <buffer> gi <plug>(lsp-implementation)
3536
nmap <buffer> gt <plug>(lsp-type-definition)
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
" https://microsoft.github.io/language-server-protocol/specification#textDocument_documentSymbol
2+
" options - {
3+
" bufnr: bufnr('%') " optional
4+
" server - 'server_name' " optional
5+
" }
6+
function! lsp#internal#document_symbol#search#do(options) abort
7+
let l:bufnr = get(a:options, 'bufnr', bufnr('%'))
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+
let l:filetype = getbufvar(l:bufnr, '&filetype')
16+
call lsp#utils#error('textDocument/documentSymbol not supported for ' . l:filetype)
17+
return
18+
endif
19+
20+
redraw | echo 'Retrieving document symbols ...'
21+
22+
call lsp#internal#ui#quickpick#open({
23+
\ 'items': [],
24+
\ 'busy': 1,
25+
\ 'input': '',
26+
\ 'key': 'text',
27+
\ 'on_accept': function('s:on_accept'),
28+
\ 'on_close': function('s:on_close'),
29+
\ })
30+
31+
let s:Dispose = lsp#callbag#pipe(
32+
\ lsp#callbag#fromList(l:servers),
33+
\ lsp#callbag#flatMap({server->
34+
\ lsp#callbag#pipe(
35+
\ lsp#request(server, {
36+
\ 'method': 'textDocument/documentSymbol',
37+
\ 'params': {
38+
\ 'textDocument': lsp#get_text_document_identifier(l:bufnr),
39+
\ },
40+
\ }),
41+
\ lsp#callbag#map({x->{'server': server, 'request': x['request'], 'response': x['response']}}),
42+
\ )
43+
\ }),
44+
\ lsp#callbag#scan({acc, curr->add(acc, curr)}, []),
45+
\ lsp#callbag#tap({x->s:update_ui_items(x)}),
46+
\ lsp#callbag#subscribe({
47+
\ 'complete':{->lsp#internal#ui#quickpick#busy(0)},
48+
\ 'error':{e->s:on_error(e)},
49+
\ }),
50+
\ )
51+
endfunction
52+
53+
function! s:update_ui_items(x) abort
54+
let l:items = []
55+
for l:i in a:x
56+
let l:items += lsp#ui#vim#utils#symbols_to_loc_list(l:i['server'], l:i)
57+
endfor
58+
call lsp#internal#ui#quickpick#items(l:items)
59+
endfunction
60+
61+
function! s:on_accept(data, ...) abort
62+
call lsp#internal#ui#quickpick#close()
63+
call lsp#utils#location#_open_vim_list_item(a:data['items'][0], '')
64+
endfunction
65+
66+
function! s:on_close(...) abort
67+
if exists('s:Dispose')
68+
call s:Dispose()
69+
unlet s:Dispose
70+
endif
71+
endfunction
72+
73+
function! s:on_error(e) abort
74+
call lsp#internal#ui#quickpick#close()
75+
call lsp#log('LspDocumentSymbolSearch error', a:e)
76+
endfunction

doc/vim-lsp.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ CONTENTS *vim-lsp-contents*
9898
LspDocumentRangeFormat |:LspDocumentRangeFormat|
9999
LspDocumentRangeFormatSync |:LspDocumentRangeFormatSync|
100100
LspDocumentSymbol |:LspDocumentSymbol|
101+
LspDocumentSymbolSearch |:LspDocumentSymbolSearch|
101102
LspHover |:LspHover|
102103
LspNextDiagnostic |:LspNextDiagnostic|
103104
LspNextError |:LspNextError|
@@ -1418,6 +1419,10 @@ LspDocumentSymbol *:LspDocumentSymbol*
14181419

14191420
Gets the symbols for the current document.
14201421

1422+
LspDocumentSymbolSearch *:LspDocumentSymbolSearch*
1423+
1424+
Search the symbols for the current document and navigate.
1425+
14211426
LspHover *:LspHover*
14221427

14231428
Gets the hover information and displays it in the |preview-window|.

plugin/lsp.vim

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ command! LspPeekDeclaration call lsp#ui#vim#declaration(1)
8888
command! LspDefinition call lsp#ui#vim#definition(0, <q-mods>)
8989
command! LspPeekDefinition call lsp#ui#vim#definition(1)
9090
command! LspDocumentSymbol call lsp#ui#vim#document_symbol()
91+
command! LspDocumentSymbolSearch call lsp#internal#document_symbol#search#do({})
9192
command! -nargs=? LspDocumentDiagnostics call lsp#internal#diagnostics#document_diagnostics_command#do(
9293
\ extend({}, lsp#utils#args#_parse(<q-args>, {
9394
\ 'buffers': {'type': type('')},
@@ -135,6 +136,7 @@ nnoremap <plug>(lsp-peek-declaration) :<c-u>call lsp#ui#vim#declaration(1)<cr>
135136
nnoremap <plug>(lsp-definition) :<c-u>call lsp#ui#vim#definition(0)<cr>
136137
nnoremap <plug>(lsp-peek-definition) :<c-u>call lsp#ui#vim#definition(1)<cr>
137138
nnoremap <plug>(lsp-document-symbol) :<c-u>call lsp#ui#vim#document_symbol()<cr>
139+
nnoremap <plug>(lsp-document-symbol-search) :<c-u>call lsp#internal#document_symbol#search#do({})<cr>
138140
nnoremap <plug>(lsp-document-diagnostics) :<c-u>call lsp#internal#diagnostics#document_diagnostics_command#do({})<cr>
139141
nnoremap <plug>(lsp-hover) :<c-u>call lsp#ui#vim#hover#get_hover_under_cursor()<cr>
140142
nnoremap <plug>(lsp-preview-close) :<c-u>call lsp#ui#vim#output#closepreview()<cr>

0 commit comments

Comments
 (0)