diff --git a/src/nvim/move.c b/src/nvim/move.c index 0a91b12255..7c63aa9d7f 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -203,7 +203,7 @@ void update_topline(win_T *wp) bool check_topline = false; // If the cursor is above or near the top of the window, scroll the window // to show the line the cursor is in, with 'scrolloff' context. - if (wp->w_topline > 1) { + if (wp->w_topline > 1 || wp->w_skipcol > 0) { // If the cursor is above topline, scrolling is always needed. // If the cursor is far below topline and there is no folding, // scrolling down is never needed. @@ -211,6 +211,15 @@ void update_topline(win_T *wp) check_topline = true; } else if (check_top_offset()) { check_topline = true; + } else if (wp->w_skipcol > 0 && wp->w_cursor.lnum == wp->w_topline) { + colnr_T vcol; + + // check the cursor position is visible. Add 3 for the ">>>" + // displayed in the top-left. + getvvcol(wp, &wp->w_cursor, &vcol, NULL, NULL); + if (wp->w_skipcol + 3 >= vcol) { + check_topline = true; + } } } // Check if there are more filler lines than allowed. @@ -1499,6 +1508,7 @@ void scroll_cursor_top(int min_scroll, int always) linenr_T top; // just above displayed lines linenr_T bot; // just below displayed lines linenr_T old_topline = curwin->w_topline; + int old_skipcol = curwin->w_skipcol; linenr_T old_topfill = curwin->w_topfill; linenr_T new_topline; int off = (int)get_scrolloff_value(curwin); @@ -1588,7 +1598,13 @@ void scroll_cursor_top(int min_scroll, int always) } } check_topfill(curwin, false); + // TODO(vim): if the line doesn't fit may optimize w_skipcol + if (curwin->w_topline == curwin->w_cursor.lnum) { + curwin->w_skipcol = 0; + redraw_later(curwin, UPD_NOT_VALID); + } if (curwin->w_topline != old_topline + || curwin->w_skipcol != old_skipcol || curwin->w_topfill != old_topfill) { curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE|VALID_BOTLINE_AP); diff --git a/test/functional/legacy/scroll_opt_spec.lua b/test/functional/legacy/scroll_opt_spec.lua index c63401cb02..fb4990ff00 100644 --- a/test/functional/legacy/scroll_opt_spec.lua +++ b/test/functional/legacy/scroll_opt_spec.lua @@ -307,7 +307,7 @@ describe('smoothscroll', function() screen:try_resize(40, 8) exec([[ call setline(1, ['Line' .. (' with some text'->repeat(7))]->repeat(7)) - set smoothscroll scrolloff=0 + set smoothscroll scrolloff=0 display= :3 ]]) screen:expect([[ @@ -322,9 +322,22 @@ describe('smoothscroll', function() ]]) feed('j') screen:expect_unchanged() + -- moving cursor down - whole bottom line shows feed('j') screen:expect_unchanged() feed('G') screen:expect_unchanged() + -- moving cursor up - whole top line shows + feed('2k') + screen:expect([[ + ^Line with some text with some text with | + some text with some text with some text | + with some text with some text | + Line with some text with some text with | + some text with some text with some text | + with some text with some text | + @ | + | + ]]) end) end) diff --git a/test/old/testdir/test_scroll_opt.vim b/test/old/testdir/test_scroll_opt.vim index 799db19298..77e656cf9f 100644 --- a/test/old/testdir/test_scroll_opt.vim +++ b/test/old/testdir/test_scroll_opt.vim @@ -198,6 +198,7 @@ func Test_smoothscroll_wrap_scrolloff_zero() call VerifyScreenDump(buf, 'Test_smooth_wrap_1', {}) + " moving cursor down - whole bottom line shows call term_sendkeys(buf, "j") call VerifyScreenDump(buf, 'Test_smooth_wrap_2', {}) @@ -207,6 +208,10 @@ func Test_smoothscroll_wrap_scrolloff_zero() call term_sendkeys(buf, "G") call VerifyScreenDump(buf, 'Test_smooth_wrap_4', {}) + " moving cursor up - whole top line shows + call term_sendkeys(buf, "2k") + call VerifyScreenDump(buf, 'Test_smooth_wrap_5', {}) + call StopVimInTerminal(buf) endfunc