nvim-cmp
nvim-cmp copied to clipboard
Using the autocomplete menu removes the completion when using GDScript LSP Server
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-buffer'
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 = {
['<CR>'] = cmp.mapping.confirm({ select = true }),
["<Tab>"] = cmp.mapping(function(fallback)
if cmp.visible() then
cmp.select_next_item()
elseif vim.fn["vsnip#available"](1) == 1 then
feedkey("<Plug>(vsnip-expand-or-jump)", "")
elseif has_words_before() then
cmp.complete()
else
fallback() -- The fallback function sends a already mapped key. In this case, it's probably `<Tab>`.
end
end, { "i", "s" }),
["<S-Tab>"] = cmp.mapping(function()
if cmp.visible() then
cmp.select_prev_item()
elseif vim.fn["vsnip#jumpable"](-1) == 1 then
feedkey("<Plug>(vsnip-jump-prev)", "")
end
end, { "i", "s" }),
},
sources = {
{ name = "nvim_lsp" },
{ name = "buffer" },
},
}
EOF
lua << EOF
local capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities())
require'lspconfig'.gdscript.setup {
capabilities = capabilities,
}
EOF
Description
If you press <CR>
without navigating through the autocomplete menu with <TAB>
, it will autocomplete the first selection without issues:
The problem occurs when you navigate through the autocomplete menu and press <CR>
when a item is selected:
Steps to reproduce
With the minimal config provided earlier:
- Download Godot https://godotengine.org/download
- Clone the repository with godot example projects https://github.com/godotengine/godot-demo-projects
- Open the project godot-demo-projects/2d/bullet_shower in Godot (otherwise the GDScript LSP server will not work).
- Open the file godot-demo-projects/2d/bullet_shower/bullets.gd in neovim with the minimal config provided.
- Try to autocomplete some constant or variable with and without navigating through the autocomplete menu.
Expected behavior
It should complete the selected item in the autocomplete menu without any issue.
Actual behavior
It does not complete the selected item, only works when you press <CR>
without navigating through the menu.
Additional context
I have been digging into this problem before creating this issue, and what I have found is that the LSP server only returns a label
without any insert_text
in the LSP type completionItem/resolve
.
Then the neovim lsp client or nvim-cmp creates a CompletionItem where the property insert_text
is an empty string.
Then I found that the "problem" was in this line: https://github.com/hrsh7th/nvim-cmp/blob/main/lua/cmp/core.lua#L414
If I replace that line with the next code, it solves the problem but I don't know if it can cause issues with others LSP servers or sources from nvim-cmp.
local insertText = misc.safe(completion_item.insertText)
if misc.empty(insertText) then
insertText = nil
end
completion_item.textEdit.newText = insertText or completion_item.word or
completion_item.label
I got through this solution with the LSP Spec:
/**
* The label of this completion item.
*
* The label property is also by default the text that
* is inserted when selecting this completion.
*
* If label details are provided the label itself should
* be an unqualified name of the completion item.
*/
label: string;
https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#completionItem
My knowledge about the LSP Protocol and Lua is limited so maybe this is not correct.
Thank you for detailed investigation.
Hm... In my eyes, it's bug of language server side... but I hope to support this case (if it's rational).
Could you put the godot response?
Sorry for the long delay,
here is the godot response:
[DEBUG][2022-11-08 19:20:52] .../lua/vim/lsp.lua:1388 "LSP[gdscript]" "client.request" 2 "completionItem/resolve" { data = { position = { character = 1, line = 12 }, textDocument = { uri = "file:///home/forazens/Downloads/godot-demo-projects/2d/bullet_shower/bullets.gd" } }, kind = 21, label = "SPEED_MAX"} <function 1> 8
[DEBUG][2022-11-08 19:20:52] .../lua/vim/lsp.lua:1388 "LSP[gdscript]" "client.request" 2 "workspace/executeCommand" { command = "", title = ""} <function 1> 8
Thanks for sharing your findings @ForAzens - I was just trying to figure this out too
I am sorry to be that person @hrsh7th, just want to follow up on to help move this issue forward (resolving it would help me greatly). Based on the godot response that @ForAzens shared above, do you think there is anything that can be done in nvim-cmp
to support this or is this something the godot engine needs to address in their LSP implementation? Since I'm bugging you let me also take the opportunity to sincerely say thank you for nvim-cmp
and the work you do on it.