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

Completion menu redisplayed after confirming completion with C-y #1282

Closed
radioneko opened this issue Dec 14, 2014 · 17 comments · Fixed by #2657
Closed

Completion menu redisplayed after confirming completion with C-y #1282

radioneko opened this issue Dec 14, 2014 · 17 comments · Fixed by #2657

Comments

@radioneko
Copy link

Steps to reproduce:

  • select completion from menu with tab/s-tab
  • confirm it by pressing C-y

After this completion menu popping again showing matches for word that was just inserted (including this word itself, so menu always has at least one item). If completion is aborted with C-e, no additional menus shown.

@radioneko
Copy link
Author

It seems that second menu is semantic completion (ie just like C-Space was pressed immediately after C-y)

@vheon
Copy link
Contributor

vheon commented Dec 14, 2014

I don't understand the need to confirm the completion using <C-y>. That is not the way YCM is designed to work. When you select the completion with <Tab> you don't need to do anything more that that. I think I'm going to close this issue since is basically a duplicate of #1272 and that is been closed as well by @Valloric.

@vheon vheon closed this as completed Dec 14, 2014
@radioneko
Copy link
Author

Sometimes I really need to insert some alignment with <Tab> right after completed name. Currently there're three workarounds which aren't convenient:

  • double <C-y>
  • <Space> followed by <Tab>
  • don't use tab for menu navigation

@vheon
Copy link
Contributor

vheon commented Dec 14, 2014

Ok, I reopened this and we'll wait and see what @Valloric thinks about this.

@vheon vheon reopened this Dec 14, 2014
@Liangzhi233
Copy link

Here is a situation where I need <c-y>. I use <tab> both for cycling through candidates in ycm and placeholders in ultisnips. But after ycm giving me some candidates, I cannot jump to next placeholder without closing the popup menu.

By the way, #1272 works perfect, and introduce little complexity in my opinion

@radioneko
Copy link
Author

