mirror of
https://github.com/vim/vim.git
synced 2025-07-26 11:04:33 -04:00
patch 9.0.1275: the code for setting options is too complicated
Problem: The code for setting options is too complicated. Solution: Refactor the do_set() function. (Yegappan Lakshmanan, Lewis Russell, closes #11932)
This commit is contained in:
parent
be4e01637e
commit
78012f55fa
200
src/option.c
200
src/option.c
@ -10,16 +10,20 @@
|
||||
/*
|
||||
* Code to handle user-settable options. This is all pretty much table-
|
||||
* driven. Checklist for adding a new option:
|
||||
* - Put it in the options array below (copy an existing entry).
|
||||
* - Put it in the options array in optiondefs.h (copy an existing entry).
|
||||
* - For a global option: Add a variable for it in option.h.
|
||||
* - For a buffer or window local option:
|
||||
* - Add a PV_XX entry to the enum below.
|
||||
* - Add a PV_XX macro definition to the optiondefs.h file.
|
||||
* - Add a variable to the window or buffer struct in structs.h.
|
||||
* - For a window option, add some code to copy_winopt().
|
||||
* - For a window string option, add code to check_win_options() and
|
||||
* clear_winopt().
|
||||
* - For a buffer option, add some code to buf_copy_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 list of flags, add some code in do_set(), search for WW_ALL.
|
||||
* - 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 did_set_string_option(), search
|
||||
* for WW_ALL.
|
||||
* - 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.
|
||||
* - Add documentation! One line in doc/quickref.txt, full description in
|
||||
@ -1633,89 +1637,37 @@ do_set_string(
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse 'arg' for option settings.
|
||||
*
|
||||
* 'arg' may be IObuff, but only when no errors can be present and option
|
||||
* does not need to be expanded with option_expand().
|
||||
* "opt_flags":
|
||||
* 0 for ":set"
|
||||
* OPT_GLOBAL for ":setglobal"
|
||||
* OPT_LOCAL for ":setlocal" and a modeline
|
||||
* OPT_MODELINE for a modeline
|
||||
* OPT_WINONLY to only set window-local options
|
||||
* OPT_NOWIN to skip setting window-local options
|
||||
* OPT_ONECOLUMN do not use multiple columns
|
||||
*
|
||||
* returns FAIL if an error is detected, OK otherwise
|
||||
* Set an option to a new value.
|
||||
* Return NULL if OK, return an untranslated error message when something is
|
||||
* wrong. "errbuf[errbuflen]" can be used to create the error message.
|
||||
*/
|
||||
int
|
||||
do_set(
|
||||
char_u *arg_start, // option string (may be written to!)
|
||||
int opt_flags)
|
||||
static char *
|
||||
do_set_option(
|
||||
int opt_flags,
|
||||
char_u **argp,
|
||||
char_u *arg_start,
|
||||
char_u **startarg,
|
||||
int *did_show,
|
||||
int *stopopteval,
|
||||
char *errbuf,
|
||||
size_t errbuflen)
|
||||
{
|
||||
char_u *arg = arg_start;
|
||||
int opt_idx;
|
||||
char *errmsg;
|
||||
char errbuf[80];
|
||||
char_u *startarg;
|
||||
char *errmsg = NULL;
|
||||
int prefix; // 1: nothing, 0: "no", 2: "inv" in front of name
|
||||
int nextchar; // next non-white char after option name
|
||||
int afterchar; // character just after option name
|
||||
int len;
|
||||
int i;
|
||||
varnumber_T value;
|
||||
char_u *arg = *argp;
|
||||
int key;
|
||||
int opt_idx;
|
||||
int len;
|
||||
set_op_T op = 0;
|
||||
long_u flags; // flags for current option
|
||||
char_u *varp = NULL; // pointer to variable for current option
|
||||
int did_show = FALSE; // already showed one value
|
||||
set_op_T op = 0;
|
||||
int cp_val = 0;
|
||||
char_u key_name[2];
|
||||
int cp_val = 0;
|
||||
varnumber_T value;
|
||||
int i;
|
||||
|
||||
if (*arg == NUL)
|
||||
{
|
||||
showoptions(0, opt_flags);
|
||||
did_show = TRUE;
|
||||
goto theend;
|
||||
}
|
||||
|
||||
while (*arg != NUL) // loop to process all options
|
||||
{
|
||||
errmsg = NULL;
|
||||
startarg = arg; // remember for error message
|
||||
|
||||
if (STRNCMP(arg, "all", 3) == 0 && !ASCII_ISALPHA(arg[3])
|
||||
&& !(opt_flags & OPT_MODELINE))
|
||||
{
|
||||
/*
|
||||
* ":set all" show all options.
|
||||
* ":set all&" set all options to their default value.
|
||||
*/
|
||||
arg += 3;
|
||||
if (*arg == '&')
|
||||
{
|
||||
++arg;
|
||||
// Only for :set command set global value of local options.
|
||||
set_options_default(OPT_FREE | opt_flags);
|
||||
didset_options();
|
||||
didset_options2();
|
||||
redraw_all_later(UPD_CLEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
showoptions(1, opt_flags);
|
||||
did_show = TRUE;
|
||||
}
|
||||
}
|
||||
else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE))
|
||||
{
|
||||
showoptions(2, opt_flags);
|
||||
show_termcodes(opt_flags);
|
||||
did_show = TRUE;
|
||||
arg += 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = 1;
|
||||
if (STRNCMP(arg, "no", 2) == 0 && STRNCMP(arg, "novice", 6) != 0)
|
||||
{
|
||||
@ -1787,7 +1739,7 @@ do_set(
|
||||
{
|
||||
errmsg = e_no_white_space_allowed_between_option_and;
|
||||
arg = p;
|
||||
startarg = p;
|
||||
*startarg = p;
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
@ -1943,12 +1895,12 @@ do_set(
|
||||
/*
|
||||
* print value
|
||||
*/
|
||||
if (did_show)
|
||||
if (*did_show)
|
||||
msg_putchar('\n'); // cursor below last one
|
||||
else
|
||||
{
|
||||
gotocmdline(TRUE); // cursor at status line
|
||||
did_show = TRUE; // remember that we did a line
|
||||
*did_show = TRUE; // remember that we did a line
|
||||
}
|
||||
if (opt_idx >= 0)
|
||||
{
|
||||
@ -2115,7 +2067,7 @@ do_set(
|
||||
else if (op == OP_REMOVING)
|
||||
value = *(long *)varp - value;
|
||||
errmsg = set_num_option(opt_idx, varp, value,
|
||||
errbuf, sizeof(errbuf), opt_flags);
|
||||
errbuf, errbuflen, opt_flags);
|
||||
}
|
||||
else if (opt_idx >= 0) // string
|
||||
{
|
||||
@ -2125,7 +2077,8 @@ do_set(
|
||||
{
|
||||
if (errmsg != NULL)
|
||||
goto skip;
|
||||
break;
|
||||
*stopopteval = TRUE;
|
||||
goto skip;
|
||||
}
|
||||
}
|
||||
else // key code option
|
||||
@ -2160,6 +2113,87 @@ do_set(
|
||||
}
|
||||
|
||||
skip:
|
||||
*argp = arg;
|
||||
return errmsg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse 'arg' for option settings.
|
||||
*
|
||||
* 'arg' may be IObuff, but only when no errors can be present and option
|
||||
* does not need to be expanded with option_expand().
|
||||
* "opt_flags":
|
||||
* 0 for ":set"
|
||||
* OPT_GLOBAL for ":setglobal"
|
||||
* OPT_LOCAL for ":setlocal" and a modeline
|
||||
* OPT_MODELINE for a modeline
|
||||
* OPT_WINONLY to only set window-local options
|
||||
* OPT_NOWIN to skip setting window-local options
|
||||
* OPT_ONECOLUMN do not use multiple columns
|
||||
*
|
||||
* Returns FAIL if an error is detected, OK otherwise.
|
||||
*/
|
||||
int
|
||||
do_set(
|
||||
char_u *arg_start, // option string (may be written to!)
|
||||
int opt_flags)
|
||||
{
|
||||
char_u *arg = arg_start;
|
||||
int i;
|
||||
int did_show = FALSE; // already showed one value
|
||||
|
||||
if (*arg == NUL)
|
||||
{
|
||||
showoptions(0, opt_flags);
|
||||
did_show = TRUE;
|
||||
goto theend;
|
||||
}
|
||||
|
||||
while (*arg != NUL) // loop to process all options
|
||||
{
|
||||
if (STRNCMP(arg, "all", 3) == 0 && !ASCII_ISALPHA(arg[3])
|
||||
&& !(opt_flags & OPT_MODELINE))
|
||||
{
|
||||
/*
|
||||
* ":set all" show all options.
|
||||
* ":set all&" set all options to their default value.
|
||||
*/
|
||||
arg += 3;
|
||||
if (*arg == '&')
|
||||
{
|
||||
++arg;
|
||||
// Only for :set command set global value of local options.
|
||||
set_options_default(OPT_FREE | opt_flags);
|
||||
didset_options();
|
||||
didset_options2();
|
||||
redraw_all_later(UPD_CLEAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
showoptions(1, opt_flags);
|
||||
did_show = TRUE;
|
||||
}
|
||||
}
|
||||
else if (STRNCMP(arg, "termcap", 7) == 0 && !(opt_flags & OPT_MODELINE))
|
||||
{
|
||||
showoptions(2, opt_flags);
|
||||
show_termcodes(opt_flags);
|
||||
did_show = TRUE;
|
||||
arg += 7;
|
||||
}
|
||||
else
|
||||
{
|
||||
int stopopteval = FALSE;
|
||||
char *errmsg = NULL;
|
||||
char errbuf[80];
|
||||
char_u *startarg = arg;
|
||||
|
||||
errmsg = do_set_option(opt_flags, &arg, arg_start, &startarg,
|
||||
&did_show, &stopopteval, errbuf,
|
||||
sizeof(errbuf));
|
||||
if (stopopteval)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Advance to next argument.
|
||||
* - skip until a blank found, taking care of backslashes
|
||||
@ -2175,7 +2209,6 @@ skip:
|
||||
if (*arg != '=')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (errmsg != NULL)
|
||||
{
|
||||
@ -2197,6 +2230,7 @@ skip:
|
||||
|
||||
return FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
arg = skipwhite(arg);
|
||||
}
|
||||
|
@ -680,6 +680,7 @@ did_set_term(int *opt_idx, long_u *free_oldval)
|
||||
// Both 'term' and 'ttytype' point to T_NAME, only set the
|
||||
// P_ALLOCED flag on 'term'.
|
||||
*opt_idx = findoption((char_u *)"term");
|
||||
if (*opt_idx >= 0)
|
||||
*free_oldval = (get_option_flags(*opt_idx) & P_ALLOCED);
|
||||
}
|
||||
|
||||
|
@ -695,6 +695,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1275,
|
||||
/**/
|
||||
1274,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user