fix(lsp): preserve trigger chars on completion #39850

Problem:
After 767fbd8, typing trigger chars would open completion but the
chars were removed.

Solution:
Use filterText fallback so selected item respects typed trigger chars.
This commit is contained in:
glepnir
2026-05-18 17:25:41 +08:00
committed by GitHub
parent d7164eced6
commit 3ffe29d679
2 changed files with 16 additions and 15 deletions

View File

@@ -168,6 +168,13 @@ local function apply_snippet(item)
end
end
local function fallback_filtertext(item, word, prefix, match)
if item.filterText and not match(word, prefix) and match(item.filterText, prefix) then
return item.filterText
end
return word
end
--- Returns text that should be inserted when a selecting completion item. The
--- precedence is as follows: textEdit.newText > insertText > label
---
@@ -200,11 +207,7 @@ local function get_completion_word(item, prefix, match)
item.filterText and vim.fn.match(item.label, '^\\k') == -1 and item.filterText
or item.label
)
if item.filterText and not match(word, prefix) then
return item.filterText
else
return word
end
return fallback_filtertext(item, word, prefix, match)
else
return item.label
end
@@ -212,15 +215,9 @@ local function get_completion_word(item, prefix, match)
local word = item.textEdit.newText
word = string.gsub(word, '\r\n?', '\n')
word = word:match('([^\n]*)') or word
if item.filterText and not match(word, prefix) then
return item.filterText
end
return word
return fallback_filtertext(item, word, prefix, match)
elseif item.insertText and item.insertText ~= '' then
if item.filterText and not match(item.insertText, prefix) then
return item.filterText
end
return item.insertText
return fallback_filtertext(item, item.insertText, prefix, match)
end
return item.label
end

View File

@@ -457,10 +457,14 @@ describe('vim.lsp.completion: item conversion', function()
it('works on non word prefix', function()
local completion_list = {
{ label = ' foo', insertText = '->foo' },
{ label = ' foo', insertText = '->foo', sortText = '1' },
{ label = ' bar', insertText = '->bar', filterText = 'bar', sortText = '2' },
}
local result = complete('wp.|', completion_list, 0, 2)
eq({ { abbr = ' foo', word = '->foo' } }, extract_word_abbr(result.items))
eq({
{ abbr = ' foo', word = '->foo' },
{ abbr = ' bar', word = '->bar' },
}, extract_word_abbr(result.items))
end)
it('trims trailing newline or tab from textEdit', function()