]> git.madduck.net Git - etc/vim.git/blob - .vim/bundle/vim-lsp/autoload/lsp/ui/vim/signature_help.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 'a39f715c13be3352193ffd9c5b7536b8786eff64' as '.vim/bundle/vim-lsp'
[etc/vim.git] / .vim / bundle / vim-lsp / autoload / lsp / ui / vim / signature_help.vim
1 " vint: -ProhibitUnusedVariable
2 let s:debounce_timer_id = 0
3
4 function! s:not_supported(what) abort
5     return lsp#utils#error(a:what.' not supported for '.&filetype)
6 endfunction
7
8 function! lsp#ui#vim#signature_help#get_signature_help_under_cursor() abort
9     let l:servers = filter(lsp#get_allowed_servers(), 'lsp#capabilities#has_signature_help_provider(v:val)')
10
11     if len(l:servers) == 0
12         call s:not_supported('Retrieving signature help')
13         return
14     endif
15
16     let l:position = lsp#get_position()
17     for l:server in l:servers
18         call lsp#send_request(l:server, {
19             \ 'method': 'textDocument/signatureHelp',
20             \ 'params': {
21             \   'textDocument': lsp#get_text_document_identifier(),
22             \   'position': l:position,
23             \ },
24             \ 'on_notification': function('s:handle_signature_help', [l:server]),
25             \ })
26     endfor
27
28     call lsp#log('Retrieving signature help')
29     return
30 endfunction
31
32 function! s:handle_signature_help(server, data) abort
33     if lsp#client#is_error(a:data['response'])
34         call lsp#utils#error('Failed to retrieve signature help information for ' . a:server)
35         return
36     endif
37
38     if !has_key(a:data['response'], 'result')
39         return
40     endif
41
42     if !empty(a:data['response']['result']) && !empty(a:data['response']['result']['signatures'])
43         " Get current signature.
44         let l:signatures = get(a:data['response']['result'], 'signatures', [])
45         let l:signature_index = get(a:data['response']['result'], 'activeSignature', 0)
46         let l:signature = get(l:signatures, l:signature_index, {})
47         if empty(l:signature)
48             return
49         endif
50
51         " Signature label.
52         let l:label = l:signature['label']
53
54         " Mark current parameter.
55         if has_key(a:data['response']['result'], 'activeParameter')
56             let l:parameters = get(l:signature, 'parameters', [])
57             let l:parameter_index = a:data['response']['result']['activeParameter']
58             let l:parameter = get(l:parameters, l:parameter_index, {})
59             let l:parameter_label = s:get_parameter_label(l:signature, l:parameter)
60             if !empty(l:parameter_label)
61                 let l:label = substitute(l:label, '\V\(' . escape(l:parameter_label, '\/?') . '\)', '`\1`', 'g')
62             endif
63         endif
64
65         let l:contents = [l:label]
66
67         if exists('l:parameter')
68             let l:parameter_doc = s:get_parameter_doc(l:parameter)
69             if !empty(l:parameter_doc)
70                 call add(l:contents, '')
71                 call add(l:contents, l:parameter_doc)
72                 call add(l:contents, '')
73             endif
74         endif
75
76         if has_key(l:signature, 'documentation')
77             call add(l:contents, l:signature['documentation'])
78         endif
79
80         call lsp#ui#vim#output#preview(a:server, l:contents, {'statusline': ' LSP SignatureHelp'})
81         return
82     else
83         " signature help is used while inserting. So this must be graceful.
84         "call lsp#utils#error('No signature help information found')
85     endif
86 endfunction
87
88 function! s:get_parameter_label(signature, parameter) abort
89     if has_key(a:parameter, 'label')
90         if type(a:parameter['label']) == type([])
91             let l:string_range = a:parameter['label']
92             return strcharpart(
93                         \ a:signature['label'],
94                         \ l:string_range[0],
95                         \ l:string_range[1] - l:string_range[0])
96         endif
97         return a:parameter['label']
98     endif
99     return ''
100 endfunction
101
102 function! s:get_parameter_doc(parameter) abort
103     if !has_key(a:parameter, 'documentation')
104         return ''
105     endif
106
107     let l:doc = copy(a:parameter['documentation'])
108     if type(l:doc) == type({})
109         let l:doc['value'] = printf('***%s*** - %s', a:parameter['label'], l:doc['value'])
110         return l:doc
111     endif
112     return printf('***%s*** - %s', a:parameter['label'], l:doc)
113 endfunction
114
115 function! s:on_cursor_moved() abort
116     let l:bufnr = bufnr('%')
117     call timer_stop(s:debounce_timer_id)
118     if g:lsp_signature_help_enabled
119         let s:debounce_timer_id = timer_start(g:lsp_signature_help_delay, function('s:on_text_changed_after', [l:bufnr]), { 'repeat': 1 })
120     endif
121 endfunction
122
123 function! s:on_text_changed_after(bufnr, timer) abort
124     if bufnr('%') != a:bufnr
125         return
126     endif
127     if index(['i', 's'], mode()[0]) == -1
128         return
129     endif
130     if win_id2win(lsp#ui#vim#output#getpreviewwinid()) >= 1
131         return
132     endif
133
134     " Cache trigger chars since this loop is heavy
135     let l:chars = get(b:, 'lsp_signature_help_trigger_character', [])
136     if empty(l:chars)
137         for l:server_name in lsp#get_allowed_servers(a:bufnr)
138             let l:chars += lsp#capabilities#get_signature_help_trigger_characters(l:server_name)
139         endfor
140         let b:lsp_signature_help_trigger_character = l:chars
141     endif
142
143     if index(l:chars, lsp#utils#_get_before_char_skip_white()) >= 0
144         call lsp#ui#vim#signature_help#get_signature_help_under_cursor()
145     endif
146 endfunction
147
148 function! lsp#ui#vim#signature_help#setup() abort
149     augroup _lsp_signature_help_
150         autocmd!
151         autocmd CursorMoved,CursorMovedI * call s:on_cursor_moved()
152     augroup END
153 endfunction
154
155 function! lsp#ui#vim#signature_help#_disable() abort
156     augroup _lsp_signature_help_
157         autocmd!
158     augroup END
159 endfunction
160