forked from aniani/vim
patch 7.4.1999
Problem: evalcmd() doesn't work recursively. Solution: Use redir_evalcmd instead of redir_vname.
This commit is contained in:
parent
bf2cc5f36d
commit
bc5d6dd1dd
47
src/eval.c
47
src/eval.c
@ -11345,6 +11345,28 @@ f_eval(typval_T *argvars, typval_T *rettv)
|
||||
EMSG(_(e_trailing));
|
||||
}
|
||||
|
||||
static garray_T redir_evalcmd_ga;
|
||||
|
||||
/*
|
||||
* Append "value[value_len]" to the evalcmd() output.
|
||||
*/
|
||||
void
|
||||
evalcmd_redir_str(char_u *value, int value_len)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (value_len == -1)
|
||||
len = (int)STRLEN(value); /* Append the entire string */
|
||||
else
|
||||
len = value_len; /* Append only "value_len" characters */
|
||||
if (ga_grow(&redir_evalcmd_ga, len) == OK)
|
||||
{
|
||||
mch_memmove((char *)redir_evalcmd_ga.ga_data
|
||||
+ redir_evalcmd_ga.ga_len, value, len);
|
||||
redir_evalcmd_ga.ga_len += len;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* "evalcmd()" function
|
||||
*/
|
||||
@ -11352,6 +11374,9 @@ f_eval(typval_T *argvars, typval_T *rettv)
|
||||
f_evalcmd(typval_T *argvars, typval_T *rettv)
|
||||
{
|
||||
char_u *s;
|
||||
int save_msg_silent = msg_silent;
|
||||
int save_redir_evalcmd = redir_evalcmd;
|
||||
garray_T save_ga;
|
||||
|
||||
rettv->vval.v_string = NULL;
|
||||
rettv->v_type = VAR_STRING;
|
||||
@ -11359,20 +11384,20 @@ f_evalcmd(typval_T *argvars, typval_T *rettv)
|
||||
s = get_tv_string_chk(&argvars[0]);
|
||||
if (s != NULL)
|
||||
{
|
||||
redir_vname = TRUE;
|
||||
redir_lval = (lval_T *)&redir_lval;
|
||||
ga_init2(&redir_ga, (int)sizeof(char), 500);
|
||||
if (redir_evalcmd)
|
||||
save_ga = redir_evalcmd_ga;
|
||||
ga_init2(&redir_evalcmd_ga, (int)sizeof(char), 500);
|
||||
redir_evalcmd = TRUE;
|
||||
|
||||
if (do_cmdline_cmd(s) == OK)
|
||||
rettv->vval.v_string = redir_ga.ga_data;
|
||||
else
|
||||
vim_free(redir_ga.ga_data);
|
||||
++msg_silent;
|
||||
do_cmdline_cmd(s);
|
||||
rettv->vval.v_string = redir_evalcmd_ga.ga_data;
|
||||
msg_silent = save_msg_silent;
|
||||
|
||||
redir_ga.ga_data = NULL;
|
||||
redir_vname = FALSE;
|
||||
redir_lval = NULL;
|
||||
redir_evalcmd = save_redir_evalcmd;
|
||||
if (redir_evalcmd)
|
||||
redir_evalcmd_ga = save_ga;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1106,6 +1106,7 @@ EXTERN FILE *redir_fd INIT(= NULL); /* message redirection file */
|
||||
#ifdef FEAT_EVAL
|
||||
EXTERN int redir_reg INIT(= 0); /* message redirection register */
|
||||
EXTERN int redir_vname INIT(= 0); /* message redirection variable */
|
||||
EXTERN int redir_evalcmd INIT(= 0); /* evalcmd() redirection */
|
||||
#endif
|
||||
|
||||
#ifdef FEAT_LANGMAP
|
||||
|
@ -3063,7 +3063,9 @@ redir_write(char_u *str, int maxlen)
|
||||
while (cur_col < msg_col)
|
||||
{
|
||||
#ifdef FEAT_EVAL
|
||||
if (redir_reg)
|
||||
if (redir_evalcmd)
|
||||
evalcmd_redir_str((char_u *)" ", -1);
|
||||
else if (redir_reg)
|
||||
write_reg_contents(redir_reg, (char_u *)" ", -1, TRUE);
|
||||
else if (redir_vname)
|
||||
var_redir_str((char_u *)" ", -1);
|
||||
@ -3078,9 +3080,11 @@ redir_write(char_u *str, int maxlen)
|
||||
}
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
if (redir_reg)
|
||||
if (redir_evalcmd)
|
||||
evalcmd_redir_str(s, maxlen);
|
||||
else if (redir_reg)
|
||||
write_reg_contents(redir_reg, s, maxlen, TRUE);
|
||||
if (redir_vname)
|
||||
else if (redir_vname)
|
||||
var_redir_str(s, maxlen);
|
||||
#endif
|
||||
|
||||
@ -3088,7 +3092,7 @@ redir_write(char_u *str, int maxlen)
|
||||
while (*s != NUL && (maxlen < 0 || (int)(s - str) < maxlen))
|
||||
{
|
||||
#ifdef FEAT_EVAL
|
||||
if (!redir_reg && !redir_vname)
|
||||
if (!redir_reg && !redir_vname && !redir_evalcmd)
|
||||
#endif
|
||||
if (redir_fd != NULL)
|
||||
putc(*s, redir_fd);
|
||||
@ -3113,7 +3117,7 @@ redirecting(void)
|
||||
{
|
||||
return redir_fd != NULL || *p_vfile != NUL
|
||||
#ifdef FEAT_EVAL
|
||||
|| redir_reg || redir_vname
|
||||
|| redir_reg || redir_vname || redir_evalcmd
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
@ -81,12 +81,14 @@ int dict_add_list(dict_T *d, char *key, list_T *list);
|
||||
dictitem_T *dict_find(dict_T *d, char_u *key, int len);
|
||||
char_u *get_dict_string(dict_T *d, char_u *key, int save);
|
||||
varnumber_T get_dict_number(dict_T *d, char_u *key);
|
||||
char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
|
||||
int string2float(char_u *text, float_T *value);
|
||||
char_u *get_function_name(expand_T *xp, int idx);
|
||||
char_u *get_expr_name(expand_T *xp, int idx);
|
||||
int call_func(char_u *funcname, int len, typval_T *rettv, int argcount_in, typval_T *argvars_in, linenr_T firstline, linenr_T lastline, int *doesrange, int evaluate, partial_T *partial, dict_T *selfdict_in);
|
||||
buf_T *buflist_find_by_name(char_u *name, int curtab_only);
|
||||
int func_call(char_u *name, typval_T *args, partial_T *partial, dict_T *selfdict, typval_T *rettv);
|
||||
void evalcmd_redir_str(char_u *value, int value_len);
|
||||
void dict_extend(dict_T *d1, dict_T *d2, char_u *action);
|
||||
void mzscheme_call_vim(char_u *name, typval_T *args, typval_T *rettv);
|
||||
float_T vim_round(float_T f);
|
||||
@ -150,5 +152,4 @@ void ex_oldfiles(exarg_T *eap);
|
||||
void reset_v_option_vars(void);
|
||||
int modify_fname(char_u *src, int *usedlen, char_u **fnamep, char_u **bufp, int *fnamelen);
|
||||
char_u *do_string_sub(char_u *str, char_u *pat, char_u *sub, char_u *flags);
|
||||
char_u *tv2string(typval_T *tv, char_u **tofree, char_u *numbuf, int copyID);
|
||||
/* vim: set ft=c : */
|
||||
|
@ -1,8 +1,33 @@
|
||||
" test evalcmd()
|
||||
|
||||
func NestedEval()
|
||||
let nested = evalcmd('echo "nested\nlines"')
|
||||
echo 'got: "' . nested . '"'
|
||||
endfunc
|
||||
|
||||
func NestedRedir()
|
||||
redir => var
|
||||
echo 'broken'
|
||||
redir END
|
||||
endfunc
|
||||
|
||||
func Test_evalcmd()
|
||||
call assert_equal("\nnocompatible", evalcmd('set compatible?'))
|
||||
call assert_equal("\nsomething\nnice", evalcmd('echo "something\nnice"'))
|
||||
call assert_equal("noendofline", evalcmd('echon "noendofline"'))
|
||||
call assert_equal("", evalcmd(123))
|
||||
|
||||
call assert_equal("\ngot: \"\nnested\nlines\"", evalcmd('call NestedEval()'))
|
||||
redir => redired
|
||||
echo 'this'
|
||||
let evaled = evalcmd('echo "that"')
|
||||
echo 'theend'
|
||||
redir END
|
||||
call assert_equal("\nthis\ntheend", redired)
|
||||
call assert_equal("\nthat", evaled)
|
||||
|
||||
call assert_fails('call evalcmd("doesnotexist")', 'E492:')
|
||||
call assert_fails('call evalcmd(3.4)', 'E806:')
|
||||
call assert_fails('call evalcmd("call NestedRedir()")', 'E930:')
|
||||
endfunc
|
||||
|
||||
|
@ -758,6 +758,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
1999,
|
||||
/**/
|
||||
1998,
|
||||
/**/
|
||||
|
Loading…
x
Reference in New Issue
Block a user