diff options
Diffstat (limited to 'src/nvim/move.c')
-rw-r--r-- | src/nvim/move.c | 120 |
1 files changed, 66 insertions, 54 deletions
diff --git a/src/nvim/move.c b/src/nvim/move.c index f47853e9cb..e7ed98d4f0 100644 --- a/src/nvim/move.c +++ b/src/nvim/move.c @@ -142,7 +142,8 @@ void update_topline(void) int old_topfill; bool check_topline = false; bool check_botline = false; - long save_so = p_so; + long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; + long save_so = *so_ptr; // If there is no valid screen and when the window height is zero just use // the cursor line. @@ -158,9 +159,10 @@ void update_topline(void) if (curwin->w_valid & VALID_TOPLINE) return; - /* When dragging with the mouse, don't scroll that quickly */ - if (mouse_dragging > 0) - p_so = mouse_dragging - 1; + // When dragging with the mouse, don't scroll that quickly + if (mouse_dragging > 0) { + *so_ptr = mouse_dragging - 1; + } old_topline = curwin->w_topline; old_topfill = curwin->w_topfill; @@ -206,15 +208,17 @@ void update_topline(void) * scrolled). */ n = 0; for (linenr_T lnum = curwin->w_cursor.lnum; - lnum < curwin->w_topline + p_so; ++lnum) { - ++n; - /* stop at end of file or when we know we are far off */ - if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight) + lnum < curwin->w_topline + *so_ptr; lnum++) { + n++; + // stop at end of file or when we know we are far off + if (lnum >= curbuf->b_ml.ml_line_count || n >= halfheight) { break; + } (void)hasFolding(lnum, NULL, &lnum); } - } else - n = curwin->w_topline + p_so - curwin->w_cursor.lnum; + } else { + n = curwin->w_topline + *so_ptr - curwin->w_cursor.lnum; + } /* If we weren't very close to begin with, we scroll to put the * cursor in the middle of the window. Otherwise put the cursor @@ -247,7 +251,7 @@ void update_topline(void) if (curwin->w_botline <= curbuf->b_ml.ml_line_count) { if (curwin->w_cursor.lnum < curwin->w_botline) { if (((long)curwin->w_cursor.lnum - >= (long)curwin->w_botline - p_so + >= (long)curwin->w_botline - *so_ptr || hasAnyFolding(curwin) )) { lineoff_T loff; @@ -266,13 +270,15 @@ void update_topline(void) && (loff.lnum + 1 < curwin->w_botline || loff.fill == 0) ) { n += loff.height; - if (n >= p_so) + if (n >= *so_ptr) { break; + } botline_forw(&loff); } - if (n >= p_so) - /* sufficient context, no need to scroll */ + if (n >= *so_ptr) { + // sufficient context, no need to scroll check_botline = false; + } } else { /* sufficient context, no need to scroll */ check_botline = false; @@ -285,7 +291,7 @@ void update_topline(void) * botline - p_so (approximation of how much will be * scrolled). */ for (linenr_T lnum = curwin->w_cursor.lnum; - lnum >= curwin->w_botline - p_so; lnum--) { + lnum >= curwin->w_botline - *so_ptr; lnum--) { line_count++; // stop at end of file or when we know we are far off if (lnum <= 0 || line_count > curwin->w_height_inner + 1) { @@ -295,7 +301,7 @@ void update_topline(void) } } else line_count = curwin->w_cursor.lnum - curwin->w_botline - + 1 + p_so; + + 1 + *so_ptr; if (line_count <= curwin->w_height_inner + 1) { scroll_cursor_bot(scrolljump_value(), false); } else { @@ -324,7 +330,7 @@ void update_topline(void) validate_cursor(); } - p_so = save_so; + *so_ptr = save_so; } /* @@ -356,25 +362,28 @@ static int scrolljump_value(void) */ static bool check_top_offset(void) { - if (curwin->w_cursor.lnum < curwin->w_topline + p_so + long so = get_scrolloff_value(); + if (curwin->w_cursor.lnum < curwin->w_topline + so || hasAnyFolding(curwin) ) { lineoff_T loff; loff.lnum = curwin->w_cursor.lnum; loff.fill = 0; - int n = curwin->w_topfill; /* always have this context */ - /* Count the visible screen lines above the cursor line. */ - while (n < p_so) { + int n = curwin->w_topfill; // always have this context + // Count the visible screen lines above the cursor line. + while (n < so) { topline_back(&loff); - /* Stop when included a line above the window. */ + // Stop when included a line above the window. if (loff.lnum < curwin->w_topline || (loff.lnum == curwin->w_topline && loff.fill > 0) - ) + ) { break; + } n += loff.height; } - if (n < p_so) + if (n < so) { return true; + } } return false; } @@ -714,6 +723,8 @@ void curs_columns( colnr_T startcol; colnr_T endcol; colnr_T prev_skipcol; + long so = get_scrolloff_value(); + long siso = get_sidescrolloff_value(); /* * First make sure that w_topline is valid (after moving the cursor). @@ -785,10 +796,10 @@ void curs_columns( * If we get closer to the edge than 'sidescrolloff', scroll a little * extra */ - assert(p_siso <= INT_MAX); - int off_left = startcol - curwin->w_leftcol - (int)p_siso; + assert(siso <= INT_MAX); + int off_left = startcol - curwin->w_leftcol - (int)siso; int off_right = - endcol - curwin->w_leftcol - curwin->w_width_inner + (int)p_siso + 1; + endcol - curwin->w_leftcol - curwin->w_width_inner + (int)siso + 1; if (off_left < 0 || off_right > 0) { int diff = (off_left < 0) ? -off_left: off_right; @@ -834,7 +845,7 @@ void curs_columns( int plines = 0; if ((curwin->w_wrow >= curwin->w_height_inner || ((prev_skipcol > 0 - || curwin->w_wrow + p_so >= curwin->w_height_inner) + || curwin->w_wrow + so >= curwin->w_height_inner) && (plines = plines_win_nofill(curwin, curwin->w_cursor.lnum, false)) - 1 >= curwin->w_height_inner)) @@ -850,17 +861,18 @@ void curs_columns( * 2: Less than "p_so" lines below * 3: both of them */ extra = 0; - if (curwin->w_skipcol + p_so * width > curwin->w_virtcol) + if (curwin->w_skipcol + so * width > curwin->w_virtcol) { extra = 1; - /* Compute last display line of the buffer line that we want at the - * bottom of the window. */ + } + // Compute last display line of the buffer line that we want at the + // bottom of the window. if (plines == 0) { plines = plines_win(curwin, curwin->w_cursor.lnum, false); } plines--; - if (plines > curwin->w_wrow + p_so) { - assert(p_so <= INT_MAX); - n = curwin->w_wrow + (int)p_so; + if (plines > curwin->w_wrow + so) { + assert(so <= INT_MAX); + n = curwin->w_wrow + (int)so; } else { n = plines; } @@ -868,7 +880,7 @@ void curs_columns( extra += 2; } - if (extra == 3 || plines < p_so * 2) { + if (extra == 3 || plines < so * 2) { // not enough room for 'scrolloff', put cursor in the middle n = curwin->w_virtcol / width; if (n > curwin->w_height_inner / 2) { @@ -882,9 +894,9 @@ void curs_columns( } curwin->w_skipcol = n * width; } else if (extra == 1) { - /* less then 'scrolloff' lines above, decrease skipcol */ - assert(p_so <= INT_MAX); - extra = (curwin->w_skipcol + (int)p_so * width - curwin->w_virtcol + // less then 'scrolloff' lines above, decrease skipcol + assert(so <= INT_MAX); + extra = (curwin->w_skipcol + (int)so * width - curwin->w_virtcol + width - 1) / width; if (extra > 0) { if ((colnr_T)(extra * width) > curwin->w_skipcol) @@ -1206,7 +1218,7 @@ void scrolldown_clamp(void) end_row += curwin->w_cline_height - 1 - curwin->w_virtcol / curwin->w_width_inner; } - if (end_row < curwin->w_height_inner - p_so) { + if (end_row < curwin->w_height_inner - get_scrolloff_value()) { if (can_fill) { ++curwin->w_topfill; check_topfill(curwin, true); @@ -1246,14 +1258,14 @@ void scrollup_clamp(void) validate_virtcol(); start_row -= curwin->w_virtcol / curwin->w_width_inner; } - if (start_row >= p_so) { - if (curwin->w_topfill > 0) - --curwin->w_topfill; - else { + if (start_row >= get_scrolloff_value()) { + if (curwin->w_topfill > 0) { + curwin->w_topfill--; + } else { (void)hasFolding(curwin->w_topline, NULL, &curwin->w_topline); - ++curwin->w_topline; + curwin->w_topline++; } - ++curwin->w_botline; /* approximate w_botline */ + curwin->w_botline++; // approximate w_botline curwin->w_valid &= ~(VALID_WROW|VALID_CROW|VALID_BOTLINE); } } @@ -1349,8 +1361,7 @@ void scroll_cursor_top(int min_scroll, int always) linenr_T old_topline = curwin->w_topline; linenr_T old_topfill = curwin->w_topfill; linenr_T new_topline; - assert(p_so <= INT_MAX); - int off = (int)p_so; + int off = (int)get_scrolloff_value(); if (mouse_dragging > 0) off = mouse_dragging - 1; @@ -1492,7 +1503,8 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) linenr_T old_botline = curwin->w_botline; int old_valid = curwin->w_valid; int old_empty_rows = curwin->w_empty_rows; - linenr_T cln = curwin->w_cursor.lnum; /* Cursor Line Number */ + linenr_T cln = curwin->w_cursor.lnum; // Cursor Line Number + long so = get_scrolloff_value(); if (set_topbot) { used = 0; @@ -1551,7 +1563,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) /* Stop when scrolled nothing or at least "min_scroll", found "extra" * context for 'scrolloff' and counted all lines below the window. */ if ((((scrolled <= 0 || scrolled >= min_scroll) - && extra >= (mouse_dragging > 0 ? mouse_dragging - 1 : p_so)) + && extra >= (mouse_dragging > 0 ? mouse_dragging - 1 : so)) || boff.lnum + 1 > curbuf->b_ml.ml_line_count) && loff.lnum <= curwin->w_botline && (loff.lnum < curwin->w_botline @@ -1589,7 +1601,7 @@ void scroll_cursor_bot(int min_scroll, int set_topbot) if (used > curwin->w_height_inner) { break; } - if (extra < (mouse_dragging > 0 ? mouse_dragging - 1 : p_so) + if (extra < (mouse_dragging > 0 ? mouse_dragging - 1 : so) || scrolled < min_scroll) { extra += boff.height; if (boff.lnum >= curwin->w_botline @@ -1724,9 +1736,8 @@ void cursor_correct(void) * How many lines we would like to have above/below the cursor depends on * whether the first/last line of the file is on screen. */ - assert(p_so <= INT_MAX); - int above_wanted = (int)p_so; - int below_wanted = (int)p_so; + int above_wanted = (int)get_scrolloff_value(); + int below_wanted = (int)get_scrolloff_value(); if (mouse_dragging > 0) { above_wanted = mouse_dragging - 1; below_wanted = mouse_dragging - 1; @@ -1821,6 +1832,7 @@ int onepage(Direction dir, long count) int retval = OK; lineoff_T loff; linenr_T old_topline = curwin->w_topline; + long so = get_scrolloff_value(); if (curbuf->b_ml.ml_line_count == 1) { /* nothing to do */ beep_flush(); @@ -1836,7 +1848,7 @@ int onepage(Direction dir, long count) * last line. */ if (dir == FORWARD - ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - p_so) + ? ((curwin->w_topline >= curbuf->b_ml.ml_line_count - so) && curwin->w_botline > curbuf->b_ml.ml_line_count) : (curwin->w_topline == 1 && curwin->w_topfill == |