feat(lsp): user-specified sorting of lsp.completion multi-server results #36401

Problem: No way to customize completion order across multiple servers.

Solution: Add `cmp` function to `vim.lsp.completion.enable()` options
for custom sorting logic.
This commit is contained in:
glepnir
2025-11-19 13:38:53 +08:00
committed by GitHub
parent 2c04ae9fcc
commit c22b03c771
4 changed files with 49 additions and 11 deletions

View File

@@ -810,7 +810,7 @@ end)
--- @param name string
--- @param completion_result lsp.CompletionList
--- @param opts? {trigger_chars?: string[], resolve_result?: lsp.CompletionItem, delay?: integer}
--- @param opts? {trigger_chars?: string[], resolve_result?: lsp.CompletionItem, delay?: integer, cmp?: string}
--- @return integer
local function create_server(name, completion_result, opts)
opts = opts or {}
@@ -841,6 +841,10 @@ local function create_server(name, completion_result, opts)
local bufnr = vim.api.nvim_get_current_buf()
vim.api.nvim_win_set_buf(0, bufnr)
local cmp_fn
if opts.cmp then
cmp_fn = assert(loadstring(opts.cmp))
end
return vim.lsp.start({
name = name,
cmd = server.cmd,
@@ -850,6 +854,7 @@ local function create_server(name, completion_result, opts)
convert = function(item)
return { abbr = item.label:gsub('%b()', '') }
end,
cmp = cmp_fn,
})
end,
})
@@ -1190,6 +1195,29 @@ describe('vim.lsp.completion: protocol', function()
end)
end)
it('enable(…,{cmp=fn}) custom sort order', function()
create_server('dummy', {
isIncomplete = false,
items = {
{ label = 'zzz', sortText = 'a' },
{ label = 'aaa', sortText = 'z' },
{ label = 'mmm', sortText = 'm' },
},
}, {
cmp = string.dump(function(a, b)
return a.abbr < b.abbr
end),
})
feed('i')
trigger_at_pos({ 1, 0 })
assert_matches(function(matches)
eq(3, #matches)
eq('aaa', matches[1].abbr)
eq('mmm', matches[2].abbr)
eq('zzz', matches[3].abbr)
end)
end)
it('sends completion context when invoked', function()
local params = exec_lua(function()
local params