Languageclient-neovim: Feature request - Delay presenting diagnostics (or suppress highlighting)

Created on 11 Sep 2018  路  16Comments  路  Source: autozimu/LanguageClient-neovim

Is your feature request related to a problem? Please describe.

Diagnostics information in the gutter, and especially highlighting, can be quite distracting when writing code. More often than not code that is in the process of being written is invalid until it is completed, either by ending the line, or exiting insert mode. This effectively results in the text and gutter flickering unnecessarily in the area that you are trying to focus on.

Describe the solution you'd like

One or more of the below solutions may be viable;

  • Diagnostics delayed on a timer, reset at each keypress
  • Diagnostics deferred being presented until exiting edit mode (or a new line)
  • An ability to turn off highlighting when in edit mode, or altogether
  • Use g:LanguageClient_changeThrottle, but with an ability to force a 'sync' just prior to autocompletion trigger

Describe alternatives you've considered

Setting texthl to an empty string hides the highlighting, but it is still gets applied, affecting performance. It'd also be nice to see the highlighting, but when viewing code rather than trying to write it. The gutter signs are also present:

let g:LanguageClient_diagnosticsDisplay = {       
...
 "texthl": "", 

I could try setting 'g:LanguageClient_changeThrottle', however this has an impact on autocompletion.

feature request

Most helpful comment

I would also love this feature (specifically: present diagnostics only on leaving insert mode).

All 16 comments

Having a look at vim-lsp I believe it works this way.
It does not send updates until required, i.e just prior to auto-completion and when exiting edit mode. The end result is better performance and less distracting editing experience.

Yes - I have that setting enabled. It isn't "flickering" so much as flagging and highlighting errors that are only present because the code is in the process of being written. It is working as designed - however I am questioning the design from a UX perspective.

The 'throttle' config option is a potential solution, however the implementation of this breaks autocomplete. This could be fixed by "forcing" an update to the LSP as part of omnifunc, similar to what vim-lsp does.

It was the case to force sync before completion. https://github.com/autozimu/LanguageClient-neovim/blob/112fa1a97a756e75a34578fd5c258819f94685e4/src/languageclient.rs#L1289-L1290

I haven't check closely if it the still the same case yet.

Throttling certainly breaks autocomplete for me until you trigger enough updates for the throttle timeout to expire.

On a side note the throttling looks like it might have another bug - it only causes some updates to be skipped. There doesn't appear to be a timer set up to trigger an update after the delay. It should be resetting a timer on each keypress/update attempt such that it will trigger the actual update when that timer expires without being reset again.

I'm aware that completion might not work when throttling is on. My point is I cannot blindly sync changes before completion because of the comment mentioned wired issue.

That's not a bug. Throttling isn't implemented based on timer. It's simply checking current time and throttle time and skip syncing the changes when last update time is within a time frame.

I think throttling should be based on a timer. The doco states:

"This will make LanguageClient pause 0.5 second to send text changes to server after one textDocument_didChange is sent."

But that doesn't appear to be true. What happens is LanguageClient simply drops all updates within each 'x second' sliding window. This means your last few keys pressed are unlikely to ever result in an update being sent, even if you wait an hour.

It does not send updates until required, i.e just prior to auto-completion and when exiting edit mode. The end result is better performance and less distracting editing experience.

I'd love this feature.

I would also love this feature (specifically: present diagnostics only on leaving insert mode).

Isn't an alternative way to get the desired behavior simply to restart the throttle timer on keypress? That way, we wouldn't send didChange to the server until a little after the user's last keypress, which would mean there would also be no diagnostics coming in during that time. We'd also be saving the server from a lot of potentially useless work.

Isn't an alternative way to get the desired behavior simply to restart the throttle timer on keypress?

That is the first option I suggested. It is called "debounce" and is the normal way to implement this behaviour, the existing throttling mechanism is quite broken (last I checked, I use vim-lsp now).

This technique is used to handle users actively entering input causing storms of requests and GUI flicker. Vim has the benefit of having an input "mode", so arguably can take advantage of that instead to detect when users are entering text.

Alternatively the change in error state should be immediate when changing from error to non-error and delayed when changing to error. That might be a bit quirky though

I think one way to help is to give diagnostics an option to decide when to start. If we have that then users can just configure it to be "on save"/"auto"/"keybinding".

also see #689

I think for most programming languages the choice for when to display diagnostics would vary between "on new line" and "oninsertleave" (or "onsave," but I have ctrl+s bound to save and insertleave)

While autocomplete is crucial to be updated and displayed with every keystroke, I believe it's a mistake to treat diagnostics the same way.

While autocomplete is crucial to be updated and displayed with every keystroke, I believe it's a mistake to treat diagnostics the same way.

Absolutely. Having said that - when correcting an error, you do want the instant feedback on every keystroke. You don't want to have to wait/enter/exit input mode to see if your corrections addressed the problem. Hence my comment above re: state transitions.

I would look at this the other way to what is suggested at this thread. I would send updates to the LSP immediately, like it is today. However suppress rendering diagnostics until a break in the typing. This way autocomplete should still be up-to-date however I won't get the unhelpful and distracting s: unknown variable, se: unknown variable, sel: unknown variable, Incorrect return type, expected bool got Self, ...

Having said that - when correcting an error, you do want the instant feedback on every keystroke.

This could also be implemented by having a policy that stale diagnostics can be removed immediately, however new diagnostics aren't shown until a pause in typing.

Added this feature in #982 .

Was this page helpful?
0 / 5 - 0 ratings