backport: fix(lsp): trailing blank line when edit inserts past end of buffer (#40176)

Problem:
A text edit positioned entirely past the last buffer line, with
newText ending in a newline, leaves a stray blank line: the
past-the-end path appends the trailing empty fragment produced by
vim.split() and does not set has_eol_text_edit, so the end-of-buffer
cleanup is skipped. Formatting servers emit such edits whenever
formatting moves text to the end of a document.

Regression from ec94014cd1 (#20137), which split the past-the-end
fast path off the clamp path that sets the flag.

Solution:
Set has_eol_text_edit in the past-the-end path, like the adjacent
path that clamps end_row.

(cherry picked from commit d42f7ee9dc)

Co-authored-by: Aaron Tinio <aptinio@gmail.com>
This commit is contained in:
neovim-backports[bot]
2026-06-14 11:25:18 -04:00
committed by GitHub
parent ecda67662f
commit dc6a9170eb
2 changed files with 15 additions and 0 deletions

View File

@@ -378,6 +378,7 @@ function M.apply_text_edits(text_edits, bufnr, position_encoding, change_annotat
-- of the buffer.
if max <= start_row then
api.nvim_buf_set_lines(bufnr, max, max, false, text)
has_eol_text_edit = true
else
local last_line_len = #(get_line(bufnr, math.min(end_row, max - 1)) or '')
-- Some LSP servers may return +1 range of the buffer content but nvim_buf_set_text can't

View File

@@ -2248,6 +2248,20 @@ describe('LSP', function()
}, buf_lines(1))
end)
it('applies newline-terminated text edits at the end of the document', function()
apply_text_edits({
{ 5, 0, 5, 0, 'foobar\n' },
})
eq({
'First line of text',
'Second line of text',
'Third line of text',
'Fourth line of text',
'å å ɧ 汉语 ↥ 🤦 🦄',
'foobar',
}, buf_lines(1))
end)
it('it restores marks', function()
eq(true, api.nvim_buf_set_mark(1, 'a', 2, 1, {}))
apply_text_edits({