mirror of
https://github.com/prabirshrestha/vim-lsp.git
synced 2025-12-14 20:35:59 +01:00
* fix comment
* fix indent
* support diagnostics in a floating window
* doc: add g:lsp_diagnostics_float_{cursor,delay}
* fix vint errors except unused variables
* suppress vint unused variable errors
* lint: use robust operator
153 lines
5.1 KiB
VimL
153 lines
5.1 KiB
VimL
" 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_whitelisted_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)
|
|
let s:debounce_timer_id = timer_start(500, function('s:on_text_changed_after', [l:bufnr]), { 'repeat': 1 })
|
|
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_whitelisted_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
|
|
|