diff options
-rw-r--r-- | src/nvim/move.c | 36 | ||||
-rw-r--r-- | src/nvim/plines.c | 7 | ||||
-rw-r--r-- | test/old/testdir/test_diffmode.vim | 14 | ||||
-rw-r--r-- | test/old/testdir/test_normal.vim | 12 | ||||
-rw-r--r-- | test/old/testdir/test_scroll_opt.vim | 8 |
5 files changed, 43 insertions, 34 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c index 675f048d09..c055f6baad 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -2424,7 +2424,6 @@ static bool scroll_with_sms(Direction dir, int count) if (labs(curwin->w_topline - prev_topline) > (dir == BACKWARD)) { fixdir = dir * -1; } - validate_cursor(curwin); while (curwin->w_skipcol > 0 && curwin->w_topline < curbuf->b_ml.ml_line_count) { scroll_redraw(fixdir == FORWARD, 1); @@ -2447,6 +2446,7 @@ int pagescroll(Direction dir, int count, bool 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 }; @@ -2464,39 +2464,31 @@ int pagescroll(Direction dir, int count, bool half) if (dir == FORWARD) { int n = plines_correct_topline(curwin, curwin->w_topline, NULL, false, NULL); if (n - count < curwin->w_height_inner && curwin->w_topline < buflen) { - n += plines_m_win(curwin, curwin->w_topline + 1, buflen, true); + n += plines_m_win(curwin, curwin->w_topline + 1, buflen, false); } if (n - count < curwin->w_height_inner) { count = n - curwin->w_height_inner; } } - // 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(curwin); - int prev_wrow = curwin->w_wrow; nochange = scroll_with_sms(dir, count); - if (!nochange) { - validate_cursor(curwin); - 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(curwin); - // 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(curwin) > 0) { cursor_correct(curwin); } // Move cursor to first line of closed fold. diff --git a/src/nvim/plines.c b/src/nvim/plines.c index 8734780415..0c55e2fd72 100644 --- a/src/nvim/plines.c +++ b/src/nvim/plines.c @@ -880,14 +880,17 @@ int plines_m_win(win_T *wp, linenr_T first, linenr_T last, bool limit_winheight) { int count = 0; - while (first <= last) { + while (first <= last && (!limit_winheight || count < wp->w_height_inner)) { linenr_T next = first; - count += plines_win_full(wp, first, &next, NULL, false, limit_winheight); + count += plines_win_full(wp, first, &next, NULL, false, false); first = next + 1; } if (first == wp->w_buffer->b_ml.ml_line_count + 1) { count += win_get_fill(wp, first); } + if (limit_winheight && count > wp->w_height_inner) { + return wp->w_height_inner; + } return count; } diff --git a/test/old/testdir/test_diffmode.vim b/test/old/testdir/test_diffmode.vim index 3cc8f97f2f..71483b7469 100644 --- a/test/old/testdir/test_diffmode.vim +++ b/test/old/testdir/test_diffmode.vim @@ -1774,17 +1774,19 @@ endfunc " Ctrl-D reveals filler lines below the last line in the buffer. func Test_diff_eob_halfpage() - 5new + new call setline(1, ['']->repeat(10) + ['a']) diffthis - call assert_true(5, winheight(5)) - 5new + new call setline(1, ['']->repeat(3) + ['a', 'b']) diffthis + resize 5 wincmd j - resize 7 - exe "norm! G\<C-D>" - call assert_equal(6, line('w0')) + resize 5 + norm G + call assert_equal(7, line('w0')) + exe "norm! \<C-D>" + call assert_equal(8, line('w0')) %bwipe! endfunc diff --git a/test/old/testdir/test_normal.vim b/test/old/testdir/test_normal.vim index 10fbf4125a..9f9d9367dc 100644 --- a/test/old/testdir/test_normal.vim +++ b/test/old/testdir/test_normal.vim @@ -4235,4 +4235,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\<C-U>zz" + call assert_notequal(100, line('.')) + + set scrolloff& + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab nofoldenable diff --git a/test/old/testdir/test_scroll_opt.vim b/test/old/testdir/test_scroll_opt.vim index cb37b09707..50b0e13ba4 100644 --- a/test/old/testdir/test_scroll_opt.vim +++ b/test/old/testdir/test_scroll_opt.vim @@ -1031,10 +1031,10 @@ func Test_smoothscroll_page() call assert_equal(415, col('.')) exe "norm! \<C-D>" call assert_equal(520, winsaveview().skipcol) - call assert_equal(535, col('.')) + call assert_equal(615, col('.')) exe "norm! \<C-D>" call assert_equal(520, winsaveview().skipcol) - call assert_equal(735, col('.')) + call assert_equal(815, col('.')) exe "norm! \<C-D>" call assert_equal(520, winsaveview().skipcol) call assert_equal(895, col('.')) @@ -1046,10 +1046,10 @@ func Test_smoothscroll_page() call assert_equal(495, col('.')) exe "norm! \<C-U>" call assert_equal(0, winsaveview().skipcol) - call assert_equal(375, col('.')) + call assert_equal(295, col('.')) exe "norm! \<C-U>" call assert_equal(0, winsaveview().skipcol) - call assert_equal(175, col('.')) + call assert_equal(95, col('.')) exe "norm! \<C-U>" call assert_equal(0, winsaveview().skipcol) call assert_equal(15, col('.')) |