# HG changeset patch # User Christian Brabandt # Date 1712691902 -7200 # Node ID fa2084ba51382f0fc1220abf195b4c6694a6f390 # Parent ca0bfdb5d652c71b2e9f39891f98636892c9e65f patch 9.1.0285: Still problems with cursor position for CTRL-D/U Commit: https://github.com/vim/vim/commit/78c51500f1bb16501521d721d52cb0982f5e70b6 Author: Luuk van Baal Date: Tue Apr 9 21:30:19 2024 +0200 patch 9.1.0285: Still problems with cursor position for CTRL-D/U Problem: Problems with cursor position when scrolling half a page. Solution: Rework the cursor logic. (Luuk van Baal) closes: #14455 Signed-off-by: Luuk van Baal Signed-off-by: Christian Brabandt diff --git a/src/move.c b/src/move.c --- a/src/move.c +++ b/src/move.c @@ -3165,7 +3165,6 @@ static int scroll_with_sms(int dir, long // extra for scrolling backward so that consuming skipcol is symmetric. if (labs(curwin->w_topline - prev_topline) > (dir == BACKWARD)) fixdir = dir * -1; - validate_cursor(); while (curwin->w_skipcol > 0 && curwin->w_topline < curbuf->b_ml.ml_line_count) scroll_redraw(fixdir == FORWARD, 1); @@ -3192,6 +3191,7 @@ pagescroll(int dir, long count, int half int nochange = TRUE; int buflen = curbuf->b_ml.ml_line_count; colnr_T prev_col = curwin->w_cursor.col; + colnr_T prev_curswant = curwin->w_curswant; linenr_T prev_lnum = curwin->w_cursor.lnum; oparg_T oa = { 0 }; cmdarg_T ca = { 0 }; @@ -3215,34 +3215,24 @@ pagescroll(int dir, long count, int half count = n - curwin->w_height; } - // Scroll the window and determine number of lines to move the cursor. + // (Try to) scroll the window unless already at the end of the buffer. if (count > 0) { - validate_cursor(); - int prev_wrow = curwin->w_wrow; nochange = scroll_with_sms(dir, count); - if (!nochange) - { - validate_cursor(); - curscount = abs(prev_wrow - curwin->w_wrow); - dir = prev_wrow > curwin->w_wrow ? FORWARD : BACKWARD; - } + curwin->w_cursor.lnum = prev_lnum; + curwin->w_cursor.col = prev_col; + curwin->w_curswant = prev_curswant; } - int so = get_scrolloff_value(); - // Move the cursor the same amount of screen lines except if - // 'scrolloff' is set and cursor was at start or end of buffer. - if (so == 0 || (prev_lnum != 1 && prev_lnum != buflen)) - { - if (curwin->w_p_wrap) - nv_screengo(&oa, dir, curscount); - else if (dir == FORWARD) - cursor_down_inner(curwin, curscount); - else - cursor_up_inner(curwin, curscount); - } + // Move the cursor the same amount of screen lines. + if (curwin->w_p_wrap) + nv_screengo(&oa, dir, curscount); + else if (dir == FORWARD) + cursor_down_inner(curwin, curscount); + else + cursor_up_inner(curwin, curscount); - if (so > 0) + if (get_scrolloff_value() > 0) cursor_correct(); #ifdef FEAT_FOLDING // Move cursor to first line of closed fold. diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim --- a/src/testdir/test_normal.vim +++ b/src/testdir/test_normal.vim @@ -4225,4 +4225,16 @@ func Test_single_line_filler_zb() bw! endfunc +" Test for Ctrl-U not getting stuck at end of buffer with 'scrolloff'. +func Test_halfpage_scrolloff_eob() + set scrolloff=5 + + call setline(1, range(1, 100)) + exe "norm! Gzz\zz" + call assert_notequal(100, line('.')) + + set scrolloff& + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab nofoldenable diff --git a/src/testdir/test_scroll_opt.vim b/src/testdir/test_scroll_opt.vim --- a/src/testdir/test_scroll_opt.vim +++ b/src/testdir/test_scroll_opt.vim @@ -1028,10 +1028,10 @@ func Test_smoothscroll_page() call assert_equal(415, col('.')) exe "norm! \" call assert_equal(520, winsaveview().skipcol) - call assert_equal(535, col('.')) + call assert_equal(615, col('.')) exe "norm! \" call assert_equal(520, winsaveview().skipcol) - call assert_equal(735, col('.')) + call assert_equal(815, col('.')) exe "norm! \" call assert_equal(520, winsaveview().skipcol) call assert_equal(895, col('.')) @@ -1043,10 +1043,10 @@ func Test_smoothscroll_page() call assert_equal(495, col('.')) exe "norm! \" call assert_equal(0, winsaveview().skipcol) - call assert_equal(375, col('.')) + call assert_equal(295, col('.')) exe "norm! \" call assert_equal(0, winsaveview().skipcol) - call assert_equal(175, col('.')) + call assert_equal(95, col('.')) exe "norm! \" call assert_equal(0, winsaveview().skipcol) call assert_equal(15, col('.')) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -705,6 +705,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 285, +/**/ 284, /**/ 283,