]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/vim-lsp/autoload/lsp/internal/inlay_hints.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:

Do not set EDITOR/VISUAL for shell
[etc/vim.git] / .vim / bundle / vim-lsp / autoload / lsp / internal / inlay_hints.vim
1 let s:use_vim_textprops = lsp#utils#_has_vim_virtual_text() && !has('nvim')
2
3 function! s:set_inlay_hints(data) abort
4     let l:bufnr = bufnr('%')
5
6     call s:clear_inlay_hints()
7
8     if mode() !=# 'n' | return | endif
9
10     if lsp#client#is_error(a:data['response']) | return | endif
11
12     " Get hints from the response
13     let l:hints = a:data['response']['result']
14     if empty(l:hints)
15         return
16     endif
17
18     let l:not_curline = s:has_inlay_hints_mode('!curline')
19     for l:hint in l:hints
20         if l:not_curline && l:hint.position.line+1 ==# line('.')
21             continue
22         endif
23         let l:label = ''
24         if type(l:hint.label) ==# v:t_list
25             let l:label = join(map(copy(l:hint.label), {_,v -> v.value}), '')
26         else
27             let l:label = l:hint.label
28         endif
29         let l:text = (get(l:hint, 'paddingLeft', v:false) ? ' ' : '') . l:label . (get(l:hint, 'paddingRight', v:false) ? ' ' : '')
30         if !has_key(l:hint, 'kind') || l:hint.kind ==# 1
31             call prop_add(l:hint.position.line+1, l:hint.position.character+1, {'type': 'vim_lsp_inlay_hint_type', 'text': l:text, 'bufnr': l:bufnr})
32         elseif l:hint.kind ==# 2
33             call prop_add(l:hint.position.line+1, l:hint.position.character+1, {'type': 'vim_lsp_inlay_hint_parameter', 'text': l:text, 'bufnr': l:bufnr})
34         endif
35     endfor
36 endfunction
37
38 function! s:init_inlay_hints() abort
39     if index(prop_type_list(), 'vim_lsp_inlay_hint_type') ==# -1
40         call prop_type_add('vim_lsp_inlay_hint_type', { 'highlight': 'lspInlayHintsType' })
41         call prop_type_add('vim_lsp_inlay_hint_parameter', { 'highlight': 'lspInlayHintsParameter' })
42     endif
43 endfunction
44
45 function! lsp#internal#inlay_hints#_disable() abort
46     if exists('s:Dispose')
47         call s:Dispose()
48         unlet s:Dispose
49     endif
50 endfunction
51
52 function! s:clear_inlay_hints() abort
53     let l:bufnr = bufnr('%')
54     call prop_remove({'type': 'vim_lsp_inlay_hint_type', 'bufnr': l:bufnr, 'all': v:true})
55     call prop_remove({'type': 'vim_lsp_inlay_hint_parameter', 'bufnr': l:bufnr, 'all': v:true})
56 endfunction
57
58 function! s:has_inlay_hints_mode(value) abort
59     let l:m = get(g:, 'lsp_inlay_hints_mode', {})
60     if type(l:m) != v:t_dict | return v:false | endif
61     if mode() ==# 'i'
62         let l:a = get(l:m, 'insert', [])
63     elseif mode() ==# 'n'
64         let l:a = get(l:m, 'normal', [])
65     else
66         return v:false
67     endif
68     if type(l:a) != v:t_list | return v:false | endif
69     return index(l:a, a:value) != -1 ? v:true : v:false
70 endfunction
71
72 function! s:send_inlay_hints_request() abort
73     let l:capability = 'lsp#capabilities#has_inlay_hint_provider(v:val)'
74     let l:servers = filter(lsp#get_allowed_servers(), l:capability)
75
76     if empty(l:servers)
77         return lsp#callbag#empty()
78     endif
79
80     if s:has_inlay_hints_mode('curline')
81         let l:range = lsp#utils#range#get_range_curline()
82     else
83         let l:range = lsp#utils#range#get_range()
84     endif
85     return lsp#request(l:servers[0], {
86         \ 'method': 'textDocument/inlayHint',
87         \ 'params': {
88         \   'textDocument': lsp#get_text_document_identifier(),
89         \   'range': l:range,
90         \  },
91         \ })
92 endfunction
93
94 function! lsp#internal#inlay_hints#_enable() abort
95     if !s:use_vim_textprops | return | endif
96     if !g:lsp_inlay_hints_enabled | return | endif
97
98     if !hlexists('lspInlayHintsType')
99         highlight link lspInlayHintsType Label
100     endif
101     if !hlexists('lspInlayHintsParameter')
102         highlight link lspInlayHintsParameter Todo
103     endif
104
105     call s:init_inlay_hints()
106     let s:Dispose = lsp#callbag#pipe(
107         \ lsp#callbag#merge(
108         \   lsp#callbag#fromEvent(['CursorMoved', 'CursorHold']),
109         \   lsp#callbag#pipe(
110         \       lsp#callbag#fromEvent(['InsertEnter', 'BufLeave']),
111         \       lsp#callbag#tap({_ -> s:clear_inlay_hints() }),
112         \   )
113         \ ),
114         \ lsp#callbag#filter({_ -> g:lsp_inlay_hints_enabled }),
115         \ lsp#callbag#debounceTime(g:lsp_inlay_hints_delay),
116         \ lsp#callbag#filter({_->getbufvar(bufnr('%'), '&buftype') !~# '^(help\|terminal\|prompt\|popup)$'}),
117         \ lsp#callbag#switchMap({_->
118         \   lsp#callbag#pipe(
119         \       s:send_inlay_hints_request(),
120         \       lsp#callbag#materialize(),
121         \       lsp#callbag#filter({x->lsp#callbag#isNextNotification(x)}),
122         \       lsp#callbag#map({x->x['value']})
123         \   )
124         \ }),
125         \ lsp#callbag#subscribe({x->s:set_inlay_hints(x)}),
126         \)
127 endfunction