nvim-cmp
nvim-cmp copied to clipboard
Snippet source shows up in preview before confirming
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
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-nvim-lsp'
Plug 'hrsh7th/vim-vsnip'
Plug 'neovim/nvim-lspconfig'
call plug#end()
PlugInstall | quit
" Setup global configuration. More on configuration below.
lua << EOF
local cmp = require "cmp"
cmp.setup {
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body)
end,
},
mapping = {
['<C-n>'] = cmp.mapping.select_next_item(),
['<CR>'] = cmp.mapping.confirm({ select = true })
},
preselect = cmp.PreselectMode.None,
sources = cmp.config.sources({
{ name = "nvim_lsp" },
}),
}
EOF
lua << EOF
local capabilities = require('cmp_nvim_lsp').default_capabilities()
require'lspconfig'.rust_analyzer.setup {
capabilities = capabilities,
}
EOF
Description
In a Rust project, when auto-completing on a function that has parameters, the snippet source code gets pasted into the main buffer when using cmp.mapping.select_next_item()
Steps to reproduce
- Initialize a rust (cargo) project with
cargo init test-proj
- Replace the contents of
main.rs
with this:fn f(a: u8, b: u8) {} fn main() { }
- Place cursor in
main()
, go into insert mode, and pressf
to trigger autocomplete on the functionf
(wait for rust_analyzer to load first). - Press
<C-n>
to runcmp.mapping.select_next_item()
, and then just move the cursor elsewhere. The buffer now reads:fn f(a: u8, b: u8) {} fn main() { f(${1:a}, ${2:b})$0 }
Expected behavior
I'm not sure what's the expected behavior here, but if I had the choice I would like there to be either nothing printed or something neater printed.
Actual behavior
The source code of the snippet gets printed into the editing buffer, and stays there if the user moves the cursor away mid-selection.
Additional context
If the user confirms the selection with <CR>
right after pressing <C-n>
, then the snippet source will be replaced with the correct output, which is the snippet in action and the cursor highlighting the first argument, a
.
After a quick bisect I found the breaking commit to be 51260c0 and this particular patch fixes this particular issue, though I don't know if it introduces new ones (it does still pass all tests):
diff --git a/lua/cmp/entry.lua b/lua/cmp/entry.lua
index 09946f2..800e408 100644
--- a/lua/cmp/entry.lua
+++ b/lua/cmp/entry.lua
@@ -116,7 +116,7 @@ entry.get_word = function(self)
word = str.trim(self:get_completion_item().textEdit.newText)
local overwrite = self:get_overwrite()
if 0 < overwrite[2] or self:get_completion_item().insertTextFormat == types.lsp.InsertTextFormat.Snippet then
- word = str.get_word(word, string.byte(self.context.cursor_after_line, 1), overwrite[1] or 0)
+ word = str.get_word(vim.lsp.util.parse_snippet(word), string.byte(self.context.cursor_after_line, 1), overwrite[1] or 0)
end
elseif not misc.empty(self:get_completion_item().insertText) then
word = str.trim(self:get_completion_item().insertText)
hey, I found that the default SelectBahavior
is Insert
.
If you want the same behavior with Up/Down
, you can set:
local types = require("cmp.types")
['<C-n>'] = cmp.select_next_item({ behavior = types.cmp.SelectBehavior.Select })
Same issue for nevom nightly, but works as expected for version 0.9.6
I'll fix it. sorry for late.
Thanks for your reply!
But after updating the plugin, neovim version 0.9.6 may occur the following error message when completion is triggered.
...local/share/nvim/lazy/nvim-cmp/lua/cmp/utils/snippet.lua:27: attempt to call field 'list_cont
ains' (a nil value)
And with neovim nightly, the problem still exists...
Thanks for your reply!
But after updating the plugin, neovim version 0.9.6 may occur the following error message when completion is triggered.
...local/share/nvim/lazy/nvim-cmp/lua/cmp/utils/snippet.lua:27: attempt to call field 'list_cont ains' (a nil value) And with neovim nightly, the problem still exists...
@hrsh7th Updates: The problem is not fixed for neovim nightly. And it works as expected for neovim 0.9.6.
No. It's fixed.
@hrsh7th Tested with my config, finding that the problem only occurs with an empty option of the select_next_item, such as:
["<C-k>"] = cmp.mapping.select_prev_item(),
["<C-j>"] = cmp.mapping.select_next_item(),
But if I fill the options with either Insert or Select, that works as expected.
["<C-k>"] = cmp.mapping.select_prev_item({ behavior = cmp.SelectBehavior.Insert }), -- or Select
["<C-j>"] = cmp.mapping.select_next_item({ behavior = cmp.SelectBehavior.Insert }), -- or Select
No, the implementation allows you to omit the argument. https://github.com/hrsh7th/nvim-cmp/blob/main/lua/cmp/init.lua#L132
@hrsh7th Seems the problem only occurs if I set the cmp_nvim_lsp.default_capabilities()
with clangd server capabilities. Comment the follwing line in my configuration works:
-- Merge cmp & server configured capabilities
server_opts.capabilities = vim.tbl_deep_extend(
"force",
{},
vim.lsp.protocol.make_client_capabilities(),
has_cmp and cmp_nvim_lsp.default_capabilities() or {},
server_opts.server_capabilities or {}
)
I will try to fix it. Thanks any way!