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

📄 eval.c

📁 VIM文本编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
f_last_buffer_nr(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    int		n = 0;
    BUF		*buf;

    for (buf = firstbuf; buf != NULL; buf = buf->b_next)
	if (n < buf->b_fnum)
	    n = buf->b_fnum;

    retvar->var_val.var_number = n;
}

/*
 * "line(string)" function
 */
    static void
f_line(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    linenr_t	lnum = 0;
    FPOS	*fp;

    fp = var2fpos(&argvars[0]);
    if (fp != NULL)
	lnum = fp->lnum;
    else if (get_var_string(&argvars[0])[0] == '$')   /* last line in buffer */
	lnum = curbuf->b_ml.ml_line_count;

    retvar->var_val.var_number = lnum;
}

/*
 * "match()" function
 */
    static void
f_match(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    f_some_match(argvars, retvar, 1);
}

/*
 * "matchend()" function
 */
    static void
f_matchend(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    f_some_match(argvars, retvar, 0);
}

/*
 * "matchstr()" function
 */
    static void
f_matchstr(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    f_some_match(argvars, retvar, 2);
}

    static void
f_some_match(argvars, retvar, type)
    VAR		argvars;
    VAR		retvar;
    int		type;
{
    char_u		*str;
    char_u		*pat;
    vim_regexp		*prog;
    char_u		patbuf[NUMBUFLEN];

    str = get_var_string(&argvars[0]);
    pat = get_var_string_buf(&argvars[1], patbuf);

    if (type == 2)
    {
	retvar->var_type = VAR_STRING;
	retvar->var_val.var_string = NULL;
    }
    else
	retvar->var_val.var_number = -1;
    prog = vim_regcomp(pat, TRUE);
    if (prog != NULL)
    {
	reg_ic = p_ic;
	if (vim_regexec(prog, str, TRUE))
	{
	    if (type == 2)
		retvar->var_val.var_string = vim_strnsave(prog->startp[0],
				      (int)(prog->endp[0] - prog->startp[0]));
	    else if (type)
		retvar->var_val.var_number = prog->startp[0] - str;
	    else
		retvar->var_val.var_number = prog->endp[0] - str;
	}
	vim_free(prog);
    }
}

/*
 * "nr2char()" function
 */
    static void
f_nr2char(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    char_u	buf[2];

    buf[0] = (char_u)get_var_number(&argvars[0]);
    retvar->var_type = VAR_STRING;
    retvar->var_val.var_string = vim_strnsave(buf, 1);
}

/*
 * "setline()" function
 */
    static void
f_setline(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    linenr_t	lnum;
    char_u	*line;

    lnum = get_var_number(&argvars[0]);
    line = get_var_string(&argvars[1]);
    retvar->var_val.var_number = 1;		/* FAIL is default */

    if (lnum >= 1 && lnum <= curbuf->b_ml.ml_line_count)
    {
	if (u_savesub(lnum) == OK && ml_replace(lnum, line, TRUE) == OK)
	{
	    changed();
#ifdef SYNTAX_HL
	    /* recompute syntax hl. for this line */
	    syn_changed(lnum);
#endif
	    redraw_curbuf_later(NOT_VALID);
	    retvar->var_val.var_number = 0;
	}
    }
}

#ifdef HAVE_STRFTIME
/*
 * "strftime()" function
 */
    static void
f_strftime(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    char_u	result_buf[80];
    struct tm	*curtime;
    time_t	seconds;
    char_u	*p;

    p = get_var_string(&argvars[0]);
    seconds = time(NULL);
    curtime = localtime(&seconds);
    (void)strftime((char *)result_buf, (size_t)80, (char *)p, curtime);

    retvar->var_type = VAR_STRING;
    retvar->var_val.var_string = vim_strsave(result_buf);
}
#endif

/*
 * "strlen()" function
 */
    static void
f_strlen(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    retvar->var_val.var_number = STRLEN(get_var_string(&argvars[0]));
}

/*
 * "strpart()" function
 */
    static void
