Merge pull request #6377 from yagebu/option-fixes

options: fixes and some refactoring for number options

Closes #6696
This commit is contained in:
James McCoy
2018-03-29 09:11:22 -04:00
committed by GitHub
2 changed files with 318 additions and 244 deletions

View File

@@ -13,7 +13,8 @@
// add some code to didset_window_options(). // add some code to didset_window_options().
// - For a buffer option, add some code to buf_copy_options(). // - For a buffer option, add some code to buf_copy_options().
// - For a buffer string option, add code to check_buf_options(). // - For a buffer string option, add code to check_buf_options().
// - If it's a numeric option, add any necessary bounds checks to do_set(). // - If it's a numeric option, add any necessary bounds checks to
// set_num_option().
// - If it's a list of flags, add some code in do_set(), search for WW_ALL. // - If it's a list of flags, add some code in do_set(), search for WW_ALL.
// - When adding an option with expansion (P_EXPAND), but with a different // - When adding an option with expansion (P_EXPAND), but with a different
// default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP. // default for Vi and Vim (no P_VI_DEF), add some code at VIMEXP.
@@ -1467,8 +1468,7 @@ do_set (
goto skip; goto skip;
} }
} else if (*arg == '-' || ascii_isdigit(*arg)) { } else if (*arg == '-' || ascii_isdigit(*arg)) {
// Allow negative (for 'undolevels'), octal and // Allow negative, octal and hex numbers.
// hex numbers.
vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0); vim_str2nr(arg, NULL, &i, STR2NR_ALL, &value, NULL, 0);
if (arg[i] != NUL && !ascii_iswhite(arg[i])) { if (arg[i] != NUL && !ascii_iswhite(arg[i])) {
errmsg = e_invarg; errmsg = e_invarg;
@@ -4089,110 +4089,207 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
return (char *)e_secure; return (char *)e_secure;
} }
// Many number options assume their value is in the signed int range.
if (value < INT_MIN || value > INT_MAX) {
return (char *)e_invarg;
}
// Options that need some validation.
if (pp == &p_wh) {
if (value < 1) {
errmsg = e_positive;
} else if (p_wmh > value) {
errmsg = e_winheight;
}
} else if (pp == &p_hh) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &p_wmh) {
if (value < 0) {
errmsg = e_positive;
} else if (value > p_wh) {
errmsg = e_winheight;
}
} else if (pp == &p_wiw) {
if (value < 1) {
errmsg = e_positive;
} else if (p_wmw > value) {
errmsg = e_winwidth;
}
} else if (pp == &p_wmw) {
if (value < 0) {
errmsg = e_positive;
} else if (value > p_wiw) {
errmsg = e_winwidth;
}
} else if (pp == &p_mco) {
if (value > MAX_MCO) {
errmsg = e_invarg;
} else if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &p_titlelen) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &p_uc) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &p_ch) {
if (value < 1) {
errmsg = e_positive;
}
} else if (pp == &p_tm) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &p_hi) {
if (value < 0) {
errmsg = e_positive;
} else if (value > 10000) {
errmsg = e_invarg;
}
} else if (pp == &p_re) {
if (value < 0 || value > 2) {
errmsg = e_invarg;
}
} else if (pp == &p_report) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &p_titlelen) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &p_so) {
if (value < 0 && full_screen) {
errmsg = e_scroll;
}
} else if (pp == &p_siso) {
if (value < 0 && full_screen) {
errmsg = e_positive;
}
} else if (pp == &p_cwh) {
if (value < 1) {
errmsg = e_positive;
}
} else if (pp == &p_ut) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &p_ss) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &curwin->w_p_fdl
|| pp == (long *)GLOBAL_WO(&curwin->w_p_fdl)) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &curwin->w_p_fdc
|| pp == (long *)GLOBAL_WO(&curwin->w_p_fdc)) {
if (value < 0) {
errmsg = e_positive;
} else if (value > 12) {
errmsg = e_invarg;
}
} else if (pp == &curwin->w_p_cole
|| pp == (long *)GLOBAL_WO(&curwin->w_p_cole)) {
if (value < 0) {
errmsg = e_positive;
} else if (value > 3) {
errmsg = e_invarg;
}
} else if (pp == &curwin->w_p_nuw
|| pp == (long *)GLOBAL_WO(&curwin->w_p_nuw)) {
if (value < 1) {
errmsg = e_positive;
} else if (value > 10) {
errmsg = e_invarg;
}
} else if (pp == &curbuf->b_p_iminsert || pp == &p_iminsert) {
if (value < 0 || value > B_IMODE_LAST) {
errmsg = e_invarg;
}
} else if (pp == &curbuf->b_p_imsearch || pp == &p_imsearch) {
if (value < -1 || value > B_IMODE_LAST) {
errmsg = e_invarg;
}
} else if (pp == &curbuf->b_p_channel || pp == &p_channel) {
errmsg = e_invarg;
} else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) {
if (value < -1 || value > SB_MAX
|| (value != -1 && opt_flags == OPT_LOCAL && !curbuf->terminal)) {
errmsg = e_invarg;
}
} else if (pp == &curbuf->b_p_sw || pp == &p_sw) {
if (value < 0) {
errmsg = e_positive;
}
} else if (pp == &curbuf->b_p_ts || pp == &p_ts) {
if (value < 1) {
errmsg = e_positive;
}
} else if (pp == &curbuf->b_p_tw || pp == &p_tw) {
if (value < 0) {
errmsg = e_positive;
}
}
// Don't change the value and return early if validation failed.
if (errmsg != NULL) {
return (char *)errmsg;
}
*pp = value; *pp = value;
/* Remember where the option was set. */ // Remember where the option was set.
set_option_scriptID_idx(opt_idx, opt_flags, current_SID); set_option_scriptID_idx(opt_idx, opt_flags, current_SID);
if (curbuf->b_p_sw < 0) { // For these options we want to fix some invalid values.
errmsg = e_positive; if (pp == &p_window) {
curbuf->b_p_sw = curbuf->b_p_ts; if (p_window < 1) {
} p_window = Rows - 1;
} else if (p_window >= Rows) {
/* p_window = Rows - 1;
* Number options that need some action when changed
*/
if (pp == &p_wh || pp == &p_hh) {
if (p_wh < 1) {
errmsg = e_positive;
p_wh = 1;
} }
if (p_wmh > p_wh) { } else if (pp == &p_ch) {
errmsg = e_winheight; if (p_ch > Rows - min_rows() + 1) {
p_wh = p_wmh; p_ch = Rows - min_rows() + 1;
}
if (p_hh < 0) {
errmsg = e_positive;
p_hh = 0;
}
/* Change window height NOW */
if (!ONE_WINDOW) {
if (pp == &p_wh && curwin->w_height < p_wh)
win_setheight((int)p_wh);
if (pp == &p_hh && curbuf->b_help && curwin->w_height < p_hh)
win_setheight((int)p_hh);
} }
} }
/* 'winminheight' */
else if (pp == &p_wmh) { // Number options that need some action when changed
if (p_wmh < 0) { if (pp == &p_wh) {
errmsg = e_positive; if (!ONE_WINDOW && curwin->w_height < p_wh) {
p_wmh = 0; win_setheight((int)p_wh);
} }
if (p_wmh > p_wh) { } else if (pp == &p_hh) {
errmsg = e_winheight; if (!ONE_WINDOW && curbuf->b_help && curwin->w_height < p_hh) {
p_wmh = p_wh; win_setheight((int)p_hh);
} }
} else if (pp == &p_wmh) {
win_setminheight(); win_setminheight();
} else if (pp == &p_wiw) { } else if (pp == &p_wiw) {
if (p_wiw < 1) { if (!ONE_WINDOW && curwin->w_width < p_wiw) {
errmsg = e_positive;
p_wiw = 1;
}
if (p_wmw > p_wiw) {
errmsg = e_winwidth;
p_wiw = p_wmw;
}
/* Change window width NOW */
if (!ONE_WINDOW && curwin->w_width < p_wiw)
win_setwidth((int)p_wiw); win_setwidth((int)p_wiw);
}
/* 'winminwidth' */
else if (pp == &p_wmw) {
if (p_wmw < 0) {
errmsg = e_positive;
p_wmw = 0;
} }
if (p_wmw > p_wiw) {
errmsg = e_winwidth;
p_wmw = p_wiw;
}
win_setminheight();
} else if (pp == &p_ls) { } else if (pp == &p_ls) {
/* (re)set last window status line */ last_status(false); // (re)set last window status line.
last_status(false); } else if (pp == &p_stal) {
} // (re)set tab page line
/* (re)set tab page line */ shell_new_rows(); // recompute window positions and heights
else if (pp == &p_stal) { } else if (pp == &curwin->w_p_fdl) {
shell_new_rows(); /* recompute window positions and heights */
}
/* 'foldlevel' */
else if (pp == &curwin->w_p_fdl) {
if (curwin->w_p_fdl < 0)
curwin->w_p_fdl = 0;
newFoldLevel(); newFoldLevel();
} } else if (pp == &curwin->w_p_fml) {
/* 'foldminlines' */
else if (pp == &curwin->w_p_fml) {
foldUpdateAll(curwin); foldUpdateAll(curwin);
} } else if (pp == &curwin->w_p_fdn) {
/* 'foldnestmax' */ if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin)) {
else if (pp == &curwin->w_p_fdn) {
if (foldmethodIsSyntax(curwin) || foldmethodIsIndent(curwin))
foldUpdateAll(curwin); foldUpdateAll(curwin);
}
/* 'foldcolumn' */
else if (pp == &curwin->w_p_fdc) {
if (curwin->w_p_fdc < 0) {
errmsg = e_positive;
curwin->w_p_fdc = 0;
} else if (curwin->w_p_fdc > 12) {
errmsg = e_invarg;
curwin->w_p_fdc = 12;
} }
// 'shiftwidth' or 'tabstop' } else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts) {
} else if (pp == &curbuf->b_p_sw || pp == (long *)&curbuf->b_p_ts) { // 'shiftwidth' or 'tabstop'
if (foldmethodIsIndent(curwin)) { if (foldmethodIsIndent(curwin)) {
foldUpdateAll(curwin); foldUpdateAll(curwin);
} }
@@ -4201,126 +4298,50 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0) { if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0) {
parse_cino(curbuf); parse_cino(curbuf);
} }
} } else if (pp == &p_mco) {
/* 'maxcombine' */ screenclear(); // will re-allocate the screen
else if (pp == &p_mco) {
if (p_mco > MAX_MCO)
p_mco = MAX_MCO;
else if (p_mco < 0)
p_mco = 0;
screenclear(); /* will re-allocate the screen */
} else if (pp == &curbuf->b_p_iminsert) { } else if (pp == &curbuf->b_p_iminsert) {
if (curbuf->b_p_iminsert < 0 || curbuf->b_p_iminsert > B_IMODE_LAST) {
errmsg = e_invarg;
curbuf->b_p_iminsert = B_IMODE_NONE;
}
p_iminsert = curbuf->b_p_iminsert;
showmode(); showmode();
/* Show/unshow value of 'keymap' in status lines. */ // Show/unshow value of 'keymap' in status lines.
status_redraw_curbuf(); status_redraw_curbuf();
} else if (pp == &p_window) { } else if (pp == &p_titlelen) {
if (p_window < 1) // if 'titlelen' has changed, redraw the title
p_window = 1; if (starting != NO_SCREEN && old_value != p_titlelen) {
else if (p_window >= Rows) need_maketitle = true;
p_window = Rows - 1;
} else if (pp == &curbuf->b_p_imsearch) {
if (curbuf->b_p_imsearch < -1 || curbuf->b_p_imsearch > B_IMODE_LAST) {
errmsg = e_invarg;
curbuf->b_p_imsearch = B_IMODE_NONE;
} }
p_imsearch = curbuf->b_p_imsearch; } else if (pp == &p_ch) {
} else if (pp == &p_channel || pp == &curbuf->b_p_channel) { // if p_ch changed value, change the command line height
errmsg = e_invarg; // Only compute the new window layout when startup has been
*pp = old_value; // completed. Otherwise the frame sizes may be wrong.
} if (p_ch != old_value && full_screen) {
/* if 'titlelen' has changed, redraw the title */
else if (pp == &p_titlelen) {
if (p_titlelen < 0) {
errmsg = e_positive;
p_titlelen = 85;
}
if (starting != NO_SCREEN && old_value != p_titlelen)
need_maketitle = TRUE;
}
/* if p_ch changed value, change the command line height */
else if (pp == &p_ch) {
if (p_ch < 1) {
errmsg = e_positive;
p_ch = 1;
}
if (p_ch > Rows - min_rows() + 1)
p_ch = Rows - min_rows() + 1;
/* Only compute the new window layout when startup has been
* completed. Otherwise the frame sizes may be wrong. */
if (p_ch != old_value && full_screen
)
command_height(); command_height();
}
/* when 'updatecount' changes from zero to non-zero, open swap files */
else if (pp == &p_uc) {
if (p_uc < 0) {
errmsg = e_positive;
p_uc = 100;
} }
if (p_uc && !old_value) } else if (pp == &p_uc) {
// when 'updatecount' changes from zero to non-zero, open swap files
if (p_uc && !old_value) {
ml_open_files(); ml_open_files();
} else if (pp == &curwin->w_p_cole) {
if (curwin->w_p_cole < 0) {
errmsg = e_positive;
curwin->w_p_cole = 0;
} else if (curwin->w_p_cole > 3) {
errmsg = e_invarg;
curwin->w_p_cole = 3;
} }
} } else if (pp == &p_ul || pp == &curbuf->b_p_ul) {
/* sync undo before 'undolevels' changes */ // sync undo before 'undolevels' changes
else if (pp == &p_ul) { // use the old value, otherwise u_sync() may not work properly
/* use the old value, otherwise u_sync() may not work properly */ *pp = old_value;
p_ul = old_value; u_sync(true);
u_sync(TRUE); *pp = value;
p_ul = value;
} else if (pp == &curbuf->b_p_ul) {
/* use the old value, otherwise u_sync() may not work properly */
curbuf->b_p_ul = old_value;
u_sync(TRUE);
curbuf->b_p_ul = value;
}
/* 'numberwidth' must be positive */
else if (pp == &curwin->w_p_nuw) {
if (curwin->w_p_nuw < 1) {
errmsg = e_positive;
curwin->w_p_nuw = 1;
}
if (curwin->w_p_nuw > 10) {
errmsg = e_invarg;
curwin->w_p_nuw = 10;
}
curwin->w_nrwidth_line_count = 0;
} else if (pp == &curbuf->b_p_tw) { } else if (pp == &curbuf->b_p_tw) {
if (curbuf->b_p_tw < 0) {
errmsg = e_positive;
curbuf->b_p_tw = 0;
}
FOR_ALL_TAB_WINDOWS(tp, wp) { FOR_ALL_TAB_WINDOWS(tp, wp) {
check_colorcolumn(wp); check_colorcolumn(wp);
} }
} else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) { } else if (pp == &curbuf->b_p_scbk || pp == &p_scbk) {
// 'scrollback' if (curbuf->terminal) {
if (*pp < -1 || *pp > SB_MAX
|| (*pp != -1 && opt_flags == OPT_LOCAL && !curbuf->terminal)) {
errmsg = e_invarg;
*pp = old_value;
} else if (curbuf->terminal) {
// Force the scrollback to take effect. // Force the scrollback to take effect.
terminal_resize(curbuf->terminal, UINT16_MAX, UINT16_MAX); terminal_resize(curbuf->terminal, UINT16_MAX, UINT16_MAX);
} }
} else if (pp == &curwin->w_p_nuw) {
curwin->w_nrwidth_line_count = 0;
} }
/*
* Check the bounds for numeric options here // Check the (new) bounds for Rows and Columns here.
*/
if (Rows < min_rows() && full_screen) { if (Rows < min_rows() && full_screen) {
if (errbuf != NULL) { if (errbuf != NULL) {
vim_snprintf((char *)errbuf, errbuflen, vim_snprintf((char *)errbuf, errbuflen,
@@ -4340,19 +4361,17 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
limit_screen_size(); limit_screen_size();
/* // If the screen (shell) height has been changed, assume it is the
* If the screen (shell) height has been changed, assume it is the // physical screenheight.
* physical screenheight.
*/
if (old_Rows != Rows || old_Columns != Columns) { if (old_Rows != Rows || old_Columns != Columns) {
/* Changing the screen size is not allowed while updating the screen. */ // Changing the screen size is not allowed while updating the screen.
if (updating_screen) { if (updating_screen) {
*pp = old_value; *pp = old_value;
} else if (full_screen) { } else if (full_screen) {
screen_resize((int)Columns, (int)Rows); screen_resize((int)Columns, (int)Rows);
} else { } else {
/* Postpone the resizing; check the size and cmdline position for // Postpone the resizing; check the size and cmdline position for
* messages. */ // messages.
check_shellsize(); check_shellsize();
if (cmdline_row > Rows - p_ch && Rows > p_ch) { if (cmdline_row > Rows - p_ch && Rows > p_ch) {
assert(p_ch >= 0 && Rows - p_ch <= INT_MAX); assert(p_ch >= 0 && Rows - p_ch <= INT_MAX);
@@ -4364,14 +4383,6 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
} }
} }
if (curbuf->b_p_ts <= 0) {
errmsg = e_positive;
curbuf->b_p_ts = 8;
}
if (p_tm < 0) {
errmsg = e_positive;
p_tm = 0;
}
if ((curwin->w_p_scr <= 0 if ((curwin->w_p_scr <= 0
|| (curwin->w_p_scr > curwin->w_height || (curwin->w_p_scr > curwin->w_height
&& curwin->w_height > 0)) && curwin->w_height > 0))
@@ -4388,21 +4399,6 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
else /* curwin->w_p_scr > curwin->w_height */ else /* curwin->w_p_scr > curwin->w_height */
curwin->w_p_scr = curwin->w_height; curwin->w_p_scr = curwin->w_height;
} }
if (p_hi < 0) {
errmsg = e_positive;
p_hi = 0;
} else if (p_hi > 10000) {
errmsg = e_invarg;
p_hi = 10000;
}
if (p_re < 0 || p_re > 2) {
errmsg = e_invarg;
p_re = 0;
}
if (p_report < 0) {
errmsg = e_positive;
p_report = 1;
}
if ((p_sj < -100 || p_sj >= Rows) && full_screen) { if ((p_sj < -100 || p_sj >= Rows) && full_screen) {
if (Rows != old_Rows) /* Rows changed, just adjust p_sj */ if (Rows != old_Rows) /* Rows changed, just adjust p_sj */
p_sj = Rows / 2; p_sj = Rows / 2;
@@ -4411,30 +4407,11 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
p_sj = 1; p_sj = 1;
} }
} }
if (p_so < 0 && full_screen) {
errmsg = e_scroll;
p_so = 0;
}
if (p_siso < 0 && full_screen) {
errmsg = e_positive;
p_siso = 0;
}
if (p_cwh < 1) {
errmsg = e_positive;
p_cwh = 1;
}
if (p_ut < 0) {
errmsg = e_positive;
p_ut = 2000;
}
if (p_ss < 0) {
errmsg = e_positive;
p_ss = 0;
}
/* May set global value for local option. */ // May set global value for local option.
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
*(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp; *(long *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL) = *pp;
}
if (pp == &curbuf->b_p_scbk && !curbuf->terminal) { if (pp == &curbuf->b_p_scbk && !curbuf->terminal) {
// Normal buffer: reset local 'scrollback' after updating the global value. // Normal buffer: reset local 'scrollback' after updating the global value.

View File

@@ -0,0 +1,97 @@
-- Tests for :setlocal and :setglobal
local helpers = require('test.functional.helpers')(after_each)
local clear, feed_command, eval, eq, meths =
helpers.clear, helpers.feed_command, helpers.eval, helpers.eq, helpers.meths
local function should_fail(opt, value, errmsg)
feed_command('setglobal ' .. opt .. '=' .. value)
eq(errmsg, eval("v:errmsg"):match("E%d*"))
feed_command('let v:errmsg = ""')
feed_command('setlocal ' .. opt .. '=' .. value)
eq(errmsg, eval("v:errmsg"):match("E%d*"))
feed_command('let v:errmsg = ""')
local status, err = pcall(meths.set_option, opt, value)
eq(status, false)
eq(errmsg, err:match("E%d*"))
eq('', eval("v:errmsg"))
end
local function should_succeed(opt, value)
feed_command('setglobal ' .. opt .. '=' .. value)
feed_command('setlocal ' .. opt .. '=' .. value)
meths.set_option(opt, value)
eq(value, meths.get_option(opt))
eq('', eval("v:errmsg"))
end
describe(':setlocal', function()
before_each(clear)
it('setlocal sets only local value', function()
eq(0, meths.get_option('iminsert'))
feed_command('setlocal iminsert=1')
eq(0, meths.get_option('iminsert'))
eq(0, meths.get_option('imsearch'))
feed_command('setlocal imsearch=1')
eq(0, meths.get_option('imsearch'))
end)
end)
describe(':set validation', function()
before_each(clear)
it('setlocal and setglobal validate values', function()
should_fail('shiftwidth', -10, 'E487')
should_succeed('shiftwidth', 0)
should_fail('tabstop', -10, 'E487')
should_fail('winheight', -10, 'E487')
should_fail('winheight', 0, 'E487')
should_fail('winminheight', -1, 'E487')
should_succeed('winminheight', 0)
should_fail('winwidth', 0, 'E487')
should_fail('helpheight', -1, 'E487')
should_fail('maxcombine', 7, 'E474')
should_fail('iminsert', 3, 'E474')
should_fail('imsearch', 3, 'E474')
should_fail('titlelen', -1, 'E487')
should_fail('cmdheight', 0, 'E487')
should_fail('updatecount', -1, 'E487')
should_fail('textwidth', -1, 'E487')
should_fail('tabstop', 0, 'E487')
should_fail('timeoutlen', -1, 'E487')
should_fail('history', 1000000, 'E474')
should_fail('regexpengine', -1, 'E474')
should_fail('regexpengine', 3, 'E474')
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')
should_fail('foldlevel', -5, 'E487')
should_fail('foldcolumn', 13, 'E474')
should_fail('conceallevel', 4, 'E474')
should_fail('numberwidth', 11, 'E474')
should_fail('numberwidth', 0, 'E487')
-- If smaller than 1 this one is set to 'lines'-1
feed_command('setglobal window=-10')
meths.set_option('window', -10)
eq(23, meths.get_option('window'))
eq('', eval("v:errmsg"))
end)
it('set wmh/wh wmw/wiw checks', function()
feed_command('set winheight=2')
feed_command('set winminheight=3')
eq('E591', eval("v:errmsg"):match("E%d*"))
feed_command('set winwidth=2')
feed_command('set winminwidth=3')
eq('E592', eval("v:errmsg"):match("E%d*"))
end)
end)