summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-07-09 17:07:29 +0200
committerBram Moolenaar <Bram@vim.org>2016-07-09 17:07:29 +0200
commit79815f1ec77406f2f21a618c053e5793b597db7a (patch)
tree7a99af24de8d373cc9a12408b39a57118a6577b9 /src
parentfc4ad616073a169badfb2b9906fee2844f76f730 (diff)
downloadvim-git-79815f1ec77406f2f21a618c053e5793b597db7a.tar.gz
patch 7.4.2008v7.4.2008
Problem: evalcmd() has a confusing name. Solution: Rename to execute(). Make silent optional. Support a list of commands.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile2
-rw-r--r--src/eval.c161
-rw-r--r--src/ex_docmd.c4
-rw-r--r--src/globals.h3
-rw-r--r--src/message.c43
-rw-r--r--src/proto/eval.pro2
-rw-r--r--src/testdir/test_alot.vim2
-rw-r--r--src/testdir/test_evalcmd.vim33
-rw-r--r--src/testdir/test_execute_func.vim51
9 files changed, 195 insertions, 106 deletions
diff --git a/src/Makefile b/src/Makefile
index 13bf77691..007c7925d 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2023,8 +2023,8 @@ test_arglist \
test_cmdline \
test_cursor_func \
test_delete \
- test_evalcmd \
test_ex_undo \
+ test_execute_func \
test_expand \
test_expand_dllpath \
test_expr \
diff --git a/src/eval.c b/src/eval.c
index 4764f49ab..ab808b9e2 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -555,9 +555,9 @@ static void f_diff_hlID(typval_T *argvars, typval_T *rettv);
static void f_empty(typval_T *argvars, typval_T *rettv);
static void f_escape(typval_T *argvars, typval_T *rettv);
static void f_eval(typval_T *argvars, typval_T *rettv);
-static void f_evalcmd(typval_T *argvars, typval_T *rettv);
static void f_eventhandler(typval_T *argvars, typval_T *rettv);
static void f_executable(typval_T *argvars, typval_T *rettv);
+static void f_execute(typval_T *argvars, typval_T *rettv);
static void f_exepath(typval_T *argvars, typval_T *rettv);
static void f_exists(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_FLOAT
@@ -8564,9 +8564,9 @@ static struct fst
{"empty", 1, 1, f_empty},
{"escape", 2, 2, f_escape},
{"eval", 1, 1, f_eval},
- {"evalcmd", 1, 1, f_evalcmd},
{"eventhandler", 0, 0, f_eventhandler},
{"executable", 1, 1, f_executable},
+ {"execute", 1, 2, f_execute},
{"exepath", 1, 1, f_exepath},
{"exists", 1, 1, f_exists},
#ifdef FEAT_FLOAT
@@ -11345,13 +11345,35 @@ f_eval(typval_T *argvars, typval_T *rettv)
EMSG(_(e_trailing));
}
-static garray_T redir_evalcmd_ga;
+/*
+ * "eventhandler()" function
+ */
+ static void
+f_eventhandler(typval_T *argvars UNUSED, typval_T *rettv)
+{
+ rettv->vval.v_number = vgetc_busy;
+}
+
+/*
+ * "executable()" function
+ */
+ static void
+f_executable(typval_T *argvars, typval_T *rettv)
+{
+ char_u *name = get_tv_string(&argvars[0]);
+
+ /* Check in $PATH and also check directly if there is a directory name. */
+ rettv->vval.v_number = mch_can_exe(name, NULL, TRUE)
+ || (gettail(name) != name && mch_can_exe(name, NULL, FALSE));
+}
+
+static garray_T redir_execute_ga;
/*
- * Append "value[value_len]" to the evalcmd() output.
+ * Append "value[value_len]" to the execute() output.
*/
void
-evalcmd_redir_str(char_u *value, int value_len)
+execute_redir_str(char_u *value, int value_len)
{
int len;
@@ -11359,71 +11381,116 @@ evalcmd_redir_str(char_u *value, int value_len)
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)
+ if (ga_grow(&redir_execute_ga, len) == OK)
{
- mch_memmove((char *)redir_evalcmd_ga.ga_data
- + redir_evalcmd_ga.ga_len, value, len);
- redir_evalcmd_ga.ga_len += len;
+ mch_memmove((char *)redir_execute_ga.ga_data
+ + redir_execute_ga.ga_len, value, len);
+ redir_execute_ga.ga_len += len;
}
}
/*
- * "evalcmd()" function
+ * Get next line from a list.
+ * Called by do_cmdline() to get the next line.
+ * Returns allocated string, or NULL for end of function.
*/
- static void
-f_evalcmd(typval_T *argvars, typval_T *rettv)
+
+ static char_u *
+get_list_line(
+ int c UNUSED,
+ void *cookie,
+ int indent UNUSED)
{
+ listitem_T **p = (listitem_T **)cookie;
+ listitem_T *item = *p;
+ char_u buf[NUMBUFLEN];
char_u *s;
+
+ if (item == NULL)
+ return NULL;
+ s = get_tv_string_buf_chk(&item->li_tv, buf);
+ *p = item->li_next;
+ return s == NULL ? NULL : vim_strsave(s);
+}
+
+/*
+ * "execute()" function
+ */
+ static void
+f_execute(typval_T *argvars, typval_T *rettv)
+{
+ char_u *cmd = NULL;
+ list_T *list = NULL;
int save_msg_silent = msg_silent;
- int save_redir_evalcmd = redir_evalcmd;
+ int save_emsg_silent = emsg_silent;
+ int save_emsg_noredir = emsg_noredir;
+ int save_redir_execute = redir_execute;
garray_T save_ga;
rettv->vval.v_string = NULL;
rettv->v_type = VAR_STRING;
- s = get_tv_string_chk(&argvars[0]);
- if (s != NULL)
+ if (argvars[0].v_type == VAR_LIST)
{
- if (redir_evalcmd)
- save_ga = redir_evalcmd_ga;
- ga_init2(&redir_evalcmd_ga, (int)sizeof(char), 500);
- redir_evalcmd = TRUE;
+ list = argvars[0].vval.v_list;
+ if (list == NULL || list->lv_first == NULL)
+ /* empty list, no commands, empty output */
+ return;
+ ++list->lv_refcount;
+ }
+ else
+ {
+ cmd = get_tv_string_chk(&argvars[0]);
+ if (cmd == NULL)
+ return;
+ }
+ if (redir_execute)
+ save_ga = redir_execute_ga;
+ ga_init2(&redir_execute_ga, (int)sizeof(char), 500);
+ redir_execute = TRUE;
+
+ if (argvars[1].v_type != VAR_UNKNOWN)
+ {
+ char_u buf[NUMBUFLEN];
+ char_u *s = get_tv_string_buf_chk(&argvars[1], buf);
+
+ if (s == NULL)
+ return;
+ if (STRNCMP(s, "silent", 6) == 0)
+ ++msg_silent;
+ if (STRCMP(s, "silent!") == 0)
+ {
+ emsg_silent = TRUE;
+ emsg_noredir = TRUE;
+ }
+ }
+ else
++msg_silent;
- do_cmdline_cmd(s);
- rettv->vval.v_string = redir_evalcmd_ga.ga_data;
- msg_silent = save_msg_silent;
- redir_evalcmd = save_redir_evalcmd;
- if (redir_evalcmd)
- redir_evalcmd_ga = save_ga;
+ if (cmd != NULL)
+ do_cmdline_cmd(cmd);
+ else
+ {
+ listitem_T *item = list->lv_first;
- /* "silent reg" or "silent echo x" leaves msg_col somewhere in the
- * line. Put it back in the first column. */
- msg_col = 0;
+ do_cmdline(NULL, get_list_line, (void *)&item,
+ DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED);
+ --list->lv_refcount;
}
-}
-/*
- * "eventhandler()" function
- */
- static void
-f_eventhandler(typval_T *argvars UNUSED, typval_T *rettv)
-{
- rettv->vval.v_number = vgetc_busy;
-}
+ rettv->vval.v_string = redir_execute_ga.ga_data;
+ msg_silent = save_msg_silent;
+ emsg_silent = save_emsg_silent;
+ emsg_noredir = save_emsg_noredir;
-/*
- * "executable()" function
- */
- static void
-f_executable(typval_T *argvars, typval_T *rettv)
-{
- char_u *name = get_tv_string(&argvars[0]);
+ redir_execute = save_redir_execute;
+ if (redir_execute)
+ redir_execute_ga = save_ga;
- /* Check in $PATH and also check directly if there is a directory name. */
- rettv->vval.v_number = mch_can_exe(name, NULL, TRUE)
- || (gettail(name) != name && mch_can_exe(name, NULL, FALSE));
+ /* "silent reg" or "silent echo x" leaves msg_col somewhere in the
+ * line. Put it back in the first column. */
+ msg_col = 0;
}
/*
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index b892b6307..f8b50ed1d 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -9456,9 +9456,9 @@ ex_redir(exarg_T *eap)
char_u *arg = eap->arg;
#ifdef FEAT_EVAL
- if (redir_evalcmd)
+ if (redir_execute)
{
- EMSG(_("E930: Cannot use :redir inside evalcmd()"));
+ EMSG(_("E930: Cannot use :redir inside execute()"));
return;
}
#endif
diff --git a/src/globals.h b/src/globals.h
index 97711164a..68bf36f58 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -971,6 +971,7 @@ EXTERN cmdmod_T cmdmod; /* Ex command modifiers */
EXTERN int msg_silent INIT(= 0); /* don't print messages */
EXTERN int emsg_silent INIT(= 0); /* don't print error messages */
+EXTERN int emsg_noredir INIT(= 0); /* don't redirect error messages */
EXTERN int cmd_silent INIT(= FALSE); /* don't echo the command line */
#if defined(FEAT_GUI_DIALOG) || defined(FEAT_CON_DIALOG) \
@@ -1106,7 +1107,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 */
+EXTERN int redir_execute INIT(= 0); /* execute() redirection */
#endif
#ifdef FEAT_LANGMAP
diff --git a/src/message.c b/src/message.c
index f793ed414..7bb154d2e 100644
--- a/src/message.c
+++ b/src/message.c
@@ -566,22 +566,25 @@ emsg(char_u *s)
*/
if (emsg_silent != 0)
{
- msg_start();
- p = get_emsg_source();
- if (p != NULL)
+ if (emsg_noredir == 0)
{
- STRCAT(p, "\n");
- redir_write(p, -1);
- vim_free(p);
- }
- p = get_emsg_lnum();
- if (p != NULL)
- {
- STRCAT(p, "\n");
- redir_write(p, -1);
- vim_free(p);
+ msg_start();
+ p = get_emsg_source();
+ if (p != NULL)
+ {
+ STRCAT(p, "\n");
+ redir_write(p, -1);
+ vim_free(p);
+ }
+ p = get_emsg_lnum();
+ if (p != NULL)
+ {
+ STRCAT(p, "\n");
+ redir_write(p, -1);
+ vim_free(p);
+ }
+ redir_write(s, -1);
}
- redir_write(s, -1);
return TRUE;
}
@@ -3063,8 +3066,8 @@ redir_write(char_u *str, int maxlen)
while (cur_col < msg_col)
{
#ifdef FEAT_EVAL
- if (redir_evalcmd)
- evalcmd_redir_str((char_u *)" ", -1);
+ if (redir_execute)
+ execute_redir_str((char_u *)" ", -1);
else if (redir_reg)
write_reg_contents(redir_reg, (char_u *)" ", -1, TRUE);
else if (redir_vname)
@@ -3080,8 +3083,8 @@ redir_write(char_u *str, int maxlen)
}
#ifdef FEAT_EVAL
- if (redir_evalcmd)
- evalcmd_redir_str(s, maxlen);
+ if (redir_execute)
+ execute_redir_str(s, maxlen);
else if (redir_reg)
write_reg_contents(redir_reg, s, maxlen, TRUE);
else if (redir_vname)
@@ -3092,7 +3095,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 && !redir_evalcmd)
+ if (!redir_reg && !redir_vname && !redir_execute)
#endif
if (redir_fd != NULL)
putc(*s, redir_fd);
@@ -3117,7 +3120,7 @@ redirecting(void)
{
return redir_fd != NULL || *p_vfile != NUL
#ifdef FEAT_EVAL
- || redir_reg || redir_vname || redir_evalcmd
+ || redir_reg || redir_vname || redir_execute
#endif
;
}
diff --git a/src/proto/eval.pro b/src/proto/eval.pro
index 28edd782c..e81669b05 100644
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -88,7 +88,7 @@ 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 execute_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);
diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim
index 074c2dec9..3074a5c0b 100644
--- a/src/testdir/test_alot.vim
+++ b/src/testdir/test_alot.vim
@@ -5,7 +5,7 @@ source test_assign.vim
source test_autocmd.vim
source test_cursor_func.vim
source test_delete.vim
-source test_evalcmd.vim
+source test_execute_func.vim
source test_ex_undo.vim
source test_expand.vim
source test_expr.vim
diff --git a/src/testdir/test_evalcmd.vim b/src/testdir/test_evalcmd.vim
deleted file mode 100644
index a9bda875f..000000000
--- a/src/testdir/test_evalcmd.vim
+++ /dev/null
@@ -1,33 +0,0 @@
-" 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
-
diff --git a/src/testdir/test_execute_func.vim b/src/testdir/test_execute_func.vim
new file mode 100644
index 000000000..dd07e4a62
--- /dev/null
+++ b/src/testdir/test_execute_func.vim
@@ -0,0 +1,51 @@
+" test execute()
+
+func NestedEval()
+ let nested = execute('echo "nested\nlines"')
+ echo 'got: "' . nested . '"'
+endfunc
+
+func NestedRedir()
+ redir => var
+ echo 'broken'
+ redir END
+endfunc
+
+func Test_execute_string()
+ call assert_equal("\nnocompatible", execute('set compatible?'))
+ call assert_equal("\nsomething\nnice", execute('echo "something\nnice"'))
+ call assert_equal("noendofline", execute('echon "noendofline"'))
+ call assert_equal("", execute(123))
+
+ call assert_equal("\ngot: \"\nnested\nlines\"", execute('call NestedEval()'))
+ redir => redired
+ echo 'this'
+ let evaled = execute('echo "that"')
+ echo 'theend'
+ redir END
+ call assert_equal("\nthis\ntheend", redired)
+ call assert_equal("\nthat", evaled)
+
+ call assert_fails('call execute("doesnotexist")', 'E492:')
+ call assert_fails('call execute(3.4)', 'E806:')
+ call assert_fails('call execute("call NestedRedir()")', 'E930:')
+
+ call assert_equal("\nsomething", execute('echo "something"', ''))
+ call assert_equal("\nsomething", execute('echo "something"', 'silent'))
+ call assert_equal("\nsomething", execute('echo "something"', 'silent!'))
+ call assert_equal("", execute('burp', 'silent!'))
+ call assert_fails('call execute("echo \"x\"", 3.4)', 'E806:')
+
+ call assert_equal("", execute(test_null_string()))
+endfunc
+
+func Test_execute_list()
+ call assert_equal("\nsomething\nnice", execute(['echo "something"', 'echo "nice"']))
+ let l = ['for n in range(0, 3)',
+ \ 'echo n',
+ \ 'endfor']
+ call assert_equal("\n0\n1\n2\n3", execute(l))
+
+ call assert_equal("", execute([]))
+ call assert_equal("", execute(test_null_list()))
+endfunc