patch 9.2.0262: invalid lnum when pasting text copied blockwise

Problem:  invalid lnum when pasting text copied blockwise
          (KillTheMule)
Solution: Subtract nr_lines from curwin->w_cursor.lnum when calling
          changed_lines() in do_put() (Pierluigi Lenoci)

When doing a blockwise paste beyond the end of the buffer, new lines are
appended and nr_lines is incremented accordingly. However, the
changed_lines() call used curwin->w_cursor.lnum as the "lnume" argument
(the first line below the changed lines BEFORE the change), which is
incorrect because the cursor has already been moved past the newly
appended lines.

Fix by subtracting nr_lines from curwin->w_cursor.lnum, so that lnume
correctly reflects the state before the change, as documented in
changed_lines().

Add a listener test to verify the correct values are reported.

Port of neovim/neovim#12733.

fixes:  #6660
closes: #19844

Signed-off-by: Pierluigi Lenoci <pierluigi.lenoci@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Pierluigi Lenoci
2026-03-27 15:49:27 +00:00
committed by Christian Brabandt
parent 54b6c0c0e7
commit 80a0c355cf
3 changed files with 22 additions and 1 deletions
+1 -1
View File
@@ -2021,7 +2021,7 @@ do_put(
curwin->w_cursor.col += bd.startspaces;
}
changed_lines(lnum, 0, curwin->w_cursor.lnum, nr_lines);
changed_lines(lnum, 0, curwin->w_cursor.lnum - nr_lines, nr_lines);
// Set '[ mark.
curbuf->b_op_start = curwin->w_cursor;
+19
View File
@@ -782,4 +782,23 @@ func Test_redraw_listener_partial()
call redraw_listener_add(#{on_start: function("s:OnRedraw", [1])})
endfunc
func Test_listener_blockwise_paste()
new
call setline(1, ['1', '2', '3'])
let s:list = []
let id = listener_add('s:StoreListArgs')
" yank a blockwise selection and paste at the end of the buffer, which
" appends new lines
call feedkeys("1G0\<C-v>2jyGp", 'xt')
call listener_flush()
" the listener should report correct lnume (before the change) and added
call assert_equal(3, s:start)
call assert_equal(4, s:end)
call assert_equal(2, s:added)
call listener_remove(id)
bwipe!
endfunc
" vim: shiftwidth=2 sts=2 expandtab
+2
View File
@@ -734,6 +734,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
262,
/**/
261,
/**/