fix(lsp): pre-filter matches on label if filterText is missing (#29491)

Although the built-in pum completion mechanism will filter anyway on the
next input it is odd if the initial popup shows entries which don't
match the current prefix.

Using fuzzy match on the label/prefix is compatible with
`completeopt+=fuzzy` and also doesn't seem to break postfix snippet
cases

Closes https://github.com/neovim/neovim/issues/29287
This commit is contained in:
Mathias Fußenegger 2024-06-27 12:20:00 +02:00 committed by GitHub
parent fc9b70826e
commit 724d1110b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 33 additions and 6 deletions

View File

@ -235,14 +235,20 @@ function M._lsp_to_complete_items(result, prefix, client_id)
return {}
end
local matches = prefix == '' and function()
return true
end or function(item)
if item.filterText then
return next(vim.fn.matchfuzzy({ item.filterText }, prefix))
---@type fun(item: lsp.CompletionItem):boolean
local matches
if prefix == '' then
matches = function(_)
return true
end
else
---@param item lsp.CompletionItem
matches = function(item)
local text = item.filterText or item.label
return next(vim.fn.matchfuzzy({ text }, prefix)) ~= nil
end
return true
end
local candidates = {}
for _, item in ipairs(items) do
if matches(item) then

View File

@ -141,6 +141,27 @@ describe('vim.lsp.completion: item conversion', function()
eq(expected, result)
end)
it('filters on label if filterText is missing', function()
local completion_list = {
{ label = 'foo' },
{ label = 'bar' },
}
local result = complete('fo|', completion_list)
local expected = {
{
abbr = 'foo',
word = 'foo',
},
}
result = vim.tbl_map(function(x)
return {
abbr = x.abbr,
word = x.word,
}
end, result.items)
eq(expected, result)
end)
it('trims trailing newline or tab from textEdit', function()
local range0 = {
start = { line = 0, character = 0 },