diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-01-31 18:26:10 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-01-31 18:26:10 +0100 |
commit | 375e3390078e740d3c83b0c118c50d9a920036c7 (patch) | |
tree | 34f565d4a9351b58d48d8d06e4a84b07effdb3fd /src | |
parent | b3051ce82f2e8af95ce3b6a41867f70aee5ecc82 (diff) | |
download | vim-git-375e3390078e740d3c83b0c118c50d9a920036c7.tar.gz |
patch 8.1.0864: cannot have a local value for 'scrolloff' and 'sidescrolloff'v8.1.0864
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)
Diffstat (limited to 'src')
-rw-r--r-- | src/edit.c | 2 | ||||
-rw-r--r-- | src/ex_cmds.c | 7 | ||||
-rw-r--r-- | src/ex_docmd.c | 2 | ||||
-rw-r--r-- | src/gui.c | 2 | ||||
-rw-r--r-- | src/misc2.c | 9 | ||||
-rw-r--r-- | src/move.c | 78 | ||||
-rw-r--r-- | src/normal.c | 13 | ||||
-rw-r--r-- | src/option.c | 52 | ||||
-rw-r--r-- | src/option.h | 2 | ||||
-rw-r--r-- | src/proto/option.pro | 2 | ||||
-rw-r--r-- | src/search.c | 14 | ||||
-rw-r--r-- | src/structs.h | 2 | ||||
-rw-r--r-- | src/testdir/test_options.vim | 35 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/window.c | 6 |
15 files changed, 165 insertions, 63 deletions
diff --git a/src/edit.c b/src/edit.c index de1666cc5..eac480314 100644 --- a/src/edit.c +++ b/src/edit.c @@ -728,7 +728,7 @@ edit( (int)curwin->w_wcol < mincol - curbuf->b_p_ts #endif && curwin->w_wrow == W_WINROW(curwin) - + curwin->w_height - 1 - p_so + + curwin->w_height - 1 - get_scrolloff_value() && (curwin->w_cursor.lnum != curwin->w_topline #ifdef FEAT_DIFF || curwin->w_topfill > 0 diff --git a/src/ex_cmds.c b/src/ex_cmds.c index 6d03d88ca..a3974c1ba 100644 --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -3784,6 +3784,7 @@ do_ecmd( #endif int readfile_flags = 0; int did_inc_redrawing_disabled = FALSE; + long *so_ptr = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; if (eap != NULL) command = eap->do_ecmd_cmd; @@ -4389,12 +4390,12 @@ do_ecmd( did_inc_redrawing_disabled = FALSE; if (!skip_redraw) { - n = p_so; + n = *so_ptr; if (topline == 0 && command == NULL) - p_so = 999; /* force cursor halfway the window */ + *so_ptr = 9999; // force cursor halfway the window update_topline(); curwin->w_scbind_pos = curwin->w_topline; - p_so = n; + *so_ptr = n; redraw_curbuf_later(NOT_VALID); /* redraw this buffer later */ } diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 1646a2213..b90ea7b17 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -8923,7 +8923,7 @@ ex_syncbind(exarg_T *eap UNUSED) { if (wp->w_p_scb && wp->w_buffer) { - y = wp->w_buffer->b_ml.ml_line_count - p_so; + y = wp->w_buffer->b_ml.ml_line_count - get_scrolloff_value(); if (topline > y) topline = y; } @@ -4405,7 +4405,7 @@ gui_do_scroll(void) #endif ) { - if (p_so != 0) + if (get_scrolloff_value() != 0) { cursor_correct(); /* fix window for 'so' */ update_topline(); /* avoid up/down jump */ diff --git a/src/misc2.c b/src/misc2.c index 657e16491..278cc330c 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -643,6 +643,7 @@ leftcol_changed(void) long lastcol; colnr_T s, e; int retval = FALSE; + long siso = get_sidescrolloff_value(); changed_cline_bef_curs(); lastcol = curwin->w_leftcol + curwin->w_width - curwin_col_off() - 1; @@ -652,15 +653,15 @@ leftcol_changed(void) * If the cursor is right or left of the screen, move it to last or first * character. */ - if (curwin->w_virtcol > (colnr_T)(lastcol - p_siso)) + if (curwin->w_virtcol > (colnr_T)(lastcol - siso)) { retval = TRUE; - coladvance((colnr_T)(lastcol - p_siso)); + coladvance((colnr_T)(lastcol - siso)); } - else if (curwin->w_virtcol < curwin->w_leftcol + p_siso) + else if (curwin->w_virtcol < curwin->w_leftcol + siso) { retval = TRUE; - (void)coladvance((colnr_T)(curwin->w_leftcol + p_siso)); + (void)coladvance((colnr_T)(curwin->w_leftcol + siso)); } /* diff --git a/src/move.c b/src/move.c index 14b7a6e7d..da29b36f5 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 diff --git a/src/normal.c b/src/normal.c index b512b559a..41af96628 100644 --- a/src/normal.c +++ b/src/normal.c @@ -2814,7 +2814,7 @@ do_mouse( /* Set global flag that we are extending the Visual area with mouse * dragging; temporarily minimize 'scrolloff'. */ - if (VIsual_active && is_drag && p_so) + if (VIsual_active && is_drag && get_scrolloff_value()) { /* In the very first line, allow scrolling one line */ if (mouse_row == 0) @@ -4635,7 +4635,7 @@ scroll_redraw(int up, long count) scrollup(count, TRUE); else scrolldown(count, TRUE); - if (p_so) + if (get_scrolloff_value()) { /* Adjust the cursor position for 'scrolloff'. Mark w_topline as * valid, otherwise the screen jumps back at the end of the file. */ @@ -4692,6 +4692,7 @@ nv_zet(cmdarg_T *cap) #ifdef FEAT_SPELL int undo = FALSE; #endif + long siso = get_sidescrolloff_value(); if (VIM_ISDIGIT(nchar)) { @@ -4874,8 +4875,8 @@ dozet: else #endif getvcol(curwin, &curwin->w_cursor, &col, NULL, NULL); - if ((long)col > p_siso) - col -= p_siso; + if ((long)col > siso) + col -= siso; else col = 0; if (curwin->w_leftcol != col) @@ -4896,10 +4897,10 @@ dozet: #endif getvcol(curwin, &curwin->w_cursor, NULL, NULL, &col); n = curwin->w_width - curwin_col_off(); - if ((long)col + p_siso < n) + if ((long)col + siso < n) col = 0; else - col = col + p_siso - n + 1; + col = col + siso - n + 1; if (curwin->w_leftcol != col) { curwin->w_leftcol = col; diff --git a/src/option.c b/src/option.c index abbbaa587..6d2bab1e0 100644 --- a/src/option.c +++ b/src/option.c @@ -227,6 +227,8 @@ #endif #define PV_SCBIND OPT_WIN(WV_SCBIND) #define PV_SCROLL OPT_WIN(WV_SCROLL) +#define PV_SISO OPT_BOTH(OPT_WIN(WV_SISO)) +#define PV_SO OPT_BOTH(OPT_WIN(WV_SO)) #ifdef FEAT_SPELL # define PV_SPELL OPT_WIN(WV_SPELL) #endif @@ -2333,7 +2335,7 @@ static struct vimoption options[] = (char_u *)&p_sj, PV_NONE, {(char_u *)1L, (char_u *)0L} SCTX_INIT}, {"scrolloff", "so", P_NUM|P_VI_DEF|P_VIM|P_RALL, - (char_u *)&p_so, PV_NONE, + (char_u *)&p_so, PV_SO, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"scrollopt", "sbo", P_STRING|P_VI_DEF|P_ONECOMMA|P_NODUP, (char_u *)&p_sbo, PV_NONE, @@ -2490,7 +2492,7 @@ static struct vimoption options[] = (char_u *)&p_ss, PV_NONE, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"sidescrolloff", "siso", P_NUM|P_VI_DEF|P_VIM|P_RBUF, - (char_u *)&p_siso, PV_NONE, + (char_u *)&p_siso, PV_SISO, {(char_u *)0L, (char_u *)0L} SCTX_INIT}, {"signcolumn", "scl", P_STRING|P_ALLOCED|P_VI_DEF|P_RWIN, #ifdef FEAT_SIGNS @@ -3736,11 +3738,19 @@ set_option_default( win_comp_scroll(curwin); else { - *(long *)varp = (long)(long_i)options[opt_idx].def_val[dvi]; + long def_val = (long)(long_i)options[opt_idx].def_val[dvi]; + + if ((long *)varp == &curwin->w_p_so + || (long *)varp == &curwin->w_p_siso) + // 'scrolloff' and 'sidescrolloff' local values have a + // different default value than the global default. + *(long *)varp = -1; + else + *(long *)varp = def_val; /* May also set global value for local option. */ if (both) *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = - *(long *)varp; + def_val; } } else /* P_BOOL */ @@ -9382,7 +9392,7 @@ set_num_option( } if (p_so < 0 && full_screen) { - errmsg = e_scroll; + errmsg = e_positive; p_so = 0; } if (p_siso < 0 && full_screen) @@ -10657,6 +10667,12 @@ unset_global_local_option(char_u *name, void *from) clear_string_option(&buf->b_p_tc); buf->b_tc_flags = 0; break; + case PV_SISO: + curwin->w_p_siso = -1; + break; + case PV_SO: + curwin->w_p_so = -1; + break; #ifdef FEAT_FIND_ID case PV_DEF: clear_string_option(&buf->b_p_def); @@ -10745,6 +10761,8 @@ get_varp_scope(struct vimoption *p, int opt_flags) case PV_AR: return (char_u *)&(curbuf->b_p_ar); case PV_TAGS: return (char_u *)&(curbuf->b_p_tags); case PV_TC: return (char_u *)&(curbuf->b_p_tc); + case PV_SISO: return (char_u *)&(curwin->w_p_siso); + case PV_SO: return (char_u *)&(curwin->w_p_so); #ifdef FEAT_FIND_ID case PV_DEF: return (char_u *)&(curbuf->b_p_def); case PV_INC: return (char_u *)&(curbuf->b_p_inc); @@ -10803,6 +10821,10 @@ get_varp(struct vimoption *p) ? (char_u *)&(curbuf->b_p_tc) : p->var; case PV_BKC: return *curbuf->b_p_bkc != NUL ? (char_u *)&(curbuf->b_p_bkc) : p->var; + case PV_SISO: return curwin->w_p_siso >= 0 + ? (char_u *)&(curwin->w_p_siso) : p->var; + case PV_SO: return curwin->w_p_so >= 0 + ? (char_u *)&(curwin->w_p_so) : p->var; #ifdef FEAT_FIND_ID case PV_DEF: return *curbuf->b_p_def != NUL ? (char_u *)&(curbuf->b_p_def) : p->var; @@ -13099,6 +13121,26 @@ get_sts_value(void) } /* + * Return the effective 'scrolloff' value for the current window, using the + * global value when appropriate. + */ + long +get_scrolloff_value(void) +{ + return curwin->w_p_so < 0 ? p_so : curwin->w_p_so; +} + +/* + * Return the effective 'sidescrolloff' value for the current window, using the + * global value when appropriate. + */ + long +get_sidescrolloff_value(void) +{ + return curwin->w_p_siso < 0 ? p_siso : curwin->w_p_siso; +} + +/* * Check matchpairs option for "*initc". * If there is a match set "*initc" to the matching character and "*findc" to * the opposite character. Set "*backwards" to the direction. diff --git a/src/option.h b/src/option.h index c282da325..90c05080b 100644 --- a/src/option.h +++ b/src/option.h @@ -1152,6 +1152,8 @@ enum #endif , WV_SCBIND , WV_SCROLL + , WV_SISO + , WV_SO #ifdef FEAT_SPELL , WV_SPELL #endif diff --git a/src/proto/option.pro b/src/proto/option.pro index 3da51c658..1027edf68 100644 --- a/src/proto/option.pro +++ b/src/proto/option.pro @@ -76,6 +76,8 @@ long get_sw_value_indent(buf_T *buf); long get_sw_value_pos(buf_T *buf, pos_T *pos); long get_sw_value_col(buf_T *buf, colnr_T col); long get_sts_value(void); +long get_scrolloff_value(void); +long get_sidescrolloff_value(void); void find_mps_values(int *initc, int *findc, int *backwards, int switchit); unsigned int get_bkc_value(buf_T *buf); int signcolumn_on(win_T *wp); diff --git a/src/search.c b/src/search.c index a4b4c4177..4b3f8532a 100644 --- a/src/search.c +++ b/src/search.c @@ -2601,6 +2601,8 @@ showmatch( #endif colnr_T save_dollar_vcol; char_u *p; + long *so = curwin->w_p_so >= 0 ? &curwin->w_p_so : &p_so; + long *siso = curwin->w_p_siso >= 0 ? &curwin->w_p_siso : &p_siso; /* * Only show match for chars in the 'matchpairs' option. @@ -2635,8 +2637,8 @@ showmatch( { mpos = *lpos; /* save the pos, update_screen() may change it */ save_cursor = curwin->w_cursor; - save_so = p_so; - save_siso = p_siso; + save_so = *so; + save_siso = *siso; /* Handle "$" in 'cpo': If the ')' is typed on top of the "$", * stop displaying the "$". */ if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol) @@ -2651,8 +2653,8 @@ showmatch( ui_cursor_shape(); /* may show different cursor shape */ #endif curwin->w_cursor = mpos; /* move to matching char */ - p_so = 0; /* don't use 'scrolloff' here */ - p_siso = 0; /* don't use 'sidescrolloff' here */ + *so = 0; /* don't use 'scrolloff' here */ + *siso = 0; /* don't use 'sidescrolloff' here */ showruler(FALSE); setcursor(); cursor_on(); /* make sure that the cursor is shown */ @@ -2672,8 +2674,8 @@ showmatch( else if (!char_avail()) ui_delay(p_mat * 100L, FALSE); curwin->w_cursor = save_cursor; /* restore cursor position */ - p_so = save_so; - p_siso = save_siso; + *so = save_so; + *siso = save_siso; #ifdef CURSOR_SHAPE State = save_state; ui_cursor_shape(); /* may show different cursor shape */ diff --git a/src/structs.h b/src/structs.h index ddc56bca4..e6cc8291f 100644 --- a/src/structs.h +++ b/src/structs.h @@ -2932,6 +2932,8 @@ struct window_S int w_p_brishift; /* additional shift for breakindent */ int w_p_brisbr; /* sbr in 'briopt' */ #endif + long w_p_siso; /* 'sidescrolloff' local value */ + long w_p_so; /* 'scrolloff' local value */ /* transform a pointer to a "onebuf" option into a "allbuf" option */ #define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T)) diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim index 740863e3c..83b315d00 100644 --- a/src/testdir/test_options.vim +++ b/src/testdir/test_options.vim @@ -483,3 +483,38 @@ func Test_shortmess_F2() bwipe bwipe endfunc + +func Test_local_scrolloff() + set so=5 + set siso=7 + split + call assert_equal(5, &so) + setlocal so=3 + call assert_equal(3, &so) + wincmd w + call assert_equal(5, &so) + wincmd w + setlocal so< + call assert_equal(5, &so) + setlocal so=0 + call assert_equal(0, &so) + setlocal so=-1 + call assert_equal(5, &so) + + call assert_equal(7, &siso) + setlocal siso=3 + call assert_equal(3, &siso) + wincmd w + call assert_equal(7, &siso) + wincmd w + setlocal siso< + call assert_equal(7, &siso) + setlocal siso=0 + call assert_equal(0, &siso) + setlocal siso=-1 + call assert_equal(7, &siso) + + close + set so& + set siso& +endfunc diff --git a/src/version.c b/src/version.c index 05b18ed7e..7a02fbdca 100644 --- a/src/version.c +++ b/src/version.c @@ -784,6 +784,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 864, +/**/ 863, /**/ 862, diff --git a/src/window.c b/src/window.c index d89f3a8e6..f78fccafe 100644 --- a/src/window.c +++ b/src/window.c @@ -4594,6 +4594,10 @@ win_alloc(win_T *after UNUSED, int hidden UNUSED) new_wp->w_cursor.lnum = 1; new_wp->w_scbind_pos = 1; + // use global option value for global-local options + new_wp->w_p_so = -1; + new_wp->w_p_siso = -1; + /* We won't calculate w_fraction until resizing the window */ new_wp->w_fraction = 0; new_wp->w_prev_fraction_row = -1; @@ -5871,7 +5875,7 @@ scroll_to_fraction(win_T *wp, int prev_height) if (wp == curwin) { - if (p_so) + if (get_scrolloff_value()) update_topline(); curs_columns(FALSE); /* validate w_wrow */ } |