patch 9.2.0883: scroll: 'smoothscroll' position is lost when using "|"
Commit:
https://github.com/vim/vim/commit/5ed8fc10fac461981a729e9cd0995545be64ae46
Author: Hirohito Higashi <
h.eas...@gmail.com>
Date: Fri Jul 31 18:28:25 2026 +0000
patch 9.2.0883: scroll: 'smoothscroll' position is lost when using "|"
Problem: With 'smoothscroll' the scroll position in a long line is lost when
moving to a column with "|".
Solution: Adjust the skipped columns for the column the cursor ends up in,
not for column zero.
related: #20885
closes: #20890
Co-Authored-By: Claude Opus 5 (1M context) <
nor...@anthropic.com>
Signed-off-by: Hirohito Higashi <
h.eas...@gmail.com>
Signed-off-by: Christian Brabandt <
c...@256bit.org>
diff --git a/src/normal.c b/src/normal.c
index a7959d62f..642d9e465 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -6604,7 +6604,10 @@ nv_pipe(cmdarg_T *cap)
{
cap->oap->motion_type = MCHAR;
cap->oap->inclusive = FALSE;
- beginline(0);
+ // Not using beginline(), the columns to skip for 'smoothscroll' must be
+ // adjusted for the column we end up in, not for column zero.
+ curwin->w_cursor.col = 0;
+ curwin->w_cursor.coladd = 0;
if (cap->count0 > 0)
{
coladvance((colnr_T)(cap->count0 - 1));
@@ -6615,6 +6618,7 @@ nv_pipe(cmdarg_T *cap)
// keep curswant at the column where we wanted to go, not where
// we ended; differs if line is too short
curwin->w_set_curswant = false;
+ adjust_skipcol();
}
/*
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_1.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_1.dump
index f6ca843e7..0175a354d 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_1.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_1.dump
@@ -5,4 +5,4 @@
|l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
-| @39
+|:|n|o|r|m| |j|7|2|1||| @28
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_2.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_2.dump
index 9162df0c2..e52116654 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_2.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_2.dump
@@ -5,4 +5,4 @@
>l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
-| @39
+|:|n|o|r|m| |j|7|2|1||| @28
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_3.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_3.dump
index 1a1fcaeae..558ef73e4 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_3.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_3.dump
@@ -5,4 +5,4 @@
> |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
-@40
+|:|n|o|r|m| |j|7|2|1||| @28
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_4.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_4.dump
index 4ed62b65b..70b209727 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_4.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_4.dump
@@ -5,4 +5,4 @@
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
> |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
-@40
+|:|n|o|r|m| |j|7|2|1||| @28
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_5.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_5.dump
index 6d7e1578d..6aeef32e0 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_5.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_5.dump
@@ -5,4 +5,4 @@
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
>g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
-@40
+|:|n|o|r|m| |j|7|2|1||| @28
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_6.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_6.dump
index 4f5dcea8b..bad57cfe4 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_6.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_6.dump
@@ -5,4 +5,4 @@
|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
>t|h|r|e@1| @34
|f|o|u|r| @35
-@40
+|:|n|o|r|m| |j|7|2|1||| @28
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_7.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_7.dump
index 6d7e1578d..6aeef32e0 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_7.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_7.dump
@@ -5,4 +5,4 @@
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
>g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
-@40
+|:|n|o|r|m| |j|7|2|1||| @28
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_1.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_1.dump
index b78abfa72..3baa0eea6 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_1.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_1.dump
@@ -5,4 +5,4 @@
|l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
-| @21|2|,|7|2|1| @8|2|0|%|
+|:|n|o|r|m| |j|7|2|1||| @10|2|,|7|2|1| @8|2|0|%|
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_2.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_2.dump
index 906327d27..ac4b1b8f1 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_2.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_2.dump
@@ -5,4 +5,4 @@
>l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
-| @21|2|,|7|6|1| @8|2|0|%|
+|:|n|o|r|m| |j|7|2|1||| @10|2|,|7|6|1| @8|2|0|%|
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_3.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_3.dump
index 021431d47..7f7184114 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_3.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_3.dump
@@ -5,4 +5,4 @@
> |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
-@22|2|,|8|0|1| @8|2|0|%|
+|:|n|o|r|m| |j|7|2|1||| @10|2|,|8|0|1| @8|2|0|%|
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_4.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_4.dump
index 4e2f6b393..4e1cad8cf 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_4.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_4.dump
@@ -5,4 +5,4 @@
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
> |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
-@22|2|,|8|4|1| @8|2|0|%|
+|:|n|o|r|m| |j|7|2|1||| @10|2|,|8|4|1| @8|2|0|%|
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_5.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_5.dump
index 6e285023a..6ed2fd0ff 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_5.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_5.dump
@@ -5,4 +5,4 @@
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
>g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
-@22|2|,|8@1|1| @8|2|0|%|
+|:|n|o|r|m| |j|7|2|1||| @10|2|,|8@1|1| @8|2|0|%|
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_6.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_6.dump
index 456bff2ca..6a8fe5476 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_6.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_6.dump
@@ -5,4 +5,4 @@
|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
>t|h|r|e@1| @34
|f|o|u|r| @35
-@22|3|,|1| @10|3@1|%|
+|:|n|o|r|m| |j|7|2|1||| @10|3|,|1| @10|3@1|%|
diff --git a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_7.dump b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_7.dump
index 6e285023a..6ed2fd0ff 100644
--- a/src/testdir/dumps/Test_smooth_long_scrolloff_ru_7.dump
+++ b/src/testdir/dumps/Test_smooth_long_scrolloff_ru_7.dump
@@ -5,4 +5,4 @@
| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o
| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n
>g| |t|w|o| |l|o|n|g| |t|w|o| |l|o|n|g| @20
-@22|2|,|8@1|1| @8|2|0|%|
+|:|n|o|r|m| |j|7|2|1||| @10|2|,|8@1|1| @8|2|0|%|
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index cf362b6a2..992d76388 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -1330,6 +1330,25 @@ func Test_smoothscroll_keep_skipcol()
bwipe!
endfunc
+func Test_smoothscroll_cursor_back_in_line()
+ call NewWindow(10, 40)
+ setlocal smoothscroll
+ call setline(1, ['abcde '->repeat(150)]->repeat(2))
+
+ exe "norm! 10\<C-E>"
+ redraw
+ call assert_equal(400, winsaveview().skipcol)
+
+ " Moving to an earlier column in the same line scrolls back only as far as
+ " needed, not all the way to the start of the line.
+ norm! 240|
+ redraw
+ call assert_equal(200, winsaveview().skipcol)
+ call assert_equal(1, winline())
+
+ bwipe!
+endfunc
+
func Test_smoothscroll_long_line_zb()
call NewWindow(10, 40)
call setline(1, 'abcde '->repeat(150))
diff --git a/src/version.c b/src/version.c
index e7c89e818..56fbf8a76 100644
--- a/src/version.c
+++ b/src/version.c
@@ -758,6 +758,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 883,
/**/
882,
/**/