patch 7.4.2008
Problem: evalcmd() has a confusing name.
Solution: Rename to execute(). Make silent optional. Support a list of
commands.
diff --git a/src/eval.c b/src/eval.c
index 4764f49..ab808b9 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -555,9 +555,9 @@
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 @@
{"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,65 +11345,6 @@
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
- */
- static void
-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;
-
- s = get_tv_string_chk(&argvars[0]);
- if (s != NULL)
- {
- if (redir_evalcmd)
- save_ga = redir_evalcmd_ga;
- ga_init2(&redir_evalcmd_ga, (int)sizeof(char), 500);
- redir_evalcmd = TRUE;
-
- ++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;
-
- /* "silent reg" or "silent echo x" leaves msg_col somewhere in the
- * line. Put it back in the first column. */
- msg_col = 0;
- }
-}
-
/*
* "eventhandler()" function
*/
@@ -11426,6 +11367,132 @@
|| (gettail(name) != name && mch_can_exe(name, NULL, FALSE));
}
+static garray_T redir_execute_ga;
+
+/*
+ * Append "value[value_len]" to the execute() output.
+ */
+ void
+execute_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_execute_ga, len) == OK)
+ {
+ mch_memmove((char *)redir_execute_ga.ga_data
+ + redir_execute_ga.ga_len, value, len);
+ redir_execute_ga.ga_len += len;
+ }
+}
+
+/*
+ * 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 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_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;
+
+ if (argvars[0].v_type == VAR_LIST)
+ {
+ 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;
+
+ if (cmd != NULL)
+ do_cmdline_cmd(cmd);
+ else
+ {
+ listitem_T *item = list->lv_first;
+
+ do_cmdline(NULL, get_list_line, (void *)&item,
+ DOCMD_NOWAIT|DOCMD_VERBOSE|DOCMD_REPEAT|DOCMD_KEYTYPED);
+ --list->lv_refcount;
+ }
+
+ rettv->vval.v_string = redir_execute_ga.ga_data;
+ msg_silent = save_msg_silent;
+ emsg_silent = save_emsg_silent;
+ emsg_noredir = save_emsg_noredir;
+
+ redir_execute = save_redir_execute;
+ if (redir_execute)
+ redir_execute_ga = save_ga;
+
+ /* "silent reg" or "silent echo x" leaves msg_col somewhere in the
+ * line. Put it back in the first column. */
+ msg_col = 0;
+}
+
/*
* "exepath()" function
*/