patch 9.2.0796: Visual block reselection wrong with 'virtualedit'
Commit:
https://github.com/vim/vim/commit/8cddbfe468299fc7fe8bf669f43ca3a4a40b40b2
Author: zeertzjq <
zeer...@outlook.com>
Date: Sat Jul 18 14:14:12 2026 +0000
patch 9.2.0796: Visual block reselection wrong with 'virtualedit'
Problem: Visual block reselection wrong with 'virtualedit' when line
lengths are different (Alex Yang, after 8.2.3494).
Solution: Set the entire cursor position to old position when computing
target curswant, since the check_cursor() added in 8.2.3494
may change cursor column as well (zeertzjq).
fixes: #20746
closes: #20748
Signed-off-by: zeertzjq <
zeer...@outlook.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/normal.c b/src/normal.c
index b803b88f6..08b9e9f0c 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -5579,13 +5579,12 @@ nv_visual(cmdarg_T *cap)
}
else if (VIsual_mode == Ctrl_V)
{
- // Update curswant on the original line, that is where "col" is
- // valid.
- linenr_T lnum = curwin->w_cursor.lnum;
- curwin->w_cursor.lnum = VIsual.lnum;
+ // Update curswant at the original cursor position.
+ pos_T tmp_cursor = curwin->w_cursor;
+ curwin->w_cursor = VIsual;
update_curswant_force();
curwin->w_curswant += resel_VIsual_vcol * cap->count0 - 1;
- curwin->w_cursor.lnum = lnum;
+ curwin->w_cursor = tmp_cursor;
if (*p_sel == 'e')
++curwin->w_curswant;
coladvance(curwin->w_curswant);
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index d92f651d9..beea4c431 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1004,6 +1004,28 @@ func Test_virtualedit_visual_block()
bwipe!
endfunc
+func Test_virtualedit_visual_block_reselect()
+ set ve=all
+ new
+ call append(0, ['###', '###', '###', '#####'])
+ call cursor(1, 1)
+ exe "norm! \<C-V>lljj"
+ call assert_equal([0, 3, 3, 0], getpos('.'))
+ call assert_equal([0, 1, 1, 0], getpos('v'))
+ norm! y
+ call assert_equal(['###', '###', '###'], getreg('"', v:true, v:true))
+ call cursor(2, 6)
+ call assert_equal([0, 2, 4, 2], getpos('.'))
+ norm! 1v
+ call assert_equal([0, 4, 6, 2], getpos('.'))
+ call assert_equal([0, 2, 4, 2], getpos('v'))
+ norm! r!
+ call assert_equal(['### !!!', '### !!!', '#####!!!'], getline(2, 4))
+
+ bwipe!
+ set ve&
+endfunc
+
" Test for changing case
func Test_visual_change_case()
new
diff --git a/src/version.c b/src/version.c
index e0861aa38..9a22bfa51 100644
--- a/src/version.c
+++ b/src/version.c
@@ -759,6 +759,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 796,
/**/
795,
/**/