All patches and comments are welcome. Please squash your changes to logical
commits before using git-format-patch and git-send-email to
patches@git.madduck.net.
If you'd read over the Git project's submission guidelines and adhered to them,
I'd be especially grateful.
1 " https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens
6 function! lsp#ui#vim#code_lens#do(option) abort
7 let l:sync = get(a:option, 'sync', v:false)
9 let l:servers = filter(lsp#get_allowed_servers(), 'lsp#capabilities#has_code_lens_provider(v:val)')
10 if len(l:servers) == 0
11 return lsp#utils#error('Code lens not supported for ' . &filetype)
14 redraw | echo 'Retrieving codelens ...'
16 let l:bufnr = bufnr('%')
18 call lsp#callbag#pipe(
19 \ lsp#callbag#fromList(l:servers),
20 \ lsp#callbag#flatMap({server->
22 \ lsp#request(server, {
23 \ 'method': 'textDocument/codeLens',
25 \ 'textDocument': lsp#get_text_document_identifier(l:bufnr),
28 \ lsp#callbag#map({x->x['response']['result']}),
29 \ lsp#callbag#filter({codelenses->!empty(codelenses)}),
30 \ lsp#callbag#flatMap({codelenses->
32 \ lsp#callbag#fromList(codelenses),
33 \ lsp#callbag#flatMap({codelens->
34 \ has_key(codelens, 'command') ? lsp#callbag#of(codelens) : s:resolve_codelens(server, codelens)}),
37 \ lsp#callbag#map({codelens->{ 'server': server, 'codelens': codelens }}),
40 \ lsp#callbag#reduce({acc,curr->add(acc, curr)}, []),
41 \ lsp#callbag#flatMap({x->s:chooseCodeLens(x, l:bufnr)}),
42 \ lsp#callbag#tap({x-> lsp#ui#vim#execute_command#_execute({
43 \ 'server_name': x['server'],
44 \ 'command_name': get(x['codelens']['command'], 'command', ''),
45 \ 'command_args': get(x['codelens']['command'], 'arguments', v:null),
48 \ lsp#callbag#takeUntil(lsp#callbag#pipe(
50 \ lsp#callbag#filter({x->has_key(x, 'command')}),
52 \ lsp#callbag#subscribe({
53 \ 'error': {e->lsp#utils#error('Error running codelens ' . json_encode(e))},
58 function! s:resolve_codelens(server, codelens) abort
59 " TODO: return callbag#lsp#empty() if codelens resolve not supported by server
60 return lsp#callbag#pipe(
61 \ lsp#request(a:server, {
62 \ 'method': 'codeLens/resolve',
63 \ 'params': a:codelens
65 \ lsp#callbag#map({x->x['response']['result']}),
69 function! s:chooseCodeLens(items, bufnr) abort
70 redraw | echo 'Select codelens:'
72 return lsp#callbag#throwError('No codelens found')
74 return lsp#callbag#create(function('s:quickpick_open', [a:items, a:bufnr]))
77 function! lsp#ui#vim#code_lens#_get_subtitle(item) abort
78 " Since element of arguments property of Command interface is defined as any in LSP spec, it is
79 " up to the language server implementation.
80 " Currently this only impacts rust-analyzer. See #1118 for more details.
82 if !has_key(a:item['codelens']['command'], 'arguments')
86 let l:arguments = a:item['codelens']['command']['arguments']
87 for l:argument in l:arguments
88 if type(l:argument) != type({}) || !has_key(l:argument, 'label')
93 return ': ' . join(map(copy(l:arguments), 'v:val["label"]'), ' > ')
96 function! s:quickpick_open(items, bufnr, next, error, complete) abort
98 return lsp#callbag#empty()
102 for l:item in a:items
103 let l:title = printf("[%s] %s%s\t| L%s:%s",
105 \ l:item['codelens']['command']['title'],
106 \ lsp#ui#vim#code_lens#_get_subtitle(l:item),
107 \ lsp#utils#position#lsp_line_to_vim(a:bufnr, l:item['codelens']['range']['start']),
108 \ getbufline(a:bufnr, lsp#utils#position#lsp_line_to_vim(a:bufnr, l:item['codelens']['range']['start']))[0])
109 call add(l:items, { 'title': l:title, 'item': l:item })
112 call lsp#internal#ui#quickpick#open({
115 \ 'on_accept': function('s:quickpick_accept', [a:next, a:error, a:complete]),
116 \ 'on_cancel': function('s:quickpick_cancel', [a:next, a:error, a:complete]),
119 return function('s:quickpick_dispose')
122 function! s:quickpick_dispose() abort
123 call lsp#internal#ui#quickpick#close()
126 function! s:quickpick_accept(next, error, complete, data, ...) abort
127 call lsp#internal#ui#quickpick#close()
128 let l:items = a:data['items']
130 call a:next(l:items[0]['item'])
135 function! s:quickpick_cancel(next, error, complete, ...) abort