aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/option.c158
-rw-r--r--src/nvim/options.lua2
-rw-r--r--src/nvim/window.c10
-rw-r--r--test/functional/ui/screen_basic_spec.lua24
4 files changed, 105 insertions, 89 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index f082bd83a7..197e70e8bf 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -2197,6 +2197,44 @@ static const char *did_set_laststatus(optset_T *args)
return NULL;
}
+/// Process the updated 'lines' or 'columns' option value.
+static const char *did_set_lines_or_columns(optset_T *args)
+{
+ // If the screen (shell) height has been changed, assume it is the
+ // physical screenheight.
+ if (p_lines != Rows || p_columns != Columns) {
+ // Changing the screen size is not allowed while updating the screen.
+ if (updating_screen) {
+ OptVal oldval = (OptVal){ .type = kOptValTypeNumber, .data = args->os_oldval };
+ set_option_varp(args->os_idx, args->os_varp, oldval, false);
+ } else if (full_screen) {
+ screen_resize((int)p_columns, (int)p_lines);
+ } else {
+ // TODO(bfredl): is this branch ever needed?
+ // Postpone the resizing; check the size and cmdline position for
+ // messages.
+ Rows = (int)p_lines;
+ Columns = (int)p_columns;
+ check_screensize();
+ int new_row = (int)(Rows - MAX(p_ch, 1));
+ if (cmdline_row > new_row && Rows > p_ch) {
+ assert(p_ch >= 0 && new_row <= INT_MAX);
+ cmdline_row = new_row;
+ }
+ }
+ if (p_window >= Rows || !option_was_set(kOptWindow)) {
+ p_window = Rows - 1;
+ }
+ }
+
+ // Adjust 'scrolljump' if needed.
+ if (p_sj >= Rows && full_screen) {
+ p_sj = Rows / 2;
+ }
+
+ return NULL;
+}
+
/// Process the updated 'lisp' option value.
static const char *did_set_lisp(optset_T *args)
{
@@ -2400,7 +2438,6 @@ static const char *did_set_previewwindow(optset_T *args)
/// Process the new 'pumblend' option value.
static const char *did_set_pumblend(optset_T *args FUNC_ATTR_UNUSED)
{
- p_pb = MAX(MIN(p_pb, 100), 0);
hl_invalidate_blends();
pum_grid.blending = (p_pb > 0);
if (pum_drawn()) {
@@ -2771,78 +2808,61 @@ static void do_spelllang_source(win_T *win)
}
/// Check the bounds of numeric options.
-static const char *check_num_option_bounds(OptInt *pp, OptInt old_value, char *errbuf,
- size_t errbuflen, const char *errmsg)
+///
+/// @param opt_idx Index in options[] table. Must not be kOptInvalid.
+/// @param[in] varp Pointer to option variable.
+/// @param[in,out] newval Pointer to new option value. Will be set to bound checked value.
+/// @param[out] errbuf Buffer for error message. Cannot be NULL.
+/// @param errbuflen Length of error buffer.
+///
+/// @return Error message, if any.
+static const char *check_num_option_bounds(OptIndex opt_idx, void *varp, OptInt *newval,
+ char *errbuf, size_t errbuflen)
+ FUNC_ATTR_NONNULL_ARG(4)
{
- int old_Rows = Rows; // remember old Rows
- // Check the (new) bounds for Rows and Columns here.
- if (p_lines < min_rows() && full_screen) {
- if (errbuf != NULL) {
+ const char *errmsg = NULL;
+
+ switch (opt_idx) {
+ case kOptLines:
+ if (*newval < min_rows() && full_screen) {
vim_snprintf(errbuf, errbuflen, _("E593: Need at least %d lines"), min_rows());
errmsg = errbuf;
+ *newval = min_rows();
}
- p_lines = min_rows();
- }
- if (p_columns < MIN_COLUMNS && full_screen) {
- if (errbuf != NULL) {
+ // True max size is defined by check_screensize().
+ *newval = MIN(*newval, INT_MAX);
+ break;
+ case kOptColumns:
+ if (*newval < MIN_COLUMNS && full_screen) {
vim_snprintf(errbuf, errbuflen, _("E594: Need at least %d columns"), MIN_COLUMNS);
errmsg = errbuf;
+ *newval = MIN_COLUMNS;
}
- p_columns = MIN_COLUMNS;
- }
-
- // True max size is defined by check_screensize()
- p_lines = MIN(p_lines, INT_MAX);
- p_columns = MIN(p_columns, INT_MAX);
-
- // If the screen (shell) height has been changed, assume it is the
- // physical screenheight.
- if (p_lines != Rows || p_columns != Columns) {
- // Changing the screen size is not allowed while updating the screen.
- if (updating_screen) {
- *pp = old_value;
- } else if (full_screen) {
- screen_resize((int)p_columns, (int)p_lines);
- } else {
- // TODO(bfredl): is this branch ever needed?
- // Postpone the resizing; check the size and cmdline position for
- // messages.
- Rows = (int)p_lines;
- Columns = (int)p_columns;
- check_screensize();
- int new_row = (int)(Rows - MAX(p_ch, 1));
- if (cmdline_row > new_row && Rows > p_ch) {
- assert(p_ch >= 0 && new_row <= INT_MAX);
- cmdline_row = new_row;
- }
- }
- if (p_window >= Rows || !option_was_set(kOptWindow)) {
- p_window = Rows - 1;
+ // True max size is defined by check_screensize().
+ *newval = MIN(*newval, INT_MAX);
+ break;
+ case kOptPumblend:
+ *newval = MAX(MIN(*newval, 100), 0);
+ break;
+ case kOptScrolljump:
+ if ((*newval < -100 || *newval >= Rows) && full_screen) {
+ errmsg = e_scroll;
+ *newval = 1;
}
- }
-
- if ((curwin->w_p_scr <= 0
- || (curwin->w_p_scr > curwin->w_height_inner && curwin->w_height_inner > 0))
- && full_screen) {
- if (pp == &(curwin->w_p_scr)) {
- if (curwin->w_p_scr != 0) {
+ break;
+ case kOptScroll:
+ if (varp == &(curwin->w_p_scr)
+ && (*newval <= 0
+ || (*newval > curwin->w_height_inner && curwin->w_height_inner > 0))
+ && full_screen) {
+ if (*newval != 0) {
errmsg = e_scroll;
}
- win_comp_scroll(curwin);
- } else if (curwin->w_p_scr <= 0) {
- // If 'scroll' became invalid because of a side effect silently adjust it.
- curwin->w_p_scr = 1;
- } else { // curwin->w_p_scr > curwin->w_height_inner
- curwin->w_p_scr = curwin->w_height_inner;
- }
- }
- if ((p_sj < -100 || p_sj >= Rows) && full_screen) {
- if (Rows != old_Rows) { // Rows changed, just adjust p_sj
- p_sj = Rows / 2;
- } else {
- errmsg = e_scroll;
- p_sj = 1;
+ *newval = win_default_scroll(curwin);
}
+ break;
+ default:
+ break;
}
return errmsg;
@@ -3512,14 +3532,6 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value
}
opt->flags |= P_ALLOCED;
- // Check the bound for num options.
- if (new_value.type == kOptValTypeNumber) {
- errmsg = check_num_option_bounds((OptInt *)varp, old_value.data.number, errbuf, errbuflen,
- errmsg);
- // Re-assign new_value because the new value was modified by the bound check.
- new_value = optval_from_varp(opt_idx, varp);
- }
-
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0 && (opt->indir & PV_BOTH)) {
// Global option with local value set to use global value.
// Free the local value and clear it.
@@ -3660,8 +3672,10 @@ static const char *set_option(const OptIndex opt_idx, void *varp, OptVal value,
if (value.type == kOptValTypeNumber) {
errmsg = validate_num_option((OptInt *)varp, &value.data.number);
-
- // Don't change the value and return early if validation failed.
+ if (errmsg != NULL) {
+ goto err;
+ }
+ errmsg = check_num_option_bounds(opt_idx, varp, &value.data.number, errbuf, errbuflen);
if (errmsg != NULL) {
goto err;
}
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index d599e0452d..8295483954 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -1269,6 +1269,7 @@ return {
},
{
abbreviation = 'co',
+ cb = 'did_set_lines_or_columns',
defaults = {
if_true = macros('DFLT_COLS'),
doc = '80 or terminal width',
@@ -4744,6 +4745,7 @@ return {
type = 'boolean',
},
{
+ cb = 'did_set_lines_or_columns',
defaults = {
if_true = macros('DFLT_ROWS'),
doc = '24 or terminal height',
diff --git a/src/nvim/window.c b/src/nvim/window.c
index b140337fec..d928063b2f 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -6561,14 +6561,16 @@ void win_new_width(win_T *wp, int width)
win_set_inner_size(wp, true);
}
+OptInt win_default_scroll(win_T *wp)
+{
+ return MAX(wp->w_height_inner / 2, 1);
+}
+
void win_comp_scroll(win_T *wp)
{
const OptInt old_w_p_scr = wp->w_p_scr;
+ wp->w_p_scr = win_default_scroll(wp);
- wp->w_p_scr = wp->w_height_inner / 2;
- if (wp->w_p_scr == 0) {
- wp->w_p_scr = 1;
- }
if (wp->w_p_scr != old_w_p_scr) {
// Used by "verbose set scroll".
wp->w_p_script_ctx[WV_SCROLL].script_ctx.sc_sid = SID_WINLAYOUT;
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index e1358a0335..b4ab3f54ca 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -618,22 +618,20 @@ local function screen_tests(linegrid)
]])
feed(':set columns=0<CR>')
screen:expect([[
- |*5
- {1: }|
- {8:E594: Need a}|
- {8:t least 12 c}|
- {8:olumns: colu}|
- {8:mns=0} |
- {7:Press ENTER }|
- {7:or type comm}|
- {7:and to conti}|
- {7:nue}^ |
+ |
+ {0:~ }|*7
+ {1: }|
+ {8:E594: Need at least }|
+ {8:12 columns: columns=}|
+ {8:0} |
+ {7:Press ENTER or type }|
+ {7:command to continue}^ |
]])
feed('<CR>')
screen:expect([[
- ^ |
- {0:~ }|*12
- |
+ ^ |
+ {0:~ }|*12
+ |
]])
end)
end)