mirror of
				https://github.com/neovim/neovim.git
				synced 2025-10-26 12:27:24 +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 |   end | ||||||
|  |  | ||||||
|   local char = api.nvim_get_vvar('char') |   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 = assert(vim.uv.new_timer()) | ||||||
|     completion_timer:start(25, 0, function() |     completion_timer:start(25, 0, function() | ||||||
|       reset_timer() |       reset_timer() | ||||||
|       vim.schedule(M.trigger) |       vim.schedule(function() | ||||||
|  |         trigger(api.nvim_get_current_buf(), matched_clients) | ||||||
|  |       end) | ||||||
|     end) |     end) | ||||||
|   end |   end | ||||||
| end | end | ||||||
|   | |||||||
| @@ -770,13 +770,14 @@ end) | |||||||
|  |  | ||||||
| --- @param name string | --- @param name string | ||||||
| --- @param completion_result lsp.CompletionList | --- @param completion_result lsp.CompletionList | ||||||
|  | --- @param trigger_chars? string[] | ||||||
| --- @return integer | --- @return integer | ||||||
| local function create_server(name, completion_result) | local function create_server(name, completion_result, trigger_chars) | ||||||
|   return exec_lua(function() |   return exec_lua(function() | ||||||
|     local server = _G._create_server({ |     local server = _G._create_server({ | ||||||
|       capabilities = { |       capabilities = { | ||||||
|         completionProvider = { |         completionProvider = { | ||||||
|           triggerCharacters = { '.' }, |           triggerCharacters = trigger_chars or { '.' }, | ||||||
|         }, |         }, | ||||||
|       }, |       }, | ||||||
|       handlers = { |       handlers = { | ||||||
| @@ -793,6 +794,7 @@ local function create_server(name, completion_result) | |||||||
|       cmd = server.cmd, |       cmd = server.cmd, | ||||||
|       on_attach = function(client, bufnr0) |       on_attach = function(client, bufnr0) | ||||||
|         vim.lsp.completion.enable(true, client.id, bufnr0, { |         vim.lsp.completion.enable(true, client.id, bufnr0, { | ||||||
|  |           autotrigger = trigger_chars ~= nil, | ||||||
|           convert = function(item) |           convert = function(item) | ||||||
|             return { abbr = item.label:gsub('%b()', '') } |             return { abbr = item.label:gsub('%b()', '') } | ||||||
|           end, |           end, | ||||||
| @@ -957,6 +959,39 @@ describe('vim.lsp.completion: protocol', function() | |||||||
|     end) |     end) | ||||||
|   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() |   it('executes commands', function() | ||||||
|     local completion_list = { |     local completion_list = { | ||||||
|       isIncomplete = false, |       isIncomplete = false, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Robert Muir
					Robert Muir