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:
parent
5a5c2f0290
commit
87d892afa0
|
@ -4900,13 +4900,17 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
|
||||
*'scrolloff'* *'so'*
|
||||
'scrolloff' 'so' number (default 0)
|
||||
global
|
||||
global or local to window |global-local|
|
||||
Minimal number of screen lines to keep above and below the cursor.
|
||||
This will make some context visible around where you are working. If
|
||||
you set it to a very large value (999) the cursor line will always be
|
||||
in the middle of the window (except at the start or end of the file or
|
||||
when long lines wrap).
|
||||
For scrolling horizontally see 'sidescrolloff'.
|
||||
After using the local value, go back the global value with one of
|
||||
these two: >
|
||||
setlocal scrolloff<
|
||||
setlocal scrolloff=-1
|
||||
< For scrolling horizontally see 'sidescrolloff'.
|
||||
|
||||
*'scrollopt'* *'sbo'*
|
||||
'scrollopt' 'sbo' string (default "ver,jump")
|
||||
|
@ -5515,7 +5519,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
|
||||
*'sidescrolloff'* *'siso'*
|
||||
'sidescrolloff' 'siso' number (default 0)
|
||||
global
|
||||
global or local to window |global-local|
|
||||
The minimal number of screen columns to keep to the left and to the
|
||||
right of the cursor if 'nowrap' is set. Setting this option to a
|
||||
value greater than 0 while having |'sidescroll'| also at a non-zero
|
||||
|
@ -5524,7 +5528,11 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||
to a large value (like 999) has the effect of keeping the cursor
|
||||
horizontally centered in the window, as long as one does not come too
|
||||
close to the beginning of the line.
|
||||
|
||||
After using the local value, go back the global value with one of
|
||||
these two: >
|
||||
setlocal sidescrolloff<
|
||||
setlocal sidescrolloff=-1
|
||||
<
|
||||
Example: Try this together with 'sidescroll' and 'listchars' as
|
||||
in the following example to never allow the cursor to move
|
||||
onto the "extends" character: >
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
120
src/nvim/move.c
120
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 ==
|
||||
|
|
|
@ -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)) {
|
||||
/*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -835,6 +835,8 @@ enum {
|
|||
, WV_RLC
|
||||
, WV_SCBIND
|
||||
, WV_SCROLL
|
||||
, WV_SISO
|
||||
, WV_SO
|
||||
, WV_SPELL
|
||||
, WV_CUC
|
||||
, WV_CUL
|
||||
|
|
|
@ -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}}
|
||||
},
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -65,8 +65,6 @@ describe(':set validation', function()
|
|||
should_succeed('regexpengine', 2)
|
||||
should_fail('report', -1, 'E487')
|
||||
should_succeed('report', 0)
|
||||
should_fail('scrolloff', -1, 'E49')
|
||||
should_fail('sidescrolloff', -1, 'E487')
|
||||
should_fail('sidescroll', -1, 'E487')
|
||||
should_fail('cmdwinheight', 0, 'E487')
|
||||
should_fail('updatetime', -1, 'E487')
|
||||
|
@ -82,6 +80,22 @@ describe(':set validation', function()
|
|||
meths.set_option('window', -10)
|
||||
eq(23, meths.get_option('window'))
|
||||
eq('', eval("v:errmsg"))
|
||||
|
||||
-- 'scrolloff' and 'sidescrolloff' can have a -1 value when
|
||||
-- set for the current window, but not globally
|
||||
feed_command('setglobal scrolloff=-1')
|
||||
eq('E487', eval("v:errmsg"):match("E%d*"))
|
||||
|
||||
feed_command('setglobal sidescrolloff=-1')
|
||||
eq('E487', eval("v:errmsg"):match("E%d*"))
|
||||
|
||||
feed_command('let v:errmsg=""')
|
||||
|
||||
feed_command('setlocal scrolloff=-1')
|
||||
eq('', eval("v:errmsg"))
|
||||
|
||||
feed_command('setlocal sidescrolloff=-1')
|
||||
eq('', eval("v:errmsg"))
|
||||
end)
|
||||
|
||||
it('set wmh/wh wmw/wiw checks', function()
|
||||
|
|
Loading…
Reference in New Issue