📄 option.c
字号:
else
{
len = 0;
/*
* The two characters after "t_" may not be alphanumeric.
*/
if (arg[0] == 't' && arg[1] == '_' && arg[2] && arg[3])
{
len = 4;
}
else
{
while (isalnum(arg[len]) || arg[len] == '_')
++len;
}
nextchar = arg[len];
arg[len] = NUL; /* put NUL after name */
opt_idx = findoption(arg);
arg[len] = nextchar; /* restore nextchar */
if (opt_idx == -1)
key = find_key_option(arg);
}
if (opt_idx == -1 && key == 0) /* found a mismatch: skip */
{
errmsg = (char_u *)"Unknown option";
goto skip;
}
if (opt_idx >= 0)
{
if (options[opt_idx].var == NULL) /* hidden option: skip */
goto skip;
flags = options[opt_idx].flags;
varp = get_varp(&(options[opt_idx]));
}
else
flags = P_STRING;
/* remember character after option name */
afterchar = arg[len];
/* skip white space, allow ":set ai ?" */
while (vim_iswhite(arg[len]))
++len;
adding = FALSE;
prepending = FALSE;
removing = FALSE;
if (arg[len] == '+' && arg[len + 1] == '=')
{
adding = TRUE; /* "+=" */
++len;
}
else if (arg[len] == '^' && arg[len + 1] == '=')
{
prepending = TRUE; /* "^=" */
++len;
}
else if (arg[len] == '-' && arg[len + 1] == '=')
{
removing = TRUE; /* "-=" */
++len;
}
nextchar = arg[len];
if (vim_strchr((char_u *)"?=:!&", nextchar) != NULL)
{
arg += len;
len = 0;
if (vim_strchr((char_u *)"?!&", nextchar) != NULL
&& arg[1] != NUL && !vim_iswhite(arg[1]))
{
errmsg = e_trailing;
goto skip;
}
}
/*
* allow '=' and ':' as MSDOS command.com allows only one
* '=' character per "set" command line. grrr. (jw)
*/
if (nextchar == '?'
|| (prefix == 1
&& vim_strchr((char_u *)"=:&", nextchar) == NULL
&& !(flags & P_BOOL)))
{
/*
* print value
*/
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 */
}
if (opt_idx >= 0)
showoneopt(&options[opt_idx]);
else
{
char_u name[2];
char_u *p;
name[0] = KEY2TERMCAP0(key);
name[1] = KEY2TERMCAP1(key);
p = find_termcode(name);
if (p == NULL)
{
errmsg = (char_u *)"Unknown option";
goto skip;
}
else
(void)show_one_termcode(name, p, TRUE);
}
if (nextchar != '?'
&& nextchar != NUL && !vim_iswhite(afterchar))
errmsg = e_trailing;
}
else
{
if (flags & P_BOOL) /* boolean */
{
if (nextchar == '=' || nextchar == ':')
{
errmsg = e_invarg;
goto skip;
}
/*
* ":set opt!": invert
* ":set opt&": reset to default value
*/
if (nextchar == '!')
value = *(int *)(varp) ^ 1;
else if (nextchar == '&')
{
/* Use a trick here to get the default value,
* without setting the actual value yet. */
i = *(int *)varp;
set_option_default(opt_idx, FALSE);
value = *(int *)varp;
*(int *)varp = i;
}
else
{
/*
* ":set invopt": invert
* ":set opt" or ":set noopt": set or reset
*/
if (nextchar != NUL && !vim_iswhite(afterchar))
{
errmsg = e_trailing;
goto skip;
}
if (prefix == 2) /* inv */
value = *(int *)(varp) ^ 1;
else
value = prefix;
}
errmsg = set_bool_option(opt_idx, varp, (int)value);
}
else /* numeric or string */
{
if (vim_strchr((char_u *)"=:&", nextchar) == NULL
|| prefix != 1)
{
errmsg = e_invarg;
goto skip;
}
if (flags & P_NUM) /* numeric */
{
/*
* Different ways to set a number option:
* & set to default value
* <xx> accept special key codes for 'wildchar'
* c accept any non-digit for 'wildchar'
* [-]0-9 set number
* other error
*/
arg += len + 1;
if (nextchar == '&')
{
long temp;
/* Use a trick here to get the default value,
* without setting the actual value yet. */
temp = *(long *)varp;
set_option_default(opt_idx, FALSE);
value = *(long *)varp;
*(long *)varp = temp;
}
else if ( (long *)varp == &p_wc
&& (*arg == '<'
|| *arg == '^'
|| ((!arg[1] || vim_iswhite(arg[1]))
&& !isdigit(*arg))))
{
if (*arg == '<')
value = find_key_option(arg + 1);
else if (*arg == '^')
value = arg[1] ^ 0x40;
else
value = *arg;
if (value == 0)
{
errmsg = e_invarg;
goto skip;
}
}
/* allow negative numbers (for 'undolevels') */
else if (*arg == '-' || isdigit(*arg))
{
i = 0;
if (*arg == '-')
i = 1;
#ifdef HAVE_STRTOL
value = strtol((char *)arg, NULL, 0);
if (arg[i] == '0' && TO_LOWER(arg[i + 1]) == 'x')
i += 2;
#else
value = atol((char *)arg);
#endif
while (isdigit(arg[i]))
++i;
if (arg[i] != NUL && !vim_iswhite(arg[i]))
{
errmsg = e_invarg;
goto skip;
}
}
else
{
errmsg = (char_u *)"Number required after =";
goto skip;
}
if (adding)
value = *(long *)varp + value;
if (prepending)
value = *(long *)varp * value;
if (removing)
value = *(long *)varp - value;
errmsg = set_num_option(opt_idx, varp, value, errbuf);
}
else if (opt_idx >= 0) /* string */
{
char_u *save_arg = NULL;
char_u *s;
char_u *oldval; /* previous value if *varp */
char_u *newval;
unsigned newlen;
int comma;
int new_value_alloced; /* new string option
was allocated */
/* The old value is kept until we are sure that the new
* value is valid. set_option_default() is therefore
* called with FALSE
*/
oldval = *(char_u **)(varp);
if (nextchar == '&') /* set to default val */
{
/* The old value will be freed in
* did_set_string_option(). Don't change the
* flags now, but do remember if the new value is
* allocated. */
set_option_default(opt_idx, FALSE);
new_value_alloced =
(options[opt_idx].flags & P_ALLOCED);
options[opt_idx].flags = flags;
}
else
{
arg += len + 1; /* jump to after the '=' or ':' */
/*
* Convert 'whichwrap' number to string, for
* backwards compatibility with Vim 3.0.
* Misuse errbuf[] for the resulting string.
*/
if (varp == (char_u *)&p_ww && isdigit(*arg))
{
*errbuf = NUL;
i = getdigits(&arg);
if (i & 1)
STRCAT(errbuf, "b,");
if (i & 2)
STRCAT(errbuf, "s,");
if (i & 4)
STRCAT(errbuf, "h,l,");
if (i & 8)
STRCAT(errbuf, "<,>,");
if (i & 16)
STRCAT(errbuf, "[,],");
if (*errbuf != NUL) /* remove trailing , */
errbuf[STRLEN(errbuf) - 1] = NUL;
save_arg = arg;
arg = errbuf;
}
/*
* Remove '>' before 'dir' and 'bdir', for
* backwards compatibility with version 3.0
*/
else if ( *arg == '>'
&& (varp == (char_u *)&p_dir
|| varp == (char_u *)&p_bdir))
{
++arg;
}
/*
* Copy the new string into allocated memory.
* Can't use set_string_option_direct(), because
* we need to remove the backslashes.
*/
/* get a bit too much */
newlen = STRLEN(arg) + 1;
if (adding || prepending || removing)
newlen += STRLEN(oldval) + 1;
newval = alloc(newlen);
if (newval == NULL) /* out of mem, don't change */
break;
s = newval;
/*
* Copy the string, skip over escaped chars.
* For MS-DOS and WIN32 backslashes before normal
* file name characters are not removed.
*/
while (*arg && !vim_iswhite(*arg))
{
if (*arg == '\\' && arg[1] != NUL
#ifdef BACKSLASH_IN_FILENAME
&& !((flags & P_EXPAND)
&& vim_isfilec(arg[1])
&& arg[1] != '\\')
#endif
)
++arg;
*s++ = *arg++;
}
*s = NUL;
/* concatenate the two strings; add a ',' if
* needed */
if (adding || prepending)
{
comma = ((flags & P_COMMA) && *oldval);
if (adding)
{
i = STRLEN(oldval);
mch_memmove(newval + i + comma, newval,
STRLEN(newval) + 1);
mch_memmove(newval, oldval, (size_t)i);
}
else
{
i = STRLEN(newval);
mch_memmove(newval + i + comma, oldval,
STRLEN(oldval) + 1);
}
if (comma)
newval[i] = ',';
}
/* locate newval[] in oldval[] and remove it */
if (removing)
{
i = STRLEN(newval);
for (s = oldval; *s; ++s)
{
if ((!(flags & P_COMMA)
|| s == oldval
|| s[-1] == ',')
&& STRNCMP(s, newval, i) == 0
&& (!(flags & P_COMMA)
|| s[i] == ','
|| s[i] == NUL))
break;
}
STRCPY(newval, oldval);
if (*s)
{
/* may need to remove a comma */
if (flags & P_COMMA)
{
if (s == oldval)
{
/* include comma after string */
if (s[i] == ',')
++i;
}
else
{
/* include comma before string */
--s;
++i;
}
}
mch_memmove(newval + (s - oldval), s + i,
STRLEN(s + i) + 1);
}
}
*(char_u **)(varp) = newval;
if (save_arg != NULL) /* number for 'whichwrap' */
arg = save_arg;
new_value_alloced = TRUE;
}
/* expand environment variables and ~ */
s = option_expand(opt_idx);
if (s != NULL)
{
if (new_value_alloced)
vim_free(*(char_u **)(varp));
*(char_u **)(varp) = s;
new_value_alloced = TRUE;
}
errmsg = did_set_string_option(opt_idx, (char_u **)varp,
new_value_alloced, oldval, errbuf);
/*
* If error detected, print the error message.
*/
if (errmsg != NULL)
goto skip;
}
else /* key code option */
{
char_u name[2];
char_u *p;
name[0] = KEY2TERMCAP0(key);
name[1] = KEY2TERMCAP1(key);
if (nextchar == '&')
{
if (add_termcap_entry(name, TRUE) == FAIL)
errmsg = (char_u *)"Not found in termcap";
}
else
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -