mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
perf(lsp): don't copy completion items in filter pass
This commit is contained in:
committed by
Mathias Fußenegger
parent
1d091e52f0
commit
cc1f2d2ca6
@ -201,6 +201,24 @@ local function get_items(result)
|
||||
end
|
||||
end
|
||||
|
||||
---@param item lsp.CompletionItem
|
||||
---@return string
|
||||
local function get_doc(item)
|
||||
local doc = item.documentation
|
||||
if not doc then
|
||||
return ''
|
||||
end
|
||||
if type(doc) == 'string' then
|
||||
return doc
|
||||
end
|
||||
if type(doc) == 'table' and type(doc.value) == 'string' then
|
||||
return doc.value
|
||||
end
|
||||
|
||||
vim.notify('invalid documentation value: ' .. vim.inspect(doc), vim.log.levels.WARN)
|
||||
return ''
|
||||
end
|
||||
|
||||
--- Turns the result of a `textDocument/completion` request into vim-compatible
|
||||
--- |complete-items|.
|
||||
---
|
||||
@ -216,44 +234,24 @@ function M._lsp_to_complete_items(result, prefix, client_id)
|
||||
return {}
|
||||
end
|
||||
|
||||
if prefix ~= '' then
|
||||
---@param item lsp.CompletionItem
|
||||
local function match_prefix(item)
|
||||
local matches = prefix == '' and function()
|
||||
return true
|
||||
end or function(item)
|
||||
if item.filterText then
|
||||
return next(vim.fn.matchfuzzy({ item.filterText }, prefix))
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
items = vim.tbl_filter(match_prefix, items) --[[@as lsp.CompletionItem[]|]]
|
||||
end
|
||||
table.sort(items, function(a, b)
|
||||
return (a.sortText or a.label) < (b.sortText or b.label)
|
||||
end)
|
||||
|
||||
local matches = {}
|
||||
local candidates = {}
|
||||
for _, item in ipairs(items) do
|
||||
local info = ''
|
||||
local documentation = item.documentation
|
||||
if documentation then
|
||||
if type(documentation) == 'string' and documentation ~= '' then
|
||||
info = documentation
|
||||
elseif type(documentation) == 'table' and type(documentation.value) == 'string' then
|
||||
info = documentation.value
|
||||
else
|
||||
vim.notify(
|
||||
('invalid documentation value %s'):format(vim.inspect(documentation)),
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
end
|
||||
end
|
||||
if matches(item) then
|
||||
local word = get_completion_word(item)
|
||||
table.insert(matches, {
|
||||
table.insert(candidates, {
|
||||
word = word,
|
||||
abbr = item.label,
|
||||
kind = protocol.CompletionItemKind[item.kind] or 'Unknown',
|
||||
menu = item.detail or '',
|
||||
info = #info > 0 and info or '',
|
||||
info = get_doc(item),
|
||||
icase = 1,
|
||||
dup = 1,
|
||||
empty = 1,
|
||||
@ -267,7 +265,17 @@ function M._lsp_to_complete_items(result, prefix, client_id)
|
||||
},
|
||||
})
|
||||
end
|
||||
return matches
|
||||
end
|
||||
---@diagnostic disable-next-line: no-unknown
|
||||
table.sort(candidates, function(a, b)
|
||||
---@type lsp.CompletionItem
|
||||
local itema = a.user_data.nvim.lsp.completion_item
|
||||
---@type lsp.CompletionItem
|
||||
local itemb = b.user_data.nvim.lsp.completion_item
|
||||
return (itema.sortText or itema.label) < (itemb.sortText or itemb.label)
|
||||
end)
|
||||
|
||||
return candidates
|
||||
end
|
||||
|
||||
--- @param lnum integer 0-indexed
|
||||
|
Reference in New Issue
Block a user