Commit: patch 9.2.0885: scroll: 'smoothscroll' position is lost when the window is squeezed

1 view
Skip to first unread message

Christian Brabandt

unread,
3:00 PM (7 hours ago) 3:00 PM
to vim...@googlegroups.com
patch 9.2.0885: scroll: 'smoothscroll' position is lost when the window is squeezed

Commit: https://github.com/vim/vim/commit/15f8ba5cec35feea22622fbc7c78f3204aad50df
Author: Hirohito Higashi <h.eas...@gmail.com>
Date: Fri Jul 31 18:39:49 2026 +0000

patch 9.2.0885: scroll: 'smoothscroll' position is lost when the window is squeezed

Problem: With 'smoothscroll' the scroll position in a long line is lost when
a window is temporarily squeezed to a couple of lines, for example
when opening and closing a help window.
Solution: When the cursor ends up in the skipped columns, skip up to the
screen line the cursor is in instead of showing the start of the
line.

closes: #20892

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/move.c b/src/move.c
index 9f9013424..cd9169de9 100644
--- a/src/move.c
+++ b/src/move.c
@@ -2537,9 +2537,23 @@ scroll_cursor_top(int min_scroll, int always)
{
validate_virtcol();
if (curwin->w_skipcol >= curwin->w_virtcol)
- // TODO: if the line doesn't fit may optimize w_skipcol instead
- // of making it zero
- reset_skipcol();
+ {
+ // Skip up to the screen line the cursor is in, so that the
+ // position in the line is kept.
+ int width1 = curwin->w_width - curwin_col_off();
+ int width2 = width1 + curwin_col_off2();
+ int plines_off = 0;
+ int skipcol;
+
+ if (width2 > 0 && curwin->w_virtcol >= (colnr_T)width1)
+ plines_off = (curwin->w_virtcol - width1) / width2 + 1;
+ skipcol = skipcol_from_plines(curwin, plines_off);
+ if (skipcol != curwin->w_skipcol)
+ {
+ curwin->w_skipcol = skipcol;
+ redraw_later(UPD_SOME_VALID);
+ }
+ }
}
if (curwin->w_topline != old_topline
|| curwin->w_skipcol != old_skipcol
diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim
index 992d76388..fc266da03 100644
--- a/src/testdir/test_scroll_opt.vim
+++ b/src/testdir/test_scroll_opt.vim
@@ -1349,6 +1349,27 @@ func Test_smoothscroll_cursor_back_in_line()
bwipe!
endfunc

+func Test_smoothscroll_squeezed_window()
+ setlocal smoothscroll
+ call setline(1, [repeat('x', 3000)] + repeat(['line'], 10))
+ exe "norm! gg10\<C-E>"
+ redraw
+ let skipcol = winsaveview().skipcol
+ call assert_notequal(0, skipcol)
+ let virtcol = virtcol('.')
+
+ " Squeezing the window to one line and restoring it must not scroll back to
+ " the start of the line.
+ new
+ wincmd _
+ close
+ redraw
+ call assert_notequal(0, winsaveview().skipcol)
+ call assert_equal(virtcol, virtcol('.'))
+
+ 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 29de0350f..55f755f23 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 */
+/**/
+ 885,
/**/
884,
/**/
Reply all
Reply to author
Forward
0 new messages