Commit: patch 9.2.0262: invalid lnum when pasting text copied blockwise

2 views
Skip to first unread message

Christian Brabandt

unread,
Mar 27, 2026, 12:02:14 PM (17 hours ago) Mar 27
to vim...@googlegroups.com
patch 9.2.0262: invalid lnum when pasting text copied blockwise

Commit: https://github.com/vim/vim/commit/80a0c355cff08bc8a20d548cc1e62a11a978babb
Author: Pierluigi Lenoci <pierluig...@gmail.com>
Date: Fri Mar 27 15:49:27 2026 +0000

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 <pierluig...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/register.c b/src/register.c
index 1fdebce95..de89b1864 100644
--- a/src/register.c
+++ b/src/register.c
@@ -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;
diff --git a/src/testdir/test_listener.vim b/src/testdir/test_listener.vim
index 91f0db2a1..8cbd15377 100644
--- a/src/testdir/test_listener.vim
+++ b/src/testdir/test_listener.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index 2dae07da4..b1b44b7f2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 262,
/**/
261,
/**/
Reply all
Reply to author
Forward
0 new messages