f_strpart(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    char_u	*p;
    int		n;
    int		len;
    int		slen;

    p = get_var_string(&argvars[0]);
    n = get_var_number(&argvars[1]);
    len = get_var_number(&argvars[2]);
    slen = STRLEN(p);
    /*
     * Only return the overlap between the specified part and the actual
     * string.
     */
    if (n < 0)
    {
	len += n;
	n = 0;
    }
    else if (n > slen)
	n = slen;
    if (len < 0)
	len = 0;
    else if (n + len > slen)
	len = slen - n;

    retvar->var_type = VAR_STRING;
    retvar->var_val.var_string = vim_strnsave(p + n, len);
}

/*
 * "synID(line, col, trans)" function
 */
    static void
f_synID(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    int		id = 0;
#ifdef SYNTAX_HL
    long	line;
    long	col;
    int		trans;

    line = get_var_number(&argvars[0]);
    col = get_var_number(&argvars[1]) - 1;
    trans = get_var_number(&argvars[2]);

    if (line >= 1 && line <= curbuf->b_ml.ml_line_count
	    && col >= 0 && col < (long)STRLEN(ml_get(line)))
	id = syn_get_id(line, col, trans);
#endif

    retvar->var_val.var_number = id;
}

/*
 * "synIDattr(id, what [, mode])" function
 */
    static void
f_synIDattr(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    char_u	*p = NULL;
#ifdef SYNTAX_HL
    int		id;
    char_u	*what;
    char_u	*mode;
    char_u	modebuf[NUMBUFLEN];
    int		modec;

    id = get_var_number(&argvars[0]);
    what = get_var_string(&argvars[1]);
    if (argvars[2].var_type != VAR_UNKNOWN)
    {
	mode = get_var_string_buf(&argvars[2], modebuf);
	modec = TO_LOWER(mode[0]);
	if (modec != 't' && modec != 'c'
#ifdef USE_GUI
		&& modec != 'g'
#endif
		)
	    modec = 0;	/* replace invalid with current */
    }
    else
    {
#ifdef USE_GUI
	if (gui.in_use)
	    modec = 'g';
	else
#endif
	    if (*T_CCO)
	    modec = 'c';
	else
	    modec = 't';
    }


    switch (TO_LOWER(what[0]))
    {
	case 'b':
		if (TO_LOWER(what[1]) == 'g')		/* bg[#] */
		    p = highlight_color(id, what, modec);
		else					/* bold */
		    p = highlight_has_attr(id, HL_BOLD, modec);
		break;

	case 'f':					/* fg[#] */
		p = highlight_color(id, what, modec);
		break;

	case 'i':
		if (TO_LOWER(what[1]) == 'n')		/* inverse */
		    p = highlight_has_attr(id, HL_INVERSE, modec);
		else					/* italic */
		    p = highlight_has_attr(id, HL_ITALIC, modec);
		break;

	case 'n':					/* name */
		p = get_highlight_name(id - 1);
		break;

	case 'r':					/* reverse */
		p = highlight_has_attr(id, HL_INVERSE, modec);
		break;

	case 's':					/* standout */
		p = highlight_has_attr(id, HL_STANDOUT, modec);
		break;

	case 'u':					/* underline */
		p = highlight_has_attr(id, HL_UNDERLINE, modec);
		break;
    }

    if (p != NULL)
	p = vim_strsave(p);
#endif
    retvar->var_type = VAR_STRING;
    retvar->var_val.var_string = p;
}

/*
 * "synIDtrans(id)" function
 */
    static void
f_synIDtrans(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    int		id;

#ifdef SYNTAX_HL
    id = get_var_number(&argvars[0]);

    if (id > 0)
	id = syn_get_final_id(id);
    else
#endif
	id = 0;

    retvar->var_val.var_number = id;
}

/*
 * "substitute()" function
 */
    static void
f_substitute(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    char_u	patbuf[NUMBUFLEN];
    char_u	subbuf[NUMBUFLEN];
    char_u	flagsbuf[NUMBUFLEN];

    retvar->var_type = VAR_STRING;
    retvar->var_val.var_string = do_string_sub(
	    get_var_string(&argvars[0]),
	    get_var_string_buf(&argvars[1], patbuf),
	    get_var_string_buf(&argvars[2], subbuf),
	    get_var_string_buf(&argvars[3], flagsbuf));
}

/*
 * "tempname()" function
 */
/*ARGSUSED*/
    static void
f_tempname(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    static int	x = 'A';

    retvar->var_type = VAR_STRING;
    retvar->var_val.var_string = vim_tempname(x);
    /* advance 'x', so that there are at least 26 different names */
    if (x == 'Z')
	x = 'A';
    else
	++x;
}

