fix(lsp): tune completion word extraction for decorated labels (#29331)

Problem:

For snippets lsp.completion prefers the label if it is shorter than the
insertText or textEdit to support postfix completion cases but clangd
adds decoration characters to labels. E.g.: `•INT16_C(c)`

Solution:

Use parse_snippet on insertText/textEdit before checking if it is
shorter than the label.

Fixes https://github.com/neovim/neovim/issues/29301
This commit is contained in:
Mathias Fußenegger
2024-06-14 19:32:34 +02:00
committed by GitHub
parent ba70404c55
commit aa47af7e69
2 changed files with 18 additions and 3 deletions

View File

@ -145,8 +145,8 @@ local function get_completion_word(item)
-- label: insert
--
-- Typing `i` would remove the candidate because newText starts with `t`.
local text = item.insertText or item.textEdit.newText
return #text < #item.label and text or item.label
local text = parse_snippet(item.insertText or item.textEdit.newText)
return #text < #item.label and vim.fn.matchstr(text, '\\k*') or item.label
elseif item.insertText and item.insertText ~= '' then
return parse_snippet(item.insertText)
else

View File

@ -81,10 +81,21 @@ describe('vim.lsp.completion: item conversion', function()
-- plain text
{
label = 'foocar',
sortText = 'k',
sortText = 'g',
insertText = 'foodar(${1:var1})',
insertTextFormat = 1,
},
{
label = '•INT16_C(c)',
insertText = 'INT16_C(${1:c})',
insertTextFormat = 2,
filterText = 'INT16_C',
sortText = 'h',
textEdit = {
newText = 'INT16_C(${1:c})',
range = range0,
},
},
}
local expected = {
{
@ -115,6 +126,10 @@ describe('vim.lsp.completion: item conversion', function()
abbr = 'foocar',
word = 'foodar(${1:var1})', -- marked as PlainText, text is used as is
},
{
abbr = '•INT16_C(c)',
word = 'INT16_C',
},
}
local result = complete('|', completion_list)
result = vim.tbl_map(function(x)