]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/vim-lsp/autoload/lsp/ui/vim/code_lens.vim

madduck's git repository

Every one of the projects in this repository is available at the canonical URL git://git.madduck.net/madduck/pub/<projectpath> — see each project's metadata for the exact URL.

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.

SSH access, as well as push access can be individually arranged.

If you use my repositories frequently, consider adding the following snippet to ~/.gitconfig and using the third clone URL listed for each project:

[url "git://git.madduck.net/madduck/"]
  insteadOf = madduck:

Merge commit '56df844d3c39ec494dacc69eae34272b27db185a' as '.vim/bundle/asyncomplete'
[etc/vim.git] / .vim / bundle / vim-lsp / autoload / lsp / ui / vim / code_lens.vim
1 " https://microsoft.github.io/language-server-protocol/specification#textDocument_codeLens
2
3 " @param option = {
4 " }
5 "
6 function! lsp#ui#vim#code_lens#do(option) abort
7     let l:sync = get(a:option, 'sync', v:false)
8
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)
12     endif
13
14     redraw | echo 'Retrieving codelens ...'
15
16     let l:bufnr = bufnr('%')
17
18     call lsp#callbag#pipe(
19         \ lsp#callbag#fromList(l:servers),
20         \ lsp#callbag#flatMap({server->
21         \   lsp#callbag#pipe(
22         \       lsp#request(server, {
23         \           'method': 'textDocument/codeLens',
24         \           'params': {
25         \               'textDocument': lsp#get_text_document_identifier(l:bufnr),
26         \           },
27         \       }),
28         \       lsp#callbag#map({x->x['response']['result']}),
29         \       lsp#callbag#filter({codelenses->!empty(codelenses)}),
30         \       lsp#callbag#flatMap({codelenses->
31         \           lsp#callbag#pipe(
32         \               lsp#callbag#fromList(codelenses),
33         \               lsp#callbag#flatMap({codelens->
34         \                   has_key(codelens, 'command') ? lsp#callbag#of(codelens) : s:resolve_codelens(server, codelens)}),
35         \           )
36         \       }),
37         \       lsp#callbag#map({codelens->{ 'server': server, 'codelens': codelens }}),
38         \   )
39         \ }),
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),
46         \   'bufnr': l:bufnr,
47         \ })}),
48         \ lsp#callbag#takeUntil(lsp#callbag#pipe(
49         \   lsp#stream(),
50         \   lsp#callbag#filter({x->has_key(x, 'command')}),
51         \ )),
52         \ lsp#callbag#subscribe({
53         \   'error': {e->lsp#utils#error('Error running codelens ' . json_encode(e))},
54         \ }),
55         \ )
56 endfunction
57
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
64         \ }),
65         \ lsp#callbag#map({x->x['response']['result']}),
66         \ )
67 endfunction
68
69 function! s:chooseCodeLens(items, bufnr) abort
70     redraw | echo 'Select codelens:'
71     if empty(a:items)
72         return lsp#callbag#throwError('No codelens found')
73     endif
74     return lsp#callbag#create(function('s:quickpick_open', [a:items, a:bufnr]))
75 endfunction
76
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.
81
82     if !has_key(a:item['codelens']['command'], 'arguments')
83         return ''
84     endif
85
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')
89             return ''
90         endif
91     endfor
92
93     return ': ' . join(map(copy(l:arguments), 'v:val["label"]'), ' > ')
94 endfunction
95
96 function! s:quickpick_open(items, bufnr, next, error, complete) abort
97     if empty(a:items)
98         return lsp#callbag#empty()
99     endif
100
101     let l:items = []
102     for l:item in a:items
103         let l:title = printf("[%s] %s%s\t| L%s:%s",
104             \ l:item['server'],
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 })
110     endfor
111
112     call lsp#internal#ui#quickpick#open({
113         \ 'items': l:items,
114         \ 'key': 'title',
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]),
117         \ })
118
119     return function('s:quickpick_dispose')
120 endfunction
121
122 function! s:quickpick_dispose() abort
123     call lsp#internal#ui#quickpick#close()
124 endfunction
125
126 function! s:quickpick_accept(next, error, complete, data, ...) abort
127     call lsp#internal#ui#quickpick#close()
128     let l:items = a:data['items']
129     if len(l:items) > 0
130         call a:next(l:items[0]['item'])
131     endif
132     call a:complete()
133 endfunction
134
135 function! s:quickpick_cancel(next, error, complete, ...) abort
136     call a:complete()
137 endfunction