fix(lsp): apply_text_edits causes unwanted BufDelete events #38778

Problem:
Since 2f6d1d3c88, `apply_text_edits`
unconditionally sets `buflisted=true`, causing spurious BufDelete events
if plugins restore the original 'buflisted' state on unlisted buffers:
65ef6cec1c/src/nvim/option.c (L2159-L2169)

Solution:
- Don't set 'buflisted' in `apply_text_edits`. Set it more narrowly, in
  `apply_workspace_edit` where the semantics requires affected buffers
  to be visible to the user.
- Also skip setting 'buflisted' if it would not be changed, to avoid
  redundant `OptionSet` events.

(cherry picked from commit 6473d007e7)
This commit is contained in:
glepnir
2026-04-09 05:10:52 +08:00
committed by github-actions[bot]
parent df726644b8
commit 7ffee0dfbf
2 changed files with 10 additions and 1 deletions

View File

@@ -312,7 +312,6 @@ function M.apply_text_edits(text_edits, bufnr, position_encoding, change_annotat
if not api.nvim_buf_is_loaded(bufnr) then
vim.fn.bufload(bufnr)
end
vim.bo[bufnr].buflisted = true
local marks = {} --- @type table<string,[integer,integer]>
local has_eol_text_edit = false
@@ -710,7 +709,12 @@ function M.apply_workspace_edit(workspace_edit, position_encoding)
elseif change.kind then --- @diagnostic disable-line:undefined-field
error(string.format('Unsupported change: %q', vim.inspect(change)))
else
local bufnr = vim.uri_to_bufnr(change.textDocument.uri)
M.apply_text_document_edit(change, idx, position_encoding, workspace_edit.changeAnnotations)
-- avoid triggering OptionSet
if not vim.bo[bufnr].buflisted then
vim.bo[bufnr].buflisted = true
end
end
end
return
@@ -724,6 +728,10 @@ function M.apply_workspace_edit(workspace_edit, position_encoding)
for uri, changes in pairs(all_changes) do
local bufnr = vim.uri_to_bufnr(uri)
M.apply_text_edits(changes, bufnr, position_encoding, workspace_edit.changeAnnotations)
-- avoid triggering OptionSet
if not vim.bo[bufnr].buflisted then
vim.bo[bufnr].buflisted = true
end
end
end

View File

@@ -2639,6 +2639,7 @@ describe('LSP', function()
return vim.api.nvim_buf_get_lines(target_bufnr, 0, -1, false)
end, make_workspace_edit(edits))
)
eq(true, api.nvim_get_option_value('buflisted', { buf = target_bufnr }))
end)
it('apply_workspace_edit applies multiple edits', function()