mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +00:00
fix(lsp): autotrigger should only trigger on client's triggerCharacters (#32266)
Problem: autotrigger option of vim.lsp.completion.enable() would trigger all clients, as long as it matched at least one client's triggerCharacters. Solution: trigger only the clients with triggerCharacters matching the character. overtriggering still happens if any client returns isIncomplete=true (this case is more involved). Co-authored-by: Mathias Fussenegger <f.mathias@zignar.net>
This commit is contained in:
@ -518,11 +518,14 @@ local function on_insert_char_pre(handle)
|
||||
end
|
||||
|
||||
local char = api.nvim_get_vvar('char')
|
||||
if not completion_timer and handle.triggers[char] then
|
||||
local matched_clients = handle.triggers[char]
|
||||
if not completion_timer and matched_clients then
|
||||
completion_timer = assert(vim.uv.new_timer())
|
||||
completion_timer:start(25, 0, function()
|
||||
reset_timer()
|
||||
vim.schedule(M.trigger)
|
||||
vim.schedule(function()
|
||||
trigger(api.nvim_get_current_buf(), matched_clients)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
@ -770,13 +770,14 @@ end)
|
||||
|
||||
--- @param name string
|
||||
--- @param completion_result lsp.CompletionList
|
||||
--- @param trigger_chars? string[]
|
||||
--- @return integer
|
||||
local function create_server(name, completion_result)
|
||||
local function create_server(name, completion_result, trigger_chars)
|
||||
return exec_lua(function()
|
||||
local server = _G._create_server({
|
||||
capabilities = {
|
||||
completionProvider = {
|
||||
triggerCharacters = { '.' },
|
||||
triggerCharacters = trigger_chars or { '.' },
|
||||
},
|
||||
},
|
||||
handlers = {
|
||||
@ -793,6 +794,7 @@ local function create_server(name, completion_result)
|
||||
cmd = server.cmd,
|
||||
on_attach = function(client, bufnr0)
|
||||
vim.lsp.completion.enable(true, client.id, bufnr0, {
|
||||
autotrigger = trigger_chars ~= nil,
|
||||
convert = function(item)
|
||||
return { abbr = item.label:gsub('%b()', '') }
|
||||
end,
|
||||
@ -957,6 +959,39 @@ describe('vim.lsp.completion: protocol', function()
|
||||
end)
|
||||
end)
|
||||
|
||||
it('insert char triggers clients matching trigger characters', function()
|
||||
local results1 = {
|
||||
isIncomplete = false,
|
||||
items = {
|
||||
{
|
||||
label = 'hello',
|
||||
},
|
||||
},
|
||||
}
|
||||
create_server('dummy1', results1, { 'e' })
|
||||
local results2 = {
|
||||
isIncomplete = false,
|
||||
items = {
|
||||
{
|
||||
label = 'hallo',
|
||||
},
|
||||
},
|
||||
}
|
||||
create_server('dummy2', results2, { 'h' })
|
||||
|
||||
feed('h')
|
||||
exec_lua(function()
|
||||
vim.v.char = 'h'
|
||||
vim.cmd.startinsert()
|
||||
vim.api.nvim_exec_autocmds('InsertCharPre', {})
|
||||
end)
|
||||
|
||||
assert_matches(function(matches)
|
||||
eq(1, #matches)
|
||||
eq('hallo', matches[1].word)
|
||||
end)
|
||||
end)
|
||||
|
||||
it('executes commands', function()
|
||||
local completion_list = {
|
||||
isIncomplete = false,
|
||||
|
Reference in New Issue
Block a user