📄 eval.c
字号:
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 + -