commit 90abd2613d7f8636b73d2f4084489b849cc16c69
parent 0ddba68607a91c2397a8122da610331e2335e40f
Author: Tomasz N <przepompownia@users.noreply.github.com>
Date: Tue, 3 Feb 2026 21:30:05 +0100
fix(lsp): don't empty server start-boundary by next client response #37665
Problem:
Server start boundary can be emptied by response provided by next client.
Solution:
Don't empty it when extending the result list.
Diffstat:
2 files changed, 45 insertions(+), 2 deletions(-)
diff --git a/runtime/lua/vim/lsp/completion.lua b/runtime/lua/vim/lsp/completion.lua
@@ -586,8 +586,8 @@ local function trigger(bufnr, clients, ctx)
if result then
Context.isIncomplete = Context.isIncomplete or result.isIncomplete
local encoding = client and client.offset_encoding or 'utf-16'
- local client_matches
- client_matches, server_start_boundary = M._convert_results(
+ local client_matches, tmp_server_start_boundary
+ client_matches, tmp_server_start_boundary = M._convert_results(
line,
cursor_row - 1,
cursor_col,
@@ -598,6 +598,7 @@ local function trigger(bufnr, clients, ctx)
encoding
)
+ server_start_boundary = tmp_server_start_boundary or server_start_boundary
vim.list_extend(matches, client_matches)
end
end
diff --git a/test/functional/plugin/lsp/completion_spec.lua b/test/functional/plugin/lsp/completion_spec.lua
@@ -1427,6 +1427,48 @@ describe('vim.lsp.completion: integration', function()
eq({ 1, 17 }, n.api.nvim_win_get_cursor(0))
end)
+ it('does not empty server start boundary', function()
+ local completion_list = {
+ isIncomplete = false,
+ items = {
+ {
+ label = 'div.foo',
+ insertTextFormat = 2,
+ textEdit = {
+ newText = '<div class="foo">$0</div>',
+ range = { start = { line = 0, character = 0 }, ['end'] = { line = 0, character = 7 } },
+ },
+ },
+ },
+ }
+ local completion_list2 = {
+ isIncomplete = false,
+ items = {
+ {
+ insertTextFormat = 1,
+ label = 'foo',
+ },
+ },
+ }
+ exec_lua(function()
+ vim.o.completeopt = 'menu,menuone,noinsert'
+ end)
+ create_server('dummy', completion_list)
+ create_server('dummy2', completion_list2)
+ feed('Adiv.foo<C-x><C-O>')
+ retry(nil, nil, function()
+ eq(
+ 1,
+ exec_lua(function()
+ return vim.fn.pumvisible()
+ end)
+ )
+ end)
+ feed('<C-Y>')
+ eq('<div class="foo"></div>', n.api.nvim_get_current_line())
+ eq({ 1, 17 }, n.api.nvim_win_get_cursor(0))
+ end)
+
it('sorts items when fuzzy is enabled and prefix not empty #33610', function()
local completion_list = {
isIncomplete = false,