Languageclient-neovim: automatic calls to textDocument_documentHighlight based on cursor position

Created on 25 Sep 2018  路  8Comments  路  Source: autozimu/LanguageClient-neovim

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.

Most helpful comment

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>

All 8 comments

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.

Was this page helpful?
0 / 5 - 0 ratings