commit 724d1110b1e4699a34f489e9cdb2d25098746499
parent fc9b70826ec88ca2e6c0624c522b872e87aa7ac1
Author: Mathias Fußenegger <mfussenegger@users.noreply.github.com>
Date: Thu, 27 Jun 2024 12:20:00 +0200
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
Diffstat:
2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua
@@ -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
diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua
@@ -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 },