Setting mapping in `cmp.setup.cmdline({'/', '?'}, {` prevents command tab completion from working after search
FAQ
- [X] I have checked the FAQ and it didn't resolve my problem.
Announcement
- [X] I have checked Breaking change announcement.
Minimal reproducible full config
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'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-cmdline'
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-calc'
call plug#end()
PlugInstall | quit
" 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" },
}),
}
local capabilities = require('cmp_nvim_lsp').default_capabilities()
cmp.setup.cmdline({'/', '?'}, {
-- setting mapping causes the issue of :e %^I after / search
mapping = cmp.mapping.preset.cmdline(),
sources = {
{ name = 'buffer' }
}
})
EOF
Description
When mapping = cmp.mapping.preset.cmdline(), is provided to the /, ? cmp cmdlines, after searching once tab completion in the vim commandline stops working and prints ^I instead. If you remove the mapping then the problem won't trigger.
Steps to reproduce
- Open some file with nvim using attached minimal config
- Verify that
:e %<tab>will actually tab-expand%to current filename. - Perform search using
/foo<CR>or equivalent; verify that:e %<tab>will not work anymore and instead, print^Iper tab invocation. - Comment out mapping line in example config and verify (3) above cannot be reproduced.
Expected behavior
:e %<tab> will expand current filename after performing at least one search
Actual behavior
:e %<tab> will expand to :e %^I which is not expected.
Additional context
I don't know the significance of the mapping attribute for the search cmdline config but I merely copy-pasted it from the reference manual/README.
I also have this bug.
I also have the same issue but I found this answer suggesting to specify the cmdline source option in a different way:
cmp.setup.cmdline(':', {
sources = {
{
name = 'cmdline',
option = {
ignore_cmds = {}
}
}
}
})
I tried it and so far it seems to be working but haven't had a chance to test it extensively.
@rhaidiz Adding that doesn't do anything for me. Builtin cmdline completion still breaks after using completion in / or ? once.
Yeah indeed, that snippet made it work for me on editor open but it breaks after searching.
I tried manually setting mappings for / and ? but I don't seem to be able to find the necessary code to get it to even work 😅
My guess is that the mappings from ? and / are also used for : once it has been triggered once, as when I add mapping = cmp.mapping.preset.cmdline() to the : cmdline option, it breaks from the start of the editor.
I also have this bug
I'm sorry, but this is the specification.
In Vim's cmdline mode, key mappings for : and / are not separated by namespace, so enabling cmp for / also enables key mappings for :. The only solution is to enable cmp-cmdline for :. However, this may not achieve full compatibility with existing cmdline behavior.
At this point, there is no complete solution and there are trade-offs. Please understand.
Workaround.
cmp.setup.cmdline(':', {
autocomplete = false,
sources = {
{ name = 'cmdline' }
}
})
I don't think I have this behaviour, completion in : works fine after /. But I've found another bug: completion menu appears but no selection can be made if the command string has no space in it. :%s Some — I will get a working completion menu (it's not a valid search/replace string still). On :%s/Some completion menu will appear but nothing can be selected. mapping = cmp.mapping.preset.cmdline(), nothing fancy here.
this workaround works for me:
found here
vim.keymap.set('c', '
@ehbLuca You should use code formatting to paste code, in your snippet the LHS and RHS of the mapping got eaten. Here is the full mapping:
vim.keymap.set('c', '<tab>', '<C-z>', { silent = false }) -- to fix cmp
Can confirm this works for me.