mirror of
https://github.com/prabirshrestha/vim-lsp.git
synced 2025-12-14 20:35:59 +01:00
Inlay hint (#1347)
* inlay hint * implement inlayHints * implement inlayHints * update doc * fix * fix * separate highlights * update/clear * use callbag * remove from doc * disable default * update doc * check version * check label array * call prop_remove() * use lsp#utils#range#get_range() * add comma * add lsp_inlay_hints_mode * own highlight * update doc * fix style check * rename lsp#utils#_has_virtual_text to lsp#utils#_has_nvim_virtual_text lsp#utils#_has_vim9textprops to lsp#utils#_has_vim_virtual_text * update doc * fix version * remove all
This commit is contained in:
@@ -69,6 +69,7 @@ function! lsp#enable() abort
|
|||||||
call lsp#internal#show_message#_enable()
|
call lsp#internal#show_message#_enable()
|
||||||
call lsp#internal#work_done_progress#_enable()
|
call lsp#internal#work_done_progress#_enable()
|
||||||
call lsp#internal#completion#documentation#_enable()
|
call lsp#internal#completion#documentation#_enable()
|
||||||
|
call lsp#internal#inlay_hints#_enable()
|
||||||
call s:register_events()
|
call s:register_events()
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -540,6 +541,9 @@ function! lsp#default_get_supported_capabilities(server_info) abort
|
|||||||
\ 'dynamicRegistration': v:false,
|
\ 'dynamicRegistration': v:false,
|
||||||
\ 'contentFormat': ['markdown', 'plaintext'],
|
\ 'contentFormat': ['markdown', 'plaintext'],
|
||||||
\ },
|
\ },
|
||||||
|
\ 'inlayHint': {
|
||||||
|
\ 'dynamicRegistration': v:false,
|
||||||
|
\ },
|
||||||
\ 'implementation': {
|
\ 'implementation': {
|
||||||
\ 'dynamicRegistration': v:false,
|
\ 'dynamicRegistration': v:false,
|
||||||
\ 'linkSupport' : v:true
|
\ 'linkSupport' : v:true
|
||||||
|
|||||||
@@ -192,3 +192,7 @@ endfunction
|
|||||||
function! lsp#capabilities#has_completion_resolve_provider(server_name) abort
|
function! lsp#capabilities#has_completion_resolve_provider(server_name) abort
|
||||||
return s:has_provider(a:server_name, 'completionProvider', 'resolveProvider')
|
return s:has_provider(a:server_name, 'completionProvider', 'resolveProvider')
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! lsp#capabilities#has_inlay_hint_provider(server_name) abort
|
||||||
|
return s:has_provider(a:server_name, 'inlayHintProvider')
|
||||||
|
endfunction
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ endif
|
|||||||
|
|
||||||
function! lsp#internal#diagnostics#virtual_text#_enable() abort
|
function! lsp#internal#diagnostics#virtual_text#_enable() abort
|
||||||
" don't even bother registering if the feature is disabled
|
" don't even bother registering if the feature is disabled
|
||||||
if !lsp#utils#_has_virtual_text() | return | endif
|
if !lsp#utils#_has_nvim_virtual_text() | return | endif
|
||||||
if !g:lsp_diagnostics_virtual_text_enabled | return | endif
|
if !g:lsp_diagnostics_virtual_text_enabled | return | endif
|
||||||
|
|
||||||
if s:enabled | return | endif
|
if s:enabled | return | endif
|
||||||
|
|||||||
127
autoload/lsp/internal/inlay_hints.vim
Normal file
127
autoload/lsp/internal/inlay_hints.vim
Normal file
@@ -0,0 +1,127 @@
|
|||||||
|
let s:use_vim_textprops = lsp#utils#_has_vim_virtual_text() && !has('nvim')
|
||||||
|
|
||||||
|
function! s:set_inlay_hints(data) abort
|
||||||
|
let l:bufnr = bufnr('%')
|
||||||
|
|
||||||
|
call s:clear_inlay_hints()
|
||||||
|
|
||||||
|
if mode() !=# 'n' | return | endif
|
||||||
|
|
||||||
|
if lsp#client#is_error(a:data['response']) | return | endif
|
||||||
|
|
||||||
|
" Get hints from the response
|
||||||
|
let l:hints = a:data['response']['result']
|
||||||
|
if empty(l:hints)
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
let l:not_curline = s:has_inlay_hints_mode('!curline')
|
||||||
|
for l:hint in l:hints
|
||||||
|
if l:not_curline && l:hint.position.line+1 ==# line('.')
|
||||||
|
continue
|
||||||
|
endif
|
||||||
|
let l:label = ''
|
||||||
|
if type(l:hint.label) ==# v:t_list
|
||||||
|
let l:label = join(map(copy(l:hint.label), {_,v -> v.value}), ', ')
|
||||||
|
else
|
||||||
|
let l:label = l:hint.label
|
||||||
|
endif
|
||||||
|
let l:text = (get(l:hint, 'paddingLeft', v:false) ? ' ' : '') . l:label . (get(l:hint, 'paddingRight', v:false) ? ' ' : '')
|
||||||
|
if !has_key(l:hint, 'kind') || l:hint.kind ==# 1
|
||||||
|
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})
|
||||||
|
elseif l:hint.kind ==# 2
|
||||||
|
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})
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:init_inlay_hints() abort
|
||||||
|
if index(prop_type_list(), 'vim_lsp_inlay_hint_type') ==# -1
|
||||||
|
call prop_type_add('vim_lsp_inlay_hint_type', { 'highlight': 'lspInlayHintsType' })
|
||||||
|
call prop_type_add('vim_lsp_inlay_hint_parameter', { 'highlight': 'lspInlayHintsParameter' })
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! lsp#internal#inlay_hints#_disable() abort
|
||||||
|
if exists('s:Dispose')
|
||||||
|
call s:Dispose()
|
||||||
|
unlet s:Dispose
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:clear_inlay_hints() abort
|
||||||
|
let l:bufnr = bufnr('%')
|
||||||
|
call prop_remove({'type': 'vim_lsp_inlay_hint_type', 'bufnr': l:bufnr, 'all': v:true})
|
||||||
|
call prop_remove({'type': 'vim_lsp_inlay_hint_parameter', 'bufnr': l:bufnr, 'all': v:true})
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:has_inlay_hints_mode(value) abort
|
||||||
|
let l:m = get(g:, 'lsp_inlay_hints_mode', {})
|
||||||
|
if type(l:m) != v:t_dict | return v:false | endif
|
||||||
|
if mode() ==# 'i'
|
||||||
|
let l:a = get(l:m, 'insert', [])
|
||||||
|
elseif mode() ==# 'n'
|
||||||
|
let l:a = get(l:m, 'normal', [])
|
||||||
|
else
|
||||||
|
return v:false
|
||||||
|
endif
|
||||||
|
if type(l:a) != v:t_list | return v:false | endif
|
||||||
|
return index(l:a, a:value) != -1 ? v:true : v:false
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! s:send_inlay_hints_request() abort
|
||||||
|
let l:capability = 'lsp#capabilities#has_inlay_hint_provider(v:val)'
|
||||||
|
let l:servers = filter(lsp#get_allowed_servers(), l:capability)
|
||||||
|
|
||||||
|
if empty(l:servers)
|
||||||
|
return lsp#callbag#empty()
|
||||||
|
endif
|
||||||
|
|
||||||
|
if s:has_inlay_hints_mode('curline')
|
||||||
|
let l:range = lsp#utils#range#get_range_curline()
|
||||||
|
else
|
||||||
|
let l:range = lsp#utils#range#get_range()
|
||||||
|
endif
|
||||||
|
return lsp#request(l:servers[0], {
|
||||||
|
\ 'method': 'textDocument/inlayHint',
|
||||||
|
\ 'params': {
|
||||||
|
\ 'textDocument': lsp#get_text_document_identifier(),
|
||||||
|
\ 'range': l:range,
|
||||||
|
\ },
|
||||||
|
\ })
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! lsp#internal#inlay_hints#_enable() abort
|
||||||
|
if !s:use_vim_textprops | return | endif
|
||||||
|
if !g:lsp_inlay_hints_enabled | return | endif
|
||||||
|
|
||||||
|
if !hlexists('lspInlayHintsType')
|
||||||
|
highlight link lspInlayHintsType Label
|
||||||
|
endif
|
||||||
|
if !hlexists('lspInlayHintsParameter')
|
||||||
|
highlight link lspInlayHintsParameter Todo
|
||||||
|
endif
|
||||||
|
|
||||||
|
call s:init_inlay_hints()
|
||||||
|
let s:Dispose = lsp#callbag#pipe(
|
||||||
|
\ lsp#callbag#merge(
|
||||||
|
\ lsp#callbag#fromEvent(['CursorMoved', 'CursorHold']),
|
||||||
|
\ lsp#callbag#pipe(
|
||||||
|
\ lsp#callbag#fromEvent(['InsertEnter', 'BufLeave']),
|
||||||
|
\ lsp#callbag#tap({_ -> s:clear_inlay_hints() }),
|
||||||
|
\ )
|
||||||
|
\ ),
|
||||||
|
\ lsp#callbag#filter({_ -> g:lsp_inlay_hints_enabled }),
|
||||||
|
\ lsp#callbag#debounceTime(g:lsp_inlay_hints_delay),
|
||||||
|
\ lsp#callbag#filter({_->getbufvar(bufnr('%'), '&buftype') !~# '^(help\|terminal\|prompt\|popup)$'}),
|
||||||
|
\ lsp#callbag#switchMap({_->
|
||||||
|
\ lsp#callbag#pipe(
|
||||||
|
\ s:send_inlay_hints_request(),
|
||||||
|
\ lsp#callbag#materialize(),
|
||||||
|
\ lsp#callbag#filter({x->lsp#callbag#isNextNotification(x)}),
|
||||||
|
\ lsp#callbag#map({x->x['value']})
|
||||||
|
\ )
|
||||||
|
\ }),
|
||||||
|
\ lsp#callbag#subscribe({x->s:set_inlay_hints(x)}),
|
||||||
|
\)
|
||||||
|
endfunction
|
||||||
@@ -4,7 +4,7 @@ function! lsp#utils#has_lua() abort
|
|||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
let s:has_virtual_text = exists('*nvim_buf_set_virtual_text') && exists('*nvim_create_namespace')
|
let s:has_virtual_text = exists('*nvim_buf_set_virtual_text') && exists('*nvim_create_namespace')
|
||||||
function! lsp#utils#_has_virtual_text() abort
|
function! lsp#utils#_has_nvim_virtual_text() abort
|
||||||
return s:has_virtual_text
|
return s:has_virtual_text
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
@@ -24,6 +24,11 @@ function! lsp#utils#_has_textprops() abort
|
|||||||
return s:has_textprops
|
return s:has_textprops
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
let s:has_vim9textprops = exists('*prop_add') && has('patch-9.0.0178')
|
||||||
|
function! lsp#utils#_has_vim_virtual_text() abort
|
||||||
|
return s:has_vim9textprops
|
||||||
|
endfunction
|
||||||
|
|
||||||
let s:has_higlights = has('nvim') ? lsp#utils#_has_nvim_buf_highlight() : lsp#utils#_has_textprops()
|
let s:has_higlights = has('nvim') ? lsp#utils#_has_nvim_buf_highlight() : lsp#utils#_has_textprops()
|
||||||
function! lsp#utils#_has_highlights() abort
|
function! lsp#utils#_has_highlights() abort
|
||||||
return s:has_higlights
|
return s:has_higlights
|
||||||
|
|||||||
@@ -70,3 +70,13 @@ function! lsp#utils#range#lsp_to_vim(bufnr, range) abort
|
|||||||
|
|
||||||
return l:position
|
return l:position
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
function! lsp#utils#range#get_range() abort
|
||||||
|
let l:char = lsp#utils#to_char('%', line('$'), col('$'))
|
||||||
|
return {'start': {'line': 0, 'character': 0}, 'end': {'line': line('$')-1, 'character': l:char}}
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function! lsp#utils#range#get_range_curline() abort
|
||||||
|
let l:char = lsp#utils#to_char('%', line('.'), col('$'))
|
||||||
|
return {'start': {'line': line('.')-1, 'character': 0}, 'end': {'line': line('.')-1, 'character': l:char}}
|
||||||
|
endfunction
|
||||||
|
|||||||
@@ -53,6 +53,12 @@ CONTENTS *vim-lsp-contents*
|
|||||||
|g:lsp_document_code_actions_signs_enabled|
|
|g:lsp_document_code_actions_signs_enabled|
|
||||||
g:lsp_document_code_action_signs_delay
|
g:lsp_document_code_action_signs_delay
|
||||||
|g:lsp_document_code_actions_signs_delay|
|
|g:lsp_document_code_actions_signs_delay|
|
||||||
|
g:lsp_inlay_hints_enabled
|
||||||
|
|g:lsp_inlay_hints_enabled|
|
||||||
|
g:lsp_inlay_hints_delay
|
||||||
|
|g:lsp_inlay_hints_delay|
|
||||||
|
g:lsp_inlay_hints_mode
|
||||||
|
|g:lsp_inlay_hints_mode|
|
||||||
g:lsp_tree_incoming_prefix |g:lsp_tree_incoming_prefix|
|
g:lsp_tree_incoming_prefix |g:lsp_tree_incoming_prefix|
|
||||||
g:lsp_format_sync_timeout |g:lsp_format_sync_timeout|
|
g:lsp_format_sync_timeout |g:lsp_format_sync_timeout|
|
||||||
g:lsp_use_event_queue |g:lsp_use_event_queue|
|
g:lsp_use_event_queue |g:lsp_use_event_queue|
|
||||||
@@ -728,6 +734,54 @@ g:lsp_document_code_action_signs_delay
|
|||||||
let g:lsp_document_code_action_signs_delay = 200
|
let g:lsp_document_code_action_signs_delay = 200
|
||||||
let g:lsp_document_code_action_signs_delay = 1000
|
let g:lsp_document_code_action_signs_delay = 1000
|
||||||
>
|
>
|
||||||
|
g:lsp_inlay_hints_enabled
|
||||||
|
*g:lsp_inlay_hints_enabled*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `1`
|
||||||
|
|
||||||
|
Enables inlay-hints. Requires Vim9 with |virtualtext|.
|
||||||
|
patch 9.0.0167 or newer.
|
||||||
|
|
||||||
|
Example: >
|
||||||
|
let g:lsp_inlay_hints_enabled = 1
|
||||||
|
let g:lsp_inlay_hints_enabled = 0
|
||||||
|
<
|
||||||
|
To change the style of the inlay-hints, you can set or link the
|
||||||
|
`lspInlayHintsType` and `lspInlayHintsParameter` highlight group.
|
||||||
|
|
||||||
|
Example: >
|
||||||
|
highlight lspInlayHintsType ctermfg=red guifg=red
|
||||||
|
\ ctermbg=green guibg=green
|
||||||
|
highlight lspInlayHintsParameter ctermfg=red guifg=red
|
||||||
|
\ ctermbg=green guibg=green
|
||||||
|
|
||||||
|
g:lsp_inlay_hints_delay
|
||||||
|
*g:lsp_inlay_hints_delay*
|
||||||
|
Type: |Number|
|
||||||
|
Default: `350`
|
||||||
|
|
||||||
|
Delay milliseconds to update inlay-hints. Requires
|
||||||
|
|g:lsp_inlay_hints_enabled|.
|
||||||
|
|
||||||
|
Example: >
|
||||||
|
let g:lsp_inlay_hints_delay = 200
|
||||||
|
let g:lsp_inlay_hints_delay = 1000
|
||||||
|
>
|
||||||
|
g:lsp_inlay_hints_mode
|
||||||
|
*g:lsp_inlay_hints_mode*
|
||||||
|
Type: |Dict|
|
||||||
|
Default: `{}`
|
||||||
|
|
||||||
|
This mode currently only include "curline" and "!curline".
|
||||||
|
|
||||||
|
Example: >
|
||||||
|
let g:lsp_inlay_hints_mode = {
|
||||||
|
\ 'normal': ['curline'],
|
||||||
|
\}
|
||||||
|
<
|
||||||
|
"curline" show hint only for current line. "!curline" show hints except
|
||||||
|
current line. Default show all hints.
|
||||||
|
>
|
||||||
g:lsp_tree_incoming_prefix *g:lsp_tree_incoming_prefix*
|
g:lsp_tree_incoming_prefix *g:lsp_tree_incoming_prefix*
|
||||||
Type: |String|
|
Type: |String|
|
||||||
Default: `"<= "`
|
Default: `"<= "`
|
||||||
@@ -1478,7 +1532,7 @@ lsp#get_progress() *lsp#get_progress()*
|
|||||||
Type: |Number|
|
Type: |Number|
|
||||||
0 - 100 or not exist
|
0 - 100 or not exist
|
||||||
|
|
||||||
lsp#document_hover_preview_winid() *lsp#document_hover_preview_winid()*
|
lsp#document_hover_preview_winid() *lsp#document_hover_preview_winid()*
|
||||||
|
|
||||||
Returns |windowid| of the current hover preview window or |v:null| if it does not
|
Returns |windowid| of the current hover preview window or |v:null| if it does not
|
||||||
exist.
|
exist.
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ let g:lsp_diagnostics_signs_information = get(g:, 'lsp_diagnostics_signs_informa
|
|||||||
let g:lsp_diagnostics_signs_hint = get(g:, 'lsp_diagnostics_signs_hint', {})
|
let g:lsp_diagnostics_signs_hint = get(g:, 'lsp_diagnostics_signs_hint', {})
|
||||||
let g:lsp_diagnostics_signs_priority = get(g:, 'lsp_diagnostics_signs_priority', 10)
|
let g:lsp_diagnostics_signs_priority = get(g:, 'lsp_diagnostics_signs_priority', 10)
|
||||||
let g:lsp_diagnostics_signs_priority_map = get(g:, 'lsp_diagnostics_signs_priority_map', {})
|
let g:lsp_diagnostics_signs_priority_map = get(g:, 'lsp_diagnostics_signs_priority_map', {})
|
||||||
let g:lsp_diagnostics_virtual_text_enabled = get(g:, 'lsp_diagnostics_virtual_text_enabled', lsp#utils#_has_virtual_text())
|
let g:lsp_diagnostics_virtual_text_enabled = get(g:, 'lsp_diagnostics_virtual_text_enabled', lsp#utils#_has_nvim_virtual_text())
|
||||||
let g:lsp_diagnostics_virtual_text_insert_mode_enabled = get(g:, 'lsp_diagnostics_virtual_text_insert_mode_enabled', 0)
|
let g:lsp_diagnostics_virtual_text_insert_mode_enabled = get(g:, 'lsp_diagnostics_virtual_text_insert_mode_enabled', 0)
|
||||||
let g:lsp_diagnostics_virtual_text_delay = get(g:, 'lsp_diagnostics_virtual_text_delay', 500)
|
let g:lsp_diagnostics_virtual_text_delay = get(g:, 'lsp_diagnostics_virtual_text_delay', 500)
|
||||||
let g:lsp_diagnostics_virtual_text_prefix = get(g:, 'lsp_diagnostics_virtual_text_prefix', '')
|
let g:lsp_diagnostics_virtual_text_prefix = get(g:, 'lsp_diagnostics_virtual_text_prefix', '')
|
||||||
@@ -72,6 +72,8 @@ let g:lsp_show_message_request_enabled = get(g:, 'lsp_show_message_request_enabl
|
|||||||
let g:lsp_show_message_log_level = get(g:, 'lsp_show_message_log_level', 'warning')
|
let g:lsp_show_message_log_level = get(g:, 'lsp_show_message_log_level', 'warning')
|
||||||
let g:lsp_work_done_progress_enabled = get(g:, 'lsp_work_done_progress_enabled', 0)
|
let g:lsp_work_done_progress_enabled = get(g:, 'lsp_work_done_progress_enabled', 0)
|
||||||
let g:lsp_untitled_buffer_enabled = get(g:, 'lsp_untitled_buffer_enabled', 1)
|
let g:lsp_untitled_buffer_enabled = get(g:, 'lsp_untitled_buffer_enabled', 1)
|
||||||
|
let g:lsp_inlay_hints_enabled = get(g:, 'lsp_inlay_hints_enabled', 0)
|
||||||
|
let g:lsp_inlay_hints_delay = get(g:, 'lsp_inlay_hints_delay', 350)
|
||||||
|
|
||||||
let g:lsp_get_supported_capabilities = get(g:, 'lsp_get_supported_capabilities', [function('lsp#default_get_supported_capabilities')])
|
let g:lsp_get_supported_capabilities = get(g:, 'lsp_get_supported_capabilities', [function('lsp#default_get_supported_capabilities')])
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user