Skip to content

Commit 1a7a6e0

Browse files
add support for codeLens/resolve (#1007)
1 parent 2ba5289 commit 1a7a6e0

File tree

2 files changed

+74
-73
lines changed

2 files changed

+74
-73
lines changed

autoload/lsp.vim

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -467,6 +467,9 @@ function! lsp#default_get_supported_capabilities(server_info) abort
467467
\ }
468468
\ }
469469
\ },
470+
\ 'codeLens': {
471+
\ 'dynamicRegistration': v:false,
472+
\ },
470473
\ 'completion': {
471474
\ 'dynamicRegistration': v:false,
472475
\ 'completionItem': {

autoload/lsp/ui/vim/code_lens.vim

Lines changed: 71 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -8,93 +8,91 @@
88
function! lsp#ui#vim#code_lens#do(option) abort
99
let l:sync = get(a:option, 'sync', v:false)
1010

11-
let l:server_names = filter(lsp#get_allowed_servers(), 'lsp#capabilities#has_code_lens_provider(v:val)')
12-
if len(l:server_names) == 0
11+
let s:items = []
12+
13+
let l:servers = filter(lsp#get_allowed_servers(), 'lsp#capabilities#has_code_lens_provider(v:val)')
14+
if len(l:servers) == 0
1315
return lsp#utils#error('Code lens not supported for ' . &filetype)
1416
endif
1517

16-
let l:ctx = {
17-
\ 'count': len(l:server_names),
18-
\ 'results': [],
19-
\}
18+
redraw | echo 'Retrieving codelens ...'
19+
2020
let l:bufnr = bufnr('%')
21-
let l:command_id = lsp#_new_command()
22-
for l:server_name in l:server_names
23-
call lsp#send_request(l:server_name, {
24-
\ 'method': 'textDocument/codeLens',
25-
\ 'params': {
26-
\ 'textDocument': lsp#get_text_document_identifier(),
27-
\ },
28-
\ 'sync': l:sync,
29-
\ 'on_notification': function('s:handle_code_lens', [l:ctx, l:server_name, l:command_id, l:sync, l:bufnr]),
30-
\ })
31-
endfor
32-
echo 'Retrieving code lenses ...'
33-
endfunction
3421

35-
function! s:handle_code_lens(ctx, server_name, command_id, sync, bufnr, data) abort
36-
" Ignore old request.
37-
if a:command_id != lsp#_last_command()
38-
return
39-
endif
22+
call lsp#callbag#pipe(
23+
\ lsp#callbag#fromList(l:servers),
24+
\ lsp#callbag#flatMap({server->
25+
\ lsp#callbag#pipe(
26+
\ lsp#request(server, {
27+
\ 'method': 'textDocument/codeLens',
28+
\ 'params': {
29+
\ 'textDocument': lsp#get_text_document_identifier(),
30+
\ },
31+
\ }),
32+
\ lsp#callbag#flatMap({x->s:resolve_if_required(server, x['response'])}),
33+
\ lsp#callbag#map({x->{ 'server': server, 'codelens': x }}),
34+
\ )
35+
\ }),
36+
\ lsp#callbag#takeUntil(lsp#callbag#pipe(
37+
\ lsp#stream(),
38+
\ lsp#callbag#filter({x->has_key(x, 'command')}),
39+
\ )),
40+
\ lsp#callbag#subscribe({
41+
\ 'next':{x->add(s:items, x)},
42+
\ 'complete': {->s:chooseCodeLens(s:items, l:bufnr)},
43+
\ 'error': {e->s:error(x)},
44+
\ }),
45+
\ )
46+
endfunction
4047

41-
call add(a:ctx['results'], {
42-
\ 'server_name': a:server_name,
43-
\ 'data': a:data,
44-
\})
45-
let a:ctx['count'] -= 1
46-
if a:ctx['count'] ># 0
47-
return
48+
function! s:resolve_if_required(server, response) abort
49+
let l:codelens = a:response['result']
50+
if empty(l:codelens)
51+
return lsp#callbag#empty()
4852
endif
4953