/*
 * "virtcol(string)" function
 */
    static void
f_virtcol(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    colnr_t	vcol = 0;
    FPOS	*fp;

    fp = var2fpos(&argvars[0]);
    if (fp != NULL)
    {
	getvcol(curwin, fp, NULL, NULL, &vcol);
	++vcol;
    }

    retvar->var_val.var_number = vcol;
}

/*
 * "winbufnr(nr)" function
 */
    static void
f_winbufnr(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    WIN		*wp;

    wp = find_win_by_nr(&argvars[0]);
    if (wp == NULL)
	retvar->var_val.var_number = -1;
    else
	retvar->var_val.var_number = wp->w_buffer->b_fnum;
}

/*
 * "winheight(nr)" function
 */
    static void
f_winheight(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    WIN		*wp;

    wp = find_win_by_nr(&argvars[0]);
    if (wp == NULL)
	retvar->var_val.var_number = -1;
    else
	retvar->var_val.var_number = wp->w_height;
}

/*
 * "winnr()" function
 */
/* ARGSUSED */
    static void
f_winnr(argvars, retvar)
    VAR		argvars;
    VAR		retvar;
{
    int		nr;
    WIN		*wp;

    nr = 1;
    for (wp = firstwin; wp != curwin; wp = wp->w_next)
	++nr;
    retvar->var_val.var_number = nr;
}

    static WIN *
find_win_by_nr(vp)
    VAR		vp;
{
    WIN		*wp;
    int		nr;

    nr = get_var_number(vp);

    if (nr == 0)
	return curwin;

    for (wp = firstwin; wp != NULL; wp = wp->w_next)
    {
	if (--nr <= 0)
	    break;
    }
    return wp;
}

/*
 * Translate a String variable into a position (for col() and virtcol()).
 */
    static FPOS *
var2fpos(varp)
    VAR		varp;
{
    char_u	*name;

    name = get_var_string(varp);
    if (name[0] == '.')		/* cursor */
	return &curwin->w_cursor;
    if (name[0] == '\'')	/* mark */
	return getmark(name[1], FALSE);
    return NULL;
}

/*
 * Get the lenght of an environment variable name.
 * Advance "arg" to the first character after the name.
 * Return 0 for error.
 */
    static int
get_env_len(arg)
    char_u	**arg;
{
    char_u	*p;
    int		len;

    for (p = *arg; vim_isIDc(*p); ++p)
	;
    if (p == *arg)	    /* no name found */
	return 0;

    len = p - *arg;
    *arg = p;
    return len;
}

/*
 * Get the value of an environment variable.
 * "arg" points to the '$' before the env var name.
 * "arg" is advanced to the first character after the name.
 * Return NULL for failure.
 */
    char_u *
get_env_string(arg)
    char_u	**arg;
{
    int	    len;
    int	    cc;
    char_u  *name;
    char_u  *s;

    ++*arg;
    name = *arg;
    len = get_env_len(arg);
    if (len == 0)
	return NULL;
    cc = name[len];
    name[len] = NUL;
    s = mch_getenv(name);
    name[len] = cc;

    return s;
}

/*
 * Get the length of the name of a function or internal variable.
 * "arg" is advanced to the first non-white character after the name.
 * Return 0 if something is wrong.
 */
    static int
get_id_len(arg)
    char_u	**arg;
{
    char_u	*p;
    int		len;

    /* Find the end of the name. */
    for (p = *arg; eval_isnamec(*p); ++p)
	;
    if (p == *arg)	    /* no name found */
	return 0;

    len = p - *arg;
    *arg = skipwhite(p);

    return len;
}

    static int
eval_isnamec(c)
    int	    c;
{
    return (isalpha(c) || isdigit(c) || c == '_' || c == ':');
}

/*
 * Get the value of internal variable "name".
 * Return OK or FAIL.
 */
    static int
get_var_var(name, len, retvar)
    char_u	*name;
    int		len;		/* length of "name" */
    VAR		retvar;		/* NULL when only checking existence */
{
    int		ret = OK;
    int		type = VAR_UNKNOWN;
    long	number = 1;
    char_u	*string = NULL;
    VAR		v;
    int		cc;

    cc = n

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -