X-Git-Url: https://git.madduck.net/etc/vim.git/blobdiff_plain/5a4872f466ebd76ddd532bdf2798554421c53df4..fe3919e725e156d751069662d11e38f7b4791de1:/.vim/bundle/vim-lsp/autoload/lsp/ui/vim/signature_help.vim diff --git a/.vim/bundle/vim-lsp/autoload/lsp/ui/vim/signature_help.vim b/.vim/bundle/vim-lsp/autoload/lsp/ui/vim/signature_help.vim new file mode 100644 index 00000000..26f6a6ae --- /dev/null +++ b/.vim/bundle/vim-lsp/autoload/lsp/ui/vim/signature_help.vim @@ -0,0 +1,160 @@ +" vint: -ProhibitUnusedVariable +let s:debounce_timer_id = 0 + +function! s:not_supported(what) abort + return lsp#utils#error(a:what.' not supported for '.&filetype) +endfunction + +function! lsp#ui#vim#signature_help#get_signature_help_under_cursor() abort + let l:servers = filter(lsp#get_allowed_servers(), 'lsp#capabilities#has_signature_help_provider(v:val)') + + if len(l:servers) == 0 + call s:not_supported('Retrieving signature help') + return + endif + + let l:position = lsp#get_position() + for l:server in l:servers + call lsp#send_request(l:server, { + \ 'method': 'textDocument/signatureHelp', + \ 'params': { + \ 'textDocument': lsp#get_text_document_identifier(), + \ 'position': l:position, + \ }, + \ 'on_notification': function('s:handle_signature_help', [l:server]), + \ }) + endfor + + call lsp#log('Retrieving signature help') + return +endfunction + +function! s:handle_signature_help(server, data) abort + if lsp#client#is_error(a:data['response']) + call lsp#utils#error('Failed to retrieve signature help information for ' . a:server) + return + endif + + if !has_key(a:data['response'], 'result') + return + endif + + if !empty(a:data['response']['result']) && !empty(a:data['response']['result']['signatures']) + " Get current signature. + let l:signatures = get(a:data['response']['result'], 'signatures', []) + let l:signature_index = get(a:data['response']['result'], 'activeSignature', 0) + let l:signature = get(l:signatures, l:signature_index, {}) + if empty(l:signature) + return + endif + + " Signature label. + let l:label = l:signature['label'] + + " Mark current parameter. + if has_key(a:data['response']['result'], 'activeParameter') + let l:parameters = get(l:signature, 'parameters', []) + let l:parameter_index = a:data['response']['result']['activeParameter'] + let l:parameter = get(l:parameters, l:parameter_index, {}) + let l:parameter_label = s:get_parameter_label(l:signature, l:parameter) + if !empty(l:parameter_label) + let l:label = substitute(l:label, '\V\(' . escape(l:parameter_label, '\/?') . '\)', '`\1`', 'g') + endif + endif + + let l:contents = [l:label] + + if exists('l:parameter') + let l:parameter_doc = s:get_parameter_doc(l:parameter) + if !empty(l:parameter_doc) + call add(l:contents, '') + call add(l:contents, l:parameter_doc) + call add(l:contents, '') + endif + endif + + if has_key(l:signature, 'documentation') + call add(l:contents, l:signature['documentation']) + endif + + call lsp#ui#vim#output#preview(a:server, l:contents, {'statusline': ' LSP SignatureHelp'}) + return + else + " signature help is used while inserting. So this must be graceful. + "call lsp#utils#error('No signature help information found') + endif +endfunction + +function! s:get_parameter_label(signature, parameter) abort + if has_key(a:parameter, 'label') + if type(a:parameter['label']) == type([]) + let l:string_range = a:parameter['label'] + return strcharpart( + \ a:signature['label'], + \ l:string_range[0], + \ l:string_range[1] - l:string_range[0]) + endif + return a:parameter['label'] + endif + return '' +endfunction + +function! s:get_parameter_doc(parameter) abort + if !has_key(a:parameter, 'documentation') + return '' + endif + + let l:doc = copy(a:parameter['documentation']) + if type(l:doc) == type({}) + let l:doc['value'] = printf('***%s*** - %s', a:parameter['label'], l:doc['value']) + return l:doc + endif + return printf('***%s*** - %s', a:parameter['label'], l:doc) +endfunction + +function! s:on_cursor_moved() abort + let l:bufnr = bufnr('%') + call timer_stop(s:debounce_timer_id) + if g:lsp_signature_help_enabled + let s:debounce_timer_id = timer_start(g:lsp_signature_help_delay, function('s:on_text_changed_after', [l:bufnr]), { 'repeat': 1 }) + endif +endfunction + +function! s:on_text_changed_after(bufnr, timer) abort + if bufnr('%') != a:bufnr + return + endif + if index(['i', 's'], mode()[0]) == -1 + return + endif + if win_id2win(lsp#ui#vim#output#getpreviewwinid()) >= 1 + return + endif + + " Cache trigger chars since this loop is heavy + let l:chars = get(b:, 'lsp_signature_help_trigger_character', []) + if empty(l:chars) + for l:server_name in lsp#get_allowed_servers(a:bufnr) + let l:chars += lsp#capabilities#get_signature_help_trigger_characters(l:server_name) + endfor + let b:lsp_signature_help_trigger_character = l:chars + endif + + if index(l:chars, lsp#utils#_get_before_char_skip_white()) >= 0 + call lsp#ui#vim#signature_help#get_signature_help_under_cursor() + endif +endfunction + +function! lsp#ui#vim#signature_help#setup() abort + augroup _lsp_signature_help_ + autocmd! + autocmd CursorMoved,CursorMovedI * call s:on_cursor_moved() + augroup END +endfunction + +function! lsp#ui#vim#signature_help#_disable() abort + augroup _lsp_signature_help_ + autocmd! + augroup END +endfunction +