vim-patch:8.1.0864 Make 'scrolloff' and 'sidescrolloff' options window local (#11854)

Problem: cannot have a local value for 'scrolloff' and 'sidescrolloff'

Author: Bram Moolenar

375e339007
This commit is contained in:
Will Eccles
2020-03-17 15:05:34 -04:00
committed by GitHub
parent 5a5c2f0290
commit 87d892afa0
14 changed files with 245 additions and 126 deletions

View File

@@ -1278,16 +1278,18 @@ struct window_S {
winopt_T w_onebuf_opt;
winopt_T w_allbuf_opt;
/* A few options have local flags for P_INSECURE. */
uint32_t w_p_stl_flags; /* flags for 'statusline' */
uint32_t w_p_fde_flags; /* flags for 'foldexpr' */
uint32_t w_p_fdt_flags; /* flags for 'foldtext' */
int *w_p_cc_cols; /* array of columns to highlight or NULL */
int w_p_brimin; /* minimum width for breakindent */
int w_p_brishift; /* additional shift for breakindent */
bool w_p_brisbr; /* sbr in 'briopt' */
// A few options have local flags for P_INSECURE.
uint32_t w_p_stl_flags; // flags for 'statusline'
uint32_t w_p_fde_flags; // flags for 'foldexpr'
uint32_t w_p_fdt_flags; // flags for 'foldtext'
int *w_p_cc_cols; // array of columns to highlight or NULL
int w_p_brimin; // minimum width for breakindent
int w_p_brishift; // additional shift for breakindent
bool w_p_brisbr; // sbr in 'briopt'
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 */
// transform a pointer to a "onebuf" option into a "allbuf" option
#define GLOBAL_WO(p) ((char *)p + sizeof(winopt_T))
long w_scbind_pos;

View File

@@ -593,7 +593,7 @@ static int insert_check(VimState *state)
if (curwin->w_wcol < s->mincol - curbuf->b_p_ts
&& curwin->w_wrow == curwin->w_winrow
+ curwin->w_height_inner - 1 - p_so
+ curwin->w_height_inner - 1 - get_scrolloff_value()
&& (curwin->w_cursor.lnum != curwin->w_topline
|| curwin->w_topfill > 0)) {
if (curwin->w_topfill > 0) {

View File

@@ -2177,6 +2177,7 @@ int do_ecmd(
int did_get_winopts = FALSE;
int readfile_flags = 0;
bool 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;
@@ -2678,13 +2679,14 @@ int do_ecmd(
RedrawingDisabled--;
did_inc_redrawing_disabled = false;
if (!skip_redraw) {
n = p_so;
if (topline == 0 && command == NULL)
p_so = 999; // force cursor to be vertically centered in the window
n = *so_ptr;
if (topline == 0 && command == NULL) {
*so_ptr = 999; // force cursor to be vertically centered in the window
}
update_topline();
curwin->w_scbind_pos = curwin->w_topline;
p_so = n;
redraw_curbuf_later(NOT_VALID); /* redraw this buffer later */
*so_ptr = n;
redraw_curbuf_later(NOT_VALID); // redraw this buffer later
}
if (p_im)

View File

@@ -7367,7 +7367,7 @@ static void ex_syncbind(exarg_T *eap)
topline = curwin->w_topline;
FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
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;
}

View File

@@ -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 ==

View File

@@ -2584,12 +2584,13 @@ 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) {
/* In the very first line, allow scrolling one line */
if (mouse_row == 0)
if (VIsual_active && is_drag && get_scrolloff_value()) {
// In the very first line, allow scrolling one line
if (mouse_row == 0) {
mouse_dragging = 2;
else
} else {
mouse_dragging = 1;
}
}
/* When dragging the mouse above the window, scroll down. */
@@ -4089,9 +4090,9 @@ void scroll_redraw(int up, long count)
scrollup(count, true);
else
scrolldown(count, true);
if (p_so) {
/* Adjust the cursor position for 'scrolloff'. Mark w_topline as
* valid, otherwise the screen jumps back at the end of the file. */
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.
cursor_correct();
check_cursor_moved(curwin);
curwin->w_valid |= VALID_TOPLINE;
@@ -4135,8 +4136,8 @@ static void nv_zet(cmdarg_T *cap)
int old_fen = curwin->w_p_fen;
bool undo = false;
assert(p_siso <= INT_MAX);
int l_p_siso = (int)p_siso;
int l_p_siso = (int)get_sidescrolloff_value();
assert(l_p_siso <= INT_MAX);
if (ascii_isdigit(nchar)) {
/*

View File

@@ -904,11 +904,19 @@ set_option_default(
if (options[opt_idx].indir == PV_SCROLL) {
win_comp_scroll(curwin);
} else {
*(long *)varp = (long)(intptr_t)options[opt_idx].def_val[dvi];
long def_val = (long)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
@@ -4349,7 +4357,7 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
}
} else if (pp == &p_so) {
if (value < 0 && full_screen) {
errmsg = e_scroll;
errmsg = e_positive;
}
} else if (pp == &p_siso) {
if (value < 0 && full_screen) {
@@ -5326,20 +5334,20 @@ showoneopt(
* Write modified options as ":set" commands to a file.
*
* There are three values for "opt_flags":
* OPT_GLOBAL: Write global option values and fresh values of
* buffer-local options (used for start of a session
* file).
* OPT_GLOBAL: Write global option values and fresh values of
* buffer-local options (used for start of a session
* file).
* OPT_GLOBAL + OPT_LOCAL: Idem, add fresh values of window-local options for
* curwin (used for a vimrc file).
* OPT_LOCAL: Write buffer-local option values for curbuf, fresh
* and local values for window-local options of
* curwin. Local values are also written when at the
* default value, because a modeline or autocommand
* may have set them when doing ":edit file" and the
* user has set them back at the default or fresh
* value.
* When "local_only" is true, don't write fresh
* values, only local values (for ":mkview").
* curwin (used for a vimrc file).
* OPT_LOCAL: Write buffer-local option values for curbuf, fresh
* and local values for window-local options of
* curwin. Local values are also written when at the
* default value, because a modeline or autocommand
* may have set them when doing ":edit file" and the
* user has set them back at the default or fresh
* value.
* When "local_only" is true, don't write fresh
* values, only local values (for ":mkview").
* (fresh value = value used for a new buffer or window for a local option).
*
* Return FAIL on error, OK otherwise.
@@ -5634,6 +5642,12 @@ void unset_global_local_option(char *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;
case PV_DEF:
clear_string_option(&buf->b_p_def);
break;
@@ -5706,6 +5720,8 @@ static char_u *get_varp_scope(vimoption_T *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);
case PV_DEF: return (char_u *)&(curbuf->b_p_def);
case PV_INC: return (char_u *)&(curbuf->b_p_inc);
case PV_DICT: return (char_u *)&(curbuf->b_p_dict);
@@ -5750,6 +5766,10 @@ static char_u *get_varp(vimoption_T *p)
? (char_u *)&(curbuf->b_p_tags) : p->var;
case PV_TC: return *curbuf->b_p_tc != NUL
? (char_u *)&(curbuf->b_p_tc) : 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;
case PV_BKC: return *curbuf->b_p_bkc != NUL
? (char_u *)&(curbuf->b_p_bkc) : p->var;
case PV_DEF: return *curbuf->b_p_def != NUL
@@ -6034,10 +6054,10 @@ void didset_window_options(win_T *wp)
* Copy global option values to local options for one buffer.
* Used when creating a new buffer and sometimes when entering a buffer.
* flags:
* BCO_ENTER We will enter the buf buffer.
* BCO_ALWAYS Always copy the options, but only set b_p_initialized when
* appropriate.
* BCO_NOHELP Don't copy the values to a help buffer.
* BCO_ENTER We will enter the buf buffer.
* BCO_ALWAYS Always copy the options, but only set b_p_initialized when
* appropriate.
* BCO_NOHELP Don't copy the values to a help buffer.
*/
void buf_copy_options(buf_T *buf, int flags)
{
@@ -7485,3 +7505,18 @@ dict_T *get_winbuf_options(const int bufopt)
return d;
}
/// 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;
}

View File

@@ -835,6 +835,8 @@ enum {
, WV_RLC
, WV_SCBIND
, WV_SCROLL
, WV_SISO
, WV_SO
, WV_SPELL
, WV_CUC
, WV_CUL

View File

@@ -1990,7 +1990,7 @@ return {
},
{
full_name='scrolloff', abbreviation='so',
type='number', scope={'global'},
type='number', scope={'global', 'window'},
vi_def=true,
vim=true,
redraw={'all_windows'},
@@ -2229,10 +2229,10 @@ return {
},
{
full_name='sidescrolloff', abbreviation='siso',
type='number', scope={'global'},
type='number', scope={'global', 'window'},
vi_def=true,
vim=true,
redraw={'current_buffer'},
redraw={'all_windows'},
varname='p_siso',
defaults={if_true={vi=0}}
},

View File

@@ -2227,6 +2227,8 @@ showmatch(
pos_T *lpos, save_cursor;
pos_T mpos;
colnr_T vcol;
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;
long save_so;
long save_siso;
int save_state;
@@ -2262,23 +2264,24 @@ showmatch(
&& vcol < curwin->w_leftcol + curwin->w_width_inner)) {
mpos = *lpos; // save the pos, update_screen() may change it
save_cursor = curwin->w_cursor;
save_so = p_so;
save_siso = p_siso;
/* Handle "$" in 'cpo': If the ')' is typed on top of the "$",
* stop displaying the "$". */
if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol)
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) {
dollar_vcol = -1;
++curwin->w_virtcol; /* do display ')' just before "$" */
update_screen(VALID); /* show the new char first */
}
curwin->w_virtcol++; // do display ')' just before "$"
update_screen(VALID); // show the new char first
save_dollar_vcol = dollar_vcol;
save_state = State;
State = SHOWMATCH;
ui_cursor_shape(); /* may show different cursor shape */
curwin->w_cursor = mpos; /* move to matching char */
p_so = 0; /* don't use 'scrolloff' here */
p_siso = 0; /* don't use 'sidescrolloff' here */
showruler(FALSE);
ui_cursor_shape(); // may show different cursor shape
curwin->w_cursor = mpos; // move to matching char
*so = 0; // don't use 'scrolloff' here
*siso = 0; // don't use 'sidescrolloff' here
showruler(false);
setcursor();
ui_flush();
/* Restore dollar_vcol(), because setcursor() may call curs_rows()
@@ -2294,11 +2297,11 @@ showmatch(
os_delay(p_mat * 100L, true);
else if (!char_avail())
os_delay(p_mat * 100L, false);
curwin->w_cursor = save_cursor; /* restore cursor position */
p_so = save_so;
p_siso = save_siso;
curwin->w_cursor = save_cursor; // restore cursor position
*so = save_so;
*siso = save_siso;
State = save_state;
ui_cursor_shape(); /* may show different cursor shape */
ui_cursor_shape(); // may show different cursor shape
}
}
}

View File

@@ -512,6 +512,41 @@ func Test_shortmess_F2()
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
func Test_visualbell()
set belloff=
set visualbell

View File

@@ -4689,6 +4689,10 @@ static win_T *win_alloc(win_T *after, int hidden)
new_wp->w_floating = 0;
new_wp->w_float_config = FLOAT_CONFIG_INIT;
// use global option 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;
@@ -5799,9 +5803,10 @@ void 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 */
}
curs_columns(false); // validate w_wrow
}
if (prev_height > 0) {
wp->w_prev_fraction_row = wp->w_wrow;