⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 option.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
	    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 + -