I have some luck in fixing it but this requres patching vim.
This double menu appears only because heuristics is used to detect line change: s:BufferTextChangedSinceLastMoveInInsertMode verifying current line length to detect if there was a change made in insert mode. When you accept completion with <C-y> line length suddenly changes (I suspect CursorHoldI is not called when pum menu is visible but haven't checked this).
My idea of fixing is just to forbid completion in s:AllowedToCompleteInCurrentFile if last key event caused accepting item from complete menu.
So I added variable to vim which is set to TRUE when <C-y> accepted pum menu item and reset to FALSE at before next key is read from edit() function. Then there's a VimL function for quering his flag value. And finally I've modified s:AllowedToCompleteInCurrentFile:

function! s:AllowedToCompleteInCurrentFile()
...
  " Make sure we don't double showing completion menu
  if exists( '*pumjustaccepted' ) && pumjustaccepted()
    return 0
  endif

  return whitelist_allows && blacklist_allows
endfunction

Maybe someone could point out better way for resolving this issue that could be accepted by vim upstream?

@vheon
Copy link
Contributor

vheon commented Dec 16, 2014

I suspect CursorHoldI is not called when pum menu is visible but haven't checked this

That is correct.

Personally I don't think that patching vim this way is the right thing to do.

EDIT: There's something similar to the pumjustaccepted() function but is an autocmd (:h CompleteDone) maybe we could thing something about that but I don't know if it will be a clean patch to YCM.

@Liangzhi233
Copy link

@radioneko is right, the second popup menu shows because first <c-y> changes the input text. Why not disable showing the candidate if it's exactly same as the word you just input? By this method, the second menu will not show, because all its candidates are same as your input. This solution only needs one python expression
results = filter(lambda a:a.get('abbr', a['word'])!=baseText or a.get('menu'), results)
added in autoload/youcompleteme.vim

@vheon
Copy link
Contributor

vheon commented Dec 16, 2014

This solution only needs one python expression
results = filter(lambda a:a.get('abbr', a['word'])!=baseText or a.get('menu'), results)
added in autoload/youcompleteme.vim

@LiangZhi1027 The fact that is only one line doesn't mean that is a simple and clean way to fix it. That line needs to be maintained by someone who is not you. In the meantime you could always use <C-y> to select the candidate and cancel the second popup with <C-e>.

@radioneko
Copy link
Author

@LiangZhi1027: imagine you have following candidates: ['free', 'free_foo', 'free_bar']. You type fr and want to complete to free. You hit <C-y> on free, then second menu appears suggesting free_foo and free_bar.
@vheon agreed. The only thing that confuses me is that first completion menu in not semantic (ie functions not showing their prototypes), and second menu that pops is semantic (it shows function prototypes and has much more indentifiers for completion).

@Liangzhi233
Copy link

@radioneko Thanks for this example. I didn't consider it. So my solution isn't right :(

@radioneko
Copy link
Author

I have patches for (g)vim and youcompleteme, so if anyone wants try it:
ycm patch (doesn't produce errors with unpatched vim) https://github.com/radioneko/gentoo-overlay/blob/master/app-editors/vim/files/vim-ycm-hack.patch
vim/gvim patch: https://github.com/radioneko/gentoo-overlay/blob/master/app-vim/youcompleteme/files/ycm-double-pum.patch

@vheon
Copy link
Contributor

vheon commented Dec 16, 2014

@radioneko @Liangzhi233 Actually I think I just solve this without patching vim. The problem is that it require to call the s:UpdateCursorMoved() function which is not callable from outside. Anyway I just added this inside autoload/youcompleteme.vim and all seems to work:

function! CtrlY()
  if pumvisible()
    call s:UpdateCursorMoved()
  endif
  return "\<C-y>"
endfunction
inoremap <expr> <C-y> CtrlY()

@blueyed
Copy link
Contributor

blueyed commented Jan 25, 2015

I had a similar problem, where <c-x><c-u> (manually calling the completion) does not work after <c-w> (which closes the completion menu, but does not move the cursor):

In youcompleteme#EnableCursorMovedAutocommands(), add this:

autocmd CompleteDone * let s:old_cursor_position = []

See blueyed@3d035e9

I hope it works for your case - I could not reproduce the issue.

blueyed added a commit to blueyed/YouCompleteMe that referenced this issue Feb 4, 2015
This is required to properly handle the pum after manually invoking the
completion and using e.g. <C-w> to delete the word; this won't trigger
CursorMovedI.

Ref: ycm-core#1282 (comment)
@blueyed
Copy link
Contributor

blueyed commented Feb 4, 2015

Update: the method from my previous comment did not work properly. I have changed it to call s:UpdateCursorMoved explicitly from the *Complete functions.

@przepompownia
Copy link

This issue is still relevant. I tested it with disabled another plugins to eliminate another potential causes of displaying menu:
LC_MESSAGES=C vim -i NONE -u ~/.vim/vimrc-test-with-sys-rtp /tmp/ssh_config
where

 $ cat ~/.vim/vimrc-test-with-sys-rtp
" vim: filetype=vim
set nocp
filetype plugin indent on
syntax on
set mouse=a
set runtimepath=/usr/share/vim/vimfiles,/usr/share/vim/vim74,/usr/share/vim/vimfiles/after
set runtimepath+=~/.vim/bundle/YouCompleteMe

ssh_config is detected as sshconfig filetype and contains only two words: Host and Hostname which become menu items after typing Ho in another place. To close menu (without typing character such as whole string does not match to any item) I must press Ctrl-y twice. It does not depend on whether I cycle through items using TAB or Ctrl-N.

I also tried

inoremap <expr> <CR> pumvisible() ? "\<C-Y>" : "\<CR>"

and I must confirm using Enter twice too.

@alvminvm
Copy link

@przepompownia
try this:
inoremap <expr> <CR> pumvisible() ? "\<C-Y>\<ESC>a" : "\<CR>"

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.

6 participants