Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[wish-list] using +timers to speedup completion in vim 8. #2500

Closed
skywind3000 opened this issue Jan 10, 2017 · 5 comments · Fixed by #2657
Closed

[wish-list] using +timers to speedup completion in vim 8. #2500

skywind3000 opened this issue Jan 10, 2017 · 5 comments · Fixed by #2657

Comments

@skywind3000
Copy link

skywind3000 commented Jan 10, 2017

People notice that completion in emacs is more smooth than vim.
In spite of client/server architecture in ycm, there is still a http timeout delay which could always get ui stuck.

YCM can get far more snappy by introducing an +timer polling method to deal with the http response:

  1. post http request to ycmd and return immediately.
  2. poll the http response repeatly in an interval (20Hz eg), this will not block the ui
  3. when response returns from ycmd in the timer, if no new characters have been entered or deleted, and cursur is still waiting at the same position, just open the completion popup window directly.
  4. when response returns from ycmd in the timer, and if the text has been changed, or cursor has moved, simply drop the response or select suggestions which is still available (can still match the changed text).

This is exactly what completion packages in Emacs does, ui delay caused by waiting http timeout could be eliminated and completion in vim can get as snappy as emacs.

And YCM will make vim great again !!

@vheon
Copy link
Contributor

vheon commented Jan 10, 2017

YCM can get far more snappy by introducing an +timer polling method to deal with the http response:

when you say this, does it means that you have a prototype and you experienced that is actually more responsive?

@skywind3000
Copy link
Author

skywind3000 commented Jan 11, 2017

There are a lot of prototype for you, you can try emacs-jedi.

Jedi has serious performance issue, I can feel a noticeable latency when I use jedi with YCM.

Each time when I press a dot ".", the cursor can't be moved for nearly 2-4 seconds in YCM
(I know I can still input new characters during that, but the cursor get stucked on the position of "." during that).

But when I try jedi in emacs, every thing works fine, although jedi is slow, but typing and cursor moving
is very fast. The experience is far more better.

@vheon
Copy link
Contributor

vheon commented Jan 11, 2017

There are a lot of prototype for you, you can try emacs-jedi.

That is not a prototype. The fact that it works in one way in emacs does not mean that it would work the same in vim or that it would get the same benefits. Talking to @puremourning it looks like the last time he profile YCM the thing that could cause visible latency is when on large buffer we have to get the content, and transcode it to utf8. So to be clear, I'm not saying that what you're saying is not true, I'm saying that I don't see the data backing it up, and personally when it comes to performance I don't go and change things if I don't have the data showing about what is really slow and why.

@insidewhy
Copy link

poll the http response repeatly in an interval (20Hz eg), this will not block the ui

It would be much better to use vim 8 jobs, the http client would be a job and access the server using ASIO, as soon as the result is ready it would be passed through a channel and callback your vim script immediately.

@puremourning
Copy link
Member

puremourning commented Feb 1, 2017

This is something I want spooking at for async events in the language server. It is a lot of work and requires very modern Vim.

zzbot added a commit that referenced this issue Jun 25, 2017
[READY] Rewrite completion system

There is a number of issues with the current completion system:
 - UI is blocked until the completions are returned by the server, the request timed out, or a key is pressed by the user. This leads to a rough experience when completions take too much time: cursor disappearing and timeout errors (see #2192 and #2574). Users even [increase the timeout by manually editing the `completion_request.py` file](https://github.com/Valloric/YouCompleteMe/blob/master/python/ycm/client/completion_request.py#L30) to avoid these errors, which exacerbate the issue and, in some cases, make the plugin unusable (see #2574).
 - no fuzzy matching from omnifunc when forcing semantic completion. See #961;
 - no fuzzy matching when deleting characters. Vim filtering is used instead:

![completion-bug-deleting-characters](https://cloud.githubusercontent.com/assets/10026824/26276156/f298c6de-3d71-11e7-92da-d22186239c27.gif)
Neovim and MacVim are not affected.
 - completion menu disappears after deleting a character and inserting one:

![completion-bug-reinserting-character](https://cloud.githubusercontent.com/assets/10026824/26276192/b3ed0f7a-3d72-11e7-8c64-523a0a59cbdc.gif)
Neovim and MacVim are not affected.
 - ignore the start column returned by the server. See PR #2489.
 - subject to flickers. This one depends a lot on the version of Vim. Completion is almost flicker-free in Neovim and MacVim. Not too bad in console Vim (except in fast terminal like [alacritty](https://github.com/jwilm/alacritty)). Awful in gVim GTK2 (a bit better on GTK3) and gVim on Windows.

This PR is an attempt at fixing all of these issues while reducing flickers as best as possible (due to how completion works in Vim, a flicker-free experience is impossible to achieve). Here's how:
 - poll for completions using a timer and call `completefunc` once the completions are ready. Use the start column returned by the server in `completefunc`;
 - immediately display the last completions on the `TextChangedI` event to prevent the popup menu disappearing while waiting for the completions. This reduces flickering;
 - use the `InsertCharPre` event to close the completion menu just before inserting a character. This way the `TextChangedI` event is triggered when the character is inserted (this event is not fired when the completion menu is visible). This replaces the `refresh` option set to `always` in `completefunc` and the `s:cursor_moved` hack;
 - remap the backspace key to close the completion menu when deleting a character and thus triggering the `TextChangedI` event;
 - send a request with `force_semantic` set to `True` when forcing semantic completion instead of calling the omnifunc. This fixes the issue where there is no fuzzy matching for custom omnifuncs.

Here's a demo where I added a spin animation on the command line while loading the completions to show that it doesn't block the Vim UI:

![async-completion-for-real](https://cloud.githubusercontent.com/assets/10026824/26277295/0f16a718-3d86-11e7-90f3-8a56bbf53f9f.gif)

Fixes #961.
Fixes #1282.
Fixes #1881.
Fixes #2192.
Fixes #2500.
Fixes #2574.

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/valloric/youcompleteme/2657)
<!-- Reviewable:end -->
@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants