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 " vint: -ProhibitUnusedVariable
2 let s:debounce_timer_id = 0
4 function! s:not_supported(what) abort
5 return lsp#utils#error(a:what.' not supported for '.&filetype)
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)')
11 if len(l:servers) == 0
12 call s:not_supported('Retrieving signature help')
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',
21 \ 'textDocument': lsp#get_text_document_identifier(),
22 \ 'position': l:position,
24 \ 'on_notification': function('s:handle_signature_help', [l:server]),
28 call lsp#log('Retrieving signature help')
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)
38 if !has_key(a:data['response'], 'result')
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, {})
52 let l:label = l:signature['label']
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')
65 let l:contents = [l:label]
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, '')
76 if has_key(l:signature, 'documentation')
77 call add(l:contents, l:signature['documentation'])
80 call lsp#ui#vim#output#preview(a:server, l:contents, {'statusline': ' LSP SignatureHelp'})
83 " signature help is used while inserting. So this must be graceful.
84 "call lsp#utils#error('No signature help information found')
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']
93 \ a:signature['label'],
95 \ l:string_range[1] - l:string_range[0])
97 return a:parameter['label']
102 function! s:get_parameter_doc(parameter) abort
103 if !has_key(a:parameter, 'documentation')
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'])
112 return printf('***%s*** - %s', a:parameter['label'], l:doc)
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 })
123 function! s:on_text_changed_after(bufnr, timer) abort
124 if bufnr('%') != a:bufnr
127 if index(['i', 's'], mode()[0]) == -1
130 if win_id2win(lsp#ui#vim#output#getpreviewwinid()) >= 1
134 " Cache trigger chars since this loop is heavy
135 let l:chars = get(b:, 'lsp_signature_help_trigger_character', [])
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)
140 let b:lsp_signature_help_trigger_character = l:chars
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()
148 function! lsp#ui#vim#signature_help#setup() abort
149 augroup _lsp_signature_help_
151 autocmd CursorMoved,CursorMovedI * call s:on_cursor_moved()
155 function! lsp#ui#vim#signature_help#_disable() abort
156 augroup _lsp_signature_help_