50-
let l:total_code_lenses = []
51-
for l:result in a:ctx['results']
52-
let l:server_name = l:result['server_name']
53-
let l:data = l:result['data']
54-
" Check response error.
55-
if lsp#client#is_error(l:data['response'])
56-
call lsp#utils#error('Failed to CodeLens for ' . l:server_name . ': ' . lsp#client#error_message(l:data['response']))
57-
continue
58-
endif
59-
60-
" Check code lenses.
61-
let l:code_lenses = l:data['response']['result']
62-
if empty(l:code_lenses)
63-
continue
64-
endif
54+
return lsp#callbag#pipe(
55+
\ lsp#callbag#fromList(l:codelens),
56+
\ lsp#callbag#flatMap({codelens-> has_key(codelens, 'command') ? lsp#callbag#of(codelens) : s:resolve_codelens(a:server, codelens) }),
57+
\ )
58+
endfunction
6559

66-
for l:code_lens in l:code_lenses
67-
call add(l:total_code_lenses, {
68-
\ 'server_name': l:server_name,
69-
\ 'code_lens': l:code_lens,
70-
\})
71-
endfor
72-
endfor
60+
function! s:resolve_codelens(server, codelens) abort
61+
" TODO: return callbag#lsp#empty() if codelens resolve not supported by server
62+
return lsp#callbag#pipe(
63+
\ lsp#request(a:server, {
64+
\ 'method': 'codeLens/resolve',
65+
\ 'params': a:codelens
66+
\ }),
67+
\ lsp#callbag#map({x->x['response']['result']}),
68+
\ )
69+
endfunction
7370

74-
if len(l:total_code_lenses) == 0
75-
echo 'No code lenses found'
71+
function! s:chooseCodeLens(items, bufnr) abort
72+
redraw | echo 'Select codelens:'
73+
if empty(a:items)
74+
call lsp#utils#error('No codelens found')
7675
return
7776
endif
78-
call lsp#log('s:handle_code_lens', l:total_code_lenses)
79-
80-
" Prompt to choose code lenses.
81-
let l:index = inputlist(map(copy(l:total_code_lenses), { i, lens ->
82-
\ printf('%s - [%s] %s', i + 1, lens['server_name'], lens['code_lens']['command']['title'])
83-
\ }))
84-
85-
" Execute code lens.
86-
if 0 < l:index && l:index <= len(l:total_code_lenses)
87-
let l:selected = l:total_code_lenses[l:index - 1]
88-
call s:handle_one_code_lens(l:selected['server_name'], a:sync, a:bufnr, l:selected['code_lens'])
77+
let l:index = inputlist(map(copy(a:items), {i, value ->
78+
\ printf('%s - [%s] %s', i + 1, value['server'], value['codelens']['command']['title'])
79+
\ }))
80+
if l:index > 0 && l:index <= len(a:items)
81+
let l:selected = a:items[l:index - 1]
82+
call s:handle_code_lens_command(l:selected['server'], l:selected['codelens'], a:bufnr)
8983
endif
9084
endfunction
9185

92-
function! s:handle_one_code_lens(server_name, sync, bufnr, code_lens) abort
86+
function! s:error(e) abort
87+
call lsp#utils#error('Echo occured during CodeLens' . a:e)
88+
endfunction
89+
90+
function! s:handle_code_lens_command(server, codelens, bufnr) abort
9391
call lsp#ui#vim#execute_command#_execute({
94-
\ 'server_name': a:server_name,
95-
\ 'command_name': get(a:code_lens['command'], 'command', ''),
96-
\ 'command_args': get(a:code_lens['command'], 'arguments', v:null),
97-
\ 'sync': a:sync,
98-
\ 'bufnr': a:bufnr,
99-
\ })
92+
\ 'server_name': a:server,
93+
\ 'command_name': get(a:codelens['command'], 'command', ''),
94+
\ 'command_args': get(a:codelens['command'], 'arguments', v:null),
95+
\ 'sync': 0,
96+
\ 'bufnr': a:bufnr,
97+
\ })
10098
endfunction

0 commit comments

Comments
 (0)