From 375e3390078e740d3c83b0c118c50d9a920036c7 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 31 Jan 2019 18:26:10 +0100 Subject: patch 8.1.0864: cannot have a local value for 'scrolloff' and 'sidescrolloff' Problem: Cannot have a local value for 'scrolloff' and 'sidescrolloff'. (Gary Holloway) Solution: Make 'scrolloff' and 'sidescrolloff' global-local. (mostly by Aron Widforss, closes #3539) --- src/move.c | 78 ++++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 35 deletions(-) (limited to 'src/move.c') diff --git a/src/move.c b/src/move.c index 14b7a6e7dc..da29b36f54 100644 --- a/src/move.c +++ b/src/move.c @@ -192,8 +192,9 @@ update_topline(void) #endif int check_topline = FALSE; int check_botline = FALSE; + long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; #ifdef FEAT_MOUSE - int save_so = p_so; + int save_so = *so_ptr; #endif /* If there is no valid screen and when the window height is zero just use @@ -214,7 +215,7 @@ update_topline(void) #ifdef FEAT_MOUSE /* When dragging with the mouse, don't scroll that quickly */ if (mouse_dragging > 0) - p_so = mouse_dragging - 1; + *so_ptr = mouse_dragging - 1; #endif old_topline = curwin->w_topline; @@ -268,11 +269,11 @@ update_topline(void) if (hasAnyFolding(curwin)) { /* Count the number of logical lines between the cursor and - * topline + p_so (approximation of how much will be + * topline + scrolloff (approximation of how much will be * scrolled). */ n = 0; for (lnum = curwin->w_cursor.lnum; - lnum < curwin->w_topline + p_so; ++lnum) + lnum < curwin->w_topline + *so_ptr; ++lnum) { ++n; /* stop at end of file or when we know we are far off */ @@ -283,7 +284,7 @@ update_topline(void) } else #endif - n = curwin->w_topline + p_so - curwin->w_cursor.lnum; + 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 @@ -325,7 +326,7 @@ update_topline(void) 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 #ifdef FEAT_FOLDING || hasAnyFolding(curwin) #endif @@ -354,11 +355,11 @@ update_topline(void) ) { n += loff.height; - if (n >= p_so) + if (n >= *so_ptr) break; botline_forw(&loff); } - if (n >= p_so) + if (n >= *so_ptr) /* sufficient context, no need to scroll */ check_botline = FALSE; } @@ -372,11 +373,11 @@ update_topline(void) if (hasAnyFolding(curwin)) { /* Count the number of logical lines between the cursor and - * botline - p_so (approximation of how much will be + * botline - scrolloff (approximation of how much will be * scrolled). */ line_count = 0; for (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 */ @@ -388,7 +389,7 @@ update_topline(void) else #endif line_count = curwin->w_cursor.lnum - curwin->w_botline - + 1 + p_so; + + 1 + *so_ptr; if (line_count <= curwin->w_height + 1) scroll_cursor_bot(scrolljump_value(), FALSE); else @@ -421,7 +422,7 @@ update_topline(void) } #ifdef FEAT_MOUSE - p_so = save_so; + *so_ptr = save_so; #endif } @@ -447,8 +448,9 @@ check_top_offset(void) { lineoff_T loff; int n; + long so = get_scrolloff_value(); - if (curwin->w_cursor.lnum < curwin->w_topline + p_so + if (curwin->w_cursor.lnum < curwin->w_topline + so #ifdef FEAT_FOLDING || hasAnyFolding(curwin) #endif @@ -462,7 +464,7 @@ check_top_offset(void) n = 0; #endif /* Count the visible screen lines above the cursor line. */ - while (n < p_so) + while (n < so) { topline_back(&loff); /* Stop when included a line above the window. */ @@ -474,7 +476,7 @@ check_top_offset(void) break; n += loff.height; } - if (n < p_so) + if (n < so) return TRUE; } return FALSE; @@ -946,6 +948,8 @@ 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). @@ -1028,9 +1032,9 @@ curs_columns( * If we get closer to the edge than 'sidescrolloff', scroll a little * extra */ - off_left = (int)startcol - (int)curwin->w_leftcol - p_siso; + off_left = (int)startcol - (int)curwin->w_leftcol - siso; off_right = (int)endcol - (int)(curwin->w_leftcol + curwin->w_width - - p_siso) + 1; + - siso) + 1; if (off_left < 0 || off_right > 0) { if (off_left < 0) @@ -1079,9 +1083,10 @@ curs_columns( prev_skipcol = curwin->w_skipcol; p_lines = 0; + if ((curwin->w_wrow >= curwin->w_height || ((prev_skipcol > 0 - || curwin->w_wrow + p_so >= curwin->w_height) + || curwin->w_wrow + so >= curwin->w_height) && (p_lines = #ifdef FEAT_DIFF plines_win_nofill @@ -1098,25 +1103,25 @@ curs_columns( /* Cursor past end of screen. Happens with a single line that does * not fit on screen. Find a skipcol to show the text around the * cursor. Avoid scrolling all the time. compute value of "extra": - * 1: Less than "p_so" lines above - * 2: Less than "p_so" lines below + * 1: Less than 'scrolloff' lines above + * 2: Less than 'scrolloff' 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. */ if (p_lines == 0) p_lines = plines_win(curwin, curwin->w_cursor.lnum, FALSE); --p_lines; - if (p_lines > curwin->w_wrow + p_so) - n = curwin->w_wrow + p_so; + if (p_lines > curwin->w_wrow + so) + n = curwin->w_wrow + so; else n = p_lines; if ((colnr_T)n >= curwin->w_height + curwin->w_skipcol / width) extra += 2; - if (extra == 3 || p_lines < p_so * 2) + if (extra == 3 || p_lines < so * 2) { /* not enough room for 'scrolloff', put cursor in the middle */ n = curwin->w_virtcol / width; @@ -1132,7 +1137,7 @@ curs_columns( else if (extra == 1) { /* less then 'scrolloff' lines above, decrease skipcol */ - extra = (curwin->w_skipcol + p_so * width - curwin->w_virtcol + extra = (curwin->w_skipcol + so * width - curwin->w_virtcol + width - 1) / width; if (extra > 0) { @@ -1464,7 +1469,7 @@ scrolldown_clamp(void) end_row += curwin->w_cline_height - 1 - curwin->w_virtcol / curwin->w_width; } - if (end_row < curwin->w_height - p_so) + if (end_row < curwin->w_height - get_scrolloff_value()) { #ifdef FEAT_DIFF if (can_fill) @@ -1522,7 +1527,7 @@ scrollup_clamp(void) validate_virtcol(); start_row -= curwin->w_virtcol / curwin->w_width; } - if (start_row >= p_so) + if (start_row >= get_scrolloff_value()) { #ifdef FEAT_DIFF if (curwin->w_topfill > 0) @@ -1666,7 +1671,7 @@ scroll_cursor_top(int min_scroll, int always) linenr_T old_topfill = curwin->w_topfill; #endif linenr_T new_topline; - int off = p_so; + int off = get_scrolloff_value(); #ifdef FEAT_MOUSE if (mouse_dragging > 0) @@ -1842,6 +1847,7 @@ scroll_cursor_bot(int min_scroll, int set_topbot) linenr_T old_valid = curwin->w_valid; int old_empty_rows = curwin->w_empty_rows; linenr_T cln; /* Cursor Line Number */ + long so = get_scrolloff_value(); cln = curwin->w_cursor.lnum; if (set_topbot) @@ -1898,7 +1904,7 @@ scroll_cursor_bot(int min_scroll, int set_topbot) * Stop counting lines to scroll when * - hitting start of the file * - scrolled nothing or at least 'sj' lines - * - at least 'so' lines below the cursor + * - at least 'scrolloff' lines below the cursor * - lines between botline and cursor have been counted */ #ifdef FEAT_FOLDING @@ -1924,7 +1930,7 @@ scroll_cursor_bot(int min_scroll, int set_topbot) #ifdef FEAT_MOUSE mouse_dragging > 0 ? mouse_dragging - 1 : #endif - p_so)) + so)) || boff.lnum + 1 > curbuf->b_ml.ml_line_count) && loff.lnum <= curwin->w_botline #ifdef FEAT_DIFF @@ -1970,7 +1976,7 @@ scroll_cursor_bot(int min_scroll, int set_topbot) #ifdef FEAT_MOUSE mouse_dragging > 0 ? mouse_dragging - 1 : #endif - p_so) || scrolled < min_scroll) + so) || scrolled < min_scroll) { extra += boff.height; if (boff.lnum >= curwin->w_botline @@ -2124,7 +2130,7 @@ scroll_cursor_halfway(int atend) /* * Correct the cursor position so that it is in a part of the screen at least - * 'so' lines from the top and bottom, if possible. + * 'scrolloff' lines from the top and bottom, if possible. * If not possible, put it at the same position as scroll_cursor_halfway(). * When called topline must be valid! */ @@ -2138,13 +2144,14 @@ cursor_correct(void) int above_wanted, below_wanted; linenr_T cln; /* Cursor Line Number */ int max_off; + long so = get_scrolloff_value(); /* * 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. */ - above_wanted = p_so; - below_wanted = p_so; + above_wanted = so; + below_wanted = so; #ifdef FEAT_MOUSE if (mouse_dragging > 0) { @@ -2262,6 +2269,7 @@ onepage(int 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 */ { @@ -2279,7 +2287,7 @@ onepage(int 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 #ifdef FEAT_DIFF -- cgit v1.2.3