diff options
Diffstat (limited to 'src/nvim/move.c')
-rw-r--r-- | src/nvim/move.c | 40 |
1 files changed, 31 insertions, 9 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c index a5383202a3..c080cf6691 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -1238,7 +1238,7 @@ bool scrolldown(long line_count, int byfold) } if (curwin->w_cursor.lnum == curwin->w_topline && do_sms) { - long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so; + long so = get_scrolloff_value(curwin); long scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; // make sure the cursor is in the visible text @@ -1274,12 +1274,11 @@ bool scrollup(long line_count, int byfold) if (do_sms || (byfold && hasAnyFolding(curwin)) || win_may_fill(curwin)) { int width1 = curwin->w_width - curwin_col_off(); int width2 = width1 + curwin_col_off2(); - int size = 0; + unsigned size = 0; linenr_T prev_topline = curwin->w_topline; if (do_sms) { - size = (int)win_linetabsize(curwin, curwin->w_topline, - ml_get(curwin->w_topline), (colnr_T)MAXCOL); + size = linetabsize(curwin, curwin->w_topline); } // diff mode: first consume "topfill" @@ -1300,7 +1299,7 @@ bool scrollup(long line_count, int byfold) // the end of the line, then advance to the next line. int add = curwin->w_skipcol > 0 ? width2 : width1; curwin->w_skipcol += add; - if (curwin->w_skipcol >= size) { + if ((unsigned)curwin->w_skipcol >= size) { if (lnum == curbuf->b_ml.ml_line_count) { // at the last screen line, can't scroll further curwin->w_skipcol -= add; @@ -1322,8 +1321,7 @@ bool scrollup(long line_count, int byfold) curwin->w_topfill = win_get_fill(curwin, lnum); curwin->w_skipcol = 0; if (todo > 1 && do_sms) { - size = (int)win_linetabsize(curwin, curwin->w_topline, - ml_get(curwin->w_topline), (colnr_T)MAXCOL); + size = linetabsize(curwin, curwin->w_topline); } } } @@ -1363,11 +1361,16 @@ bool scrollup(long line_count, int byfold) if (curwin->w_cursor.lnum == curwin->w_topline && do_sms && curwin->w_skipcol > 0) { int width1 = curwin->w_width - curwin_col_off(); int width2 = width1 + curwin_col_off2(); - long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so; + long so = get_scrolloff_value(curwin); long scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; + int space_cols = (curwin->w_height - 1) * width2; // Make sure the cursor is in a visible part of the line, taking // 'scrolloff' into account, but using screen lines. + // If there are not enough screen lines put the cursor in the middle. + if (scrolloff_cols > space_cols / 2) { + scrolloff_cols = space_cols / 2; + } validate_virtcol(); if (curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) { colnr_T col = curwin->w_virtcol; @@ -1402,11 +1405,20 @@ void adjust_skipcol(void) int width1 = curwin->w_width - curwin_col_off(); int width2 = width1 + curwin_col_off2(); - long so = curwin->w_p_so >= 0 ? curwin->w_p_so : p_so; + long so = get_scrolloff_value(curwin); long scrolloff_cols = so == 0 ? 0 : width1 + (so - 1) * width2; bool scrolled = false; validate_virtcol(); + if (curwin->w_cline_height == curwin->w_height) { + // the line just fits in the window, don't scroll + if (curwin->w_skipcol != 0) { + curwin->w_skipcol = 0; + redraw_later(curwin, UPD_NOT_VALID); + } + return; + } + while (curwin->w_skipcol > 0 && curwin->w_virtcol < curwin->w_skipcol + 3 + scrolloff_cols) { // scroll a screen line down @@ -2071,6 +2083,16 @@ void cursor_correct(void) return; } + if (curwin->w_p_sms && !curwin->w_p_wrap) { + // 'smoothscroll is active + if (curwin->w_cline_height == curwin->w_height) { + // The cursor line just fits in the window, don't scroll. + curwin->w_skipcol = 0; + return; + } + // TODO(vim): If the cursor line doesn't fit in the window then only adjust w_skipcol. + } + // Narrow down the area where the cursor can be put by taking lines from // the top and the bottom until: // - the desired context lines are found |