Manually calling textDocument_documentHighlight and the appropriate clear method is pretty tedious. It would be nice if there was at least some option to automatically call this method based on the cursor movement. Many language servers use this feature to visualize variable usage and having this automatically would be an improvement in many cases.
And hover too.
I'm not sure if this is quite what you mean, but I use the following to automatically trigger textDocument_documentHighlight and textDocument_hover:
function! LspMaybeHover(is_running) abort
if a:is_running.result
call LanguageClient_textDocument_hover()
endif
endfunction
function! LspMaybeHighlight(is_running) abort
if a:is_running.result
call LanguageClient#textDocument_documentHighlight()
endif
endfunction
augroup lsp_aucommands
au!
au CursorHold * call LanguageClient#isAlive(function('LspMaybeHover'))
au CursorMoved * call LanguageClient#isAlive(function('LspMaybeHighlight'))
augroup END
This snippet invokes the relevant methods iff the language server is running in a given buffer. I invoke highlighting whenever the cursor moves, but only run hovering when the cursor pauses (I think this more closely approximates GUI hovering behavior).
Sorry for the spam if I've misinterpreted what you were asking!
@wbthomason
That works so good!
I will continue to use this from now.
@autozimu what you think about adding this to example config in README?
I wonder if there is something like CursorHold that triggers in visual mode?
I improved a bit to toggle.
function! LspMaybeHover(is_running) abort
if a:is_running.result && g:LanguageClient_autoHoverAndHighlightStatus
call LanguageClient_textDocument_hover()
endif
endfunction
function! LspMaybeHighlight(is_running) abort
if a:is_running.result && g:LanguageClient_autoHoverAndHighlightStatus
call LanguageClient#textDocument_documentHighlight()
endif
endfunction
augroup lsp_aucommands
au!
au CursorHold * call LanguageClient#isAlive(function('LspMaybeHover'))
au CursorMoved * call LanguageClient#isAlive(function('LspMaybeHighlight'))
augroup END
let g:LanguageClient_autoHoverAndHighlightStatus = 0
function! ToggleLspAutoHoverAndHilight() abort
if g:LanguageClient_autoHoverAndHighlightStatus
let g:LanguageClient_autoHoverAndHighlightStatus = 0
call LanguageClient#clearDocumentHighlight()
echo ""
else
let g:LanguageClient_autoHoverAndHighlightStatus = 1
end
endfunction
nnoremap <silent> ;tg :call ToggleLspAutoHoverAndHilight()<CR>
This is my automatic hover and document highlight configuration:
" Automatic Hover
function! DoNothingHandler(output)
endfunction
function! IsDifferentHoverLineFromLast()
if !exists('b:last_hover_line')
return 1
endif
return b:last_hover_line !=# line('.') || b:last_hover_col !=# col('.')
endfunction
function! GetHoverInfo()
" Only call hover if the cursor position changed.
"
" This is needed to prevent infinite loops, because hover info is displayed
" in a popup window via nvim_buf_set_lines() which puts the cursor into the
" popup window and back, which in turn calls CursorMoved again.
if mode() == 'n' && IsDifferentHoverLineFromLast()
let b:last_hover_line = line('.')
let b:last_hover_col = col('.')
call LanguageClient_textDocument_hover({'handle': v:true}, 'DoNothingHandler')
call LanguageClient_clearDocumentHighlight()
call LanguageClient_textDocument_documentHighlight({'handle': v:true}, 'DoNothingHandler')
endif
endfunction
augroup LanguageClient_config
autocmd!
autocmd CursorMoved * call GetHoverInfo()
autocmd CursorMovedI * call LanguageClient_clearDocumentHighlight()
augroup end
Closing this as it's solved by config. Happy to include this in the docs as an example config if someone is willing to open a PR for it.
Most helpful comment
I improved a bit to toggle.