-
Notifications
You must be signed in to change notification settings - Fork 363
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
Manual whole-line completion with ^X^L inserts the wrong entry into the buffer. #1326
Comments
Hm... To be honest, I can't understand the root cause (but reproduced).
I think the above option will improve the behavior. Could you try this? |
I added that line at the beginning of the minimal reproducible config from above, but the bug is still happening. Is it possible, as a workaround, to completely disable Another workaround is to use https://github.com/amarakon/nvim-cmp-buffer-lines but that doesn't currently work for large files. |
if has('vim_starting')
set encoding=utf-8
endif
scriptencoding utf-8
if &compatible
set nocompatible
endif
let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end
execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-buffer'
call plug#end()
PlugInstall | quit
set completeopt=menu,menuone,noselect
" Setup global configuration. More on configuration below.
lua << EOF
local cmp = require "cmp"
cmp.setup {
mapping = {
['<CR>'] = cmp.mapping.confirm({ select = true })
},
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "buffer" },
}),
}
EOF In my environment, the above setup solve this problem. |
I've just tried it with that file, i.e. Sometimes, another weird thing happens: I press to insert a line, but nothing happens, as if I hadn't pressed any key at all. |
I just noticed that the same problem (the wrong entry gets selected) occurs when using repeated ^X^P selection, i.e. ^X^P^X^P^X^P to select words that appear in the file in a sequence. In my books, this is a much more serious problem than ^X^L not working. On the plus, side, I think I found a workaround that actually works: when the entry is already selected, I can just keep writing, and the correct selection keeps being inserted. In other words, as long as I avoid the Enter key, nothing bad happens. Obviously, that makes using Another idea how to solve this: would it be possible to completely disable nvim-cmp for manual completion? I think, this would be an intuitive solution for everyone who is already used to manual completion. |
Okay, so here's a hacky workaround that seems to work for me for now and actually lets me use ['<CR>'] = function(fallback) -- ugly workaround because manual completion (not only ^X^L) is broken!
if cmp.visible() and cmp.get_active_entry() then
cmp.select_next_item({ behavior = cmp.SelectBehavior.Insert })
cmp.select_prev_item({ behavior = cmp.SelectBehavior.Insert })
vim.cmd([[call feedkeys("\<Space>\<BS>")]])
else
fallback()
end
end, |
Sorry to spam this issue with workarounds instead of fixing it, but I noticed that my last attempt at a workaround isn't suitable, because it destroys i.a. the snippet functionality. Here's a better way which so far seems to work perfectly: ['<CR>'] = function(fallback) -- ugly workaround for nvim-cmp bug that selects wrong entry for manual completion
if vim.fn.complete_info().mode ~= '' then
cmp.select_next_item({ behavior = cmp.SelectBehavior.Insert })
cmp.select_prev_item({ behavior = cmp.SelectBehavior.Insert })
vim.cmd([[call feedkeys("\<Space>\<BS>")]])
else
if not cmp.confirm({ select = false }) then fallback() end
end
end, I didn't find a way to check if cmp is active, but the check on |
Could you please provide detailed steps to reproduce? |
Ok, I'll try again: Here's an exact sequence of keystrokes which I can use to reproduce. I've tried this several times and the result is the same every time.
where the last line is blank. Now, in the shell, input: nvim --clean -u init.vim.nvim-cmp-1326-reproduce nvim-cmp-1326-input-file and then in neovim, the following keypresses: Instead of |
@bagohart Yes. Your reproduction steps can be reproduced the problem. I think it's depending on to the (Sorry. In my previous post, I wrote |
The bug is happening with this setting for completeopt, too.
To reproduce: |
Hi! I am facing the same issue. I find the bug is happening if you move backward in any native completion menu. As an example, if you press I tried playing around with Running Neovim 0.8.2 on Fedora:
|
@bagohart, is this still reproducing for you using your minimal config from #1326 (comment) on latest In my observation, the base error also doesn't seem to be an off-by-1 error, but rather a sign error (it seems to reliably reverse top/bottom of menu). It can be hard to notice because the order of the menu changes and this can make it seem more like an off-by-n. I detail more about that in the duplicate issue I filed before finding this one. This is close to the behavior described by @hmrks but is different in that the behavior I observe does not occur with @hmrks As another user, I do not see the same behavior with
OS: WSL2 running Arch Linux on Win 11 |
Yes, it still reproduces with the same example and procedure described above, still using the same file
I think I am on the same nvim version:
|
Snippets for debugging.
With the above mapping, you can hit In
Testing just the |
Repro configCLICK ON ME! Click to expand and save as `repro_nvim_cmp_vimrc`if has('vim_starting')
set encoding=utf-8
endif
scriptencoding utf-8
if &compatible
set nocompatible
endif
let s:plug_dir = expand('/tmp/plugged/vim-plug')
if !filereadable(s:plug_dir .. '/plug.vim')
execute printf('!curl -fLo %s/autoload/plug.vim --create-dirs https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim', s:plug_dir)
end
execute 'set runtimepath+=' . s:plug_dir
call plug#begin(s:plug_dir)
Plug 'hrsh7th/nvim-cmp'
Plug 'hrsh7th/cmp-buffer'
call plug#end()
PlugInstall | quit
set completeopt=menu,menuone,noselect
" Setup global configuration. More on configuration below.
lua << EOF
local cmp = require "cmp"
cmp.setup {
mapping = cmp.mapping.preset.insert({
['<CR>'] = cmp.mapping.confirm({ select = true })
}),
sources = cmp.config.sources({
{ name = "nvim_lsp" },
{ name = "buffer" },
}),
}
EOF
imap \ <cmd>put =execute('lua print(vim.fn.complete_info({''selected''}).selected)')<CR>
imap [ <cmd>lua require('cmp.utils.feedkeys').call(require('cmp.utils.keymap').t(string.rep('<C-P>',1)),'in')<CR>
nmap \\ iaaa<CR>bbb<CR>ccc<CR>ddd<CR>eee<CR> Note the 3 maps, Repro Steps
|
Some more investigation. I think this is a subtle upstream bug affecting the scripting interface for |
for now, here's a different, only slightly less hacky workaround than sending mapping = cmp.mapping.preset.insert({
-- cmp.mapping.preset.insert provides <C-N>, <C-P>, etc
['<C-d>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<CR>'] = function(fallback)
if vim.fn.pumvisible() == 1 then
-- native pumenu
-- workaround for neovim/neovim#22892
if vim.fn.complete_info({'selected'}).selected == -1 then
-- nothing selected, insert newline
feedkeys.call(keymap.t('<CR>'), 'in')
else
-- something selected, confirm selection by stopping Ctrl-X mode
-- :h i_CTRL-X_CTRL-Z*
feedkeys.call(keymap.t('<C-X><C-Z>'), 'in')
end
else
-- `nvim-cmp` default confirm action
-- Accept currently selected item.
-- Set `select` to `false` to only confirm explicitly selected items.
cmp.mapping.confirm({ select = false })(fallback)
end
end
}), You'll need to put the following local cmp = require'cmp'
local feedkeys = require('cmp.utils.feedkeys')
local keymap = require('cmp.utils.keymap') Alright, now I'll stop spamming this thread. Hopefully upstream will fix the underlying issue and then we can get a better sense of if anything needs to change in |
@d-r-a-b is great. I checked the vim issue thread. thank you! |
added fix from: hrsh7th/nvim-cmp#1326 (comment)
@d-r-a-b I'm now on neovim 0.9.4 and cannot reproduce the bug anymore, with neither Edit: nevermind, it still doesn't work. I tried to remove the mapping, but didn't realize that it was then shadowed by another plugin, and that seemed to make the bug disappear. But it's still there. |
FAQ
Announcement
Minimal reproducible full config
Description
Hi,
Cool plugin! I've tried it this week for using it with LSP and really like it so far.
My only problem is that it breaks manual whole-line completion.
This seems to happen independently of other plugins, filetype, file content and doesn't depend on if the autocompletion menu was open or not.
So when I type (
^X^L
) to start manual line completion, then the automatic completion menu is dismissed (if it was visible), and the manual line completion menu appears, and then I can use<C-p>
and<C-n>
to select an entry, but when I press<CR>
to accept the selected line, then a different line is inserted. This does not always happen, but in more than 50% of my attempts. I tried it with different settings for'completeopt'
and even tried to override<CR>
to be used only when the menu is visible usingcmp.core.view:visible()
, but it made no difference. Sometimes it seems to be an off-by-one selection, but sometimes the inserted text is farther away. It happens when the line is empty, and if there's something written to complete. I've spent about 2 hours trying to fix this, and have no idea what's happening here.Steps to reproduce
nvim -u ~/cmp-repro.vim ~/cmp-repro.vim
Insert two empty lines at the beginning of the file, go to first line.
Press
^X^L
and use^P
or^N
to choose some entry.Select the entry with
<CR>
.Expected behavior
The selected line should be inserted in the buffer.
Actual behavior
Another line that was not selected is inserted in the buffer.
Additional context
Output of
:version
:Running on Manjaro XFCE.
The text was updated successfully, but these errors were encountered: