aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2017-01-08 23:13:51 -0500
committerJames McCoy <jamessan@jamessan.com>2017-01-10 07:14:12 -0500
commit6520517e22ad87e1be558f2e899152ca5a9174a2 (patch)
tree16b726be3b3caac3976c7857fbed5e5fee0814a9 /src
parent9fcf6d577fa712d2ce420012c53a687cc9f7301d (diff)
downloadrneovim-6520517e22ad87e1be558f2e899152ca5a9174a2.tar.gz
rneovim-6520517e22ad87e1be558f2e899152ca5a9174a2.tar.bz2
rneovim-6520517e22ad87e1be558f2e899152ca5a9174a2.zip
vim-patch:7.4.2008
Problem: evalcmd() has a confusing name. Solution: Rename to execute(). Make silent optional. Support a list of commands. https://github.com/vim/vim/commit/79815f1ec77406f2f21a618c053e5793b597db7a
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval.c53
-rw-r--r--src/nvim/eval.lua2
-rw-r--r--src/nvim/globals.h1
-rw-r--r--src/nvim/message.c30
-rw-r--r--src/nvim/testdir/test_alot.vim1
-rw-r--r--src/nvim/testdir/test_execute_func.vim55
6 files changed, 120 insertions, 22 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index a046b2a288..2e86da5046 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -8828,10 +8828,27 @@ static void f_executable(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|| (gettail_dir(name) != name && os_can_exe(name, NULL, false));
}
+static char_u * get_list_line(int c, void *cookie, int indent)
+{
+ 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(command)" function
static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
{
int save_msg_silent = msg_silent;
+ int save_emsg_silent = emsg_silent;
+ bool save_emsg_noredir = emsg_noredir;
garray_T *save_capture_ga = capture_ga;
if (check_secure()) {
@@ -8839,23 +8856,45 @@ static void f_execute(typval_T *argvars, typval_T *rettv, FunPtr fptr)
}
garray_T capture_local;
+ ga_init(&capture_local, (int)sizeof(char), 80);
capture_ga = &capture_local;
- ga_init(capture_ga, (int)sizeof(char), 80);
- msg_silent++;
+ 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 (argvars[0].v_type != VAR_LIST) {
do_cmdline_cmd((char *)get_tv_string(&argvars[0]));
} else if (argvars[0].vval.v_list != NULL) {
- for (listitem_T *li = argvars[0].vval.v_list->lv_first;
- li != NULL; li = li->li_next) {
- do_cmdline_cmd((char *)get_tv_string(&li->li_tv));
- }
+ list_T *list = argvars[0].vval.v_list;
+ list->lv_refcount++;
+ 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--;
}
msg_silent = save_msg_silent;
+ emsg_silent = save_emsg_silent;
+ emsg_noredir = save_emsg_noredir;
ga_append(capture_ga, NUL);
rettv->v_type = VAR_STRING;
- rettv->vval.v_string = capture_ga->ga_data;
+ rettv->vval.v_string = vim_strsave(capture_ga->ga_data);
+ ga_clear(capture_ga);
capture_ga = save_capture_ga;
}
diff --git a/src/nvim/eval.lua b/src/nvim/eval.lua
index 5fb99fecc6..e0b72feb19 100644
--- a/src/nvim/eval.lua
+++ b/src/nvim/eval.lua
@@ -79,7 +79,7 @@ return {
eval={args=1},
eventhandler={},
executable={args=1},
- execute={args=1},
+ execute={args={1, 2}},
exepath={args=1},
exists={args=1},
exp={args=1, func="float_op_wrapper", data="&exp"},
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 5ee04ad982..692b3b761c 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -871,6 +871,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 bool emsg_noredir INIT(= false); // don't redirect error messages
EXTERN int cmd_silent INIT(= FALSE); /* don't echo the command line */
/* Values for swap_exists_action: what to do when swap file already exists */
diff --git a/src/nvim/message.c b/src/nvim/message.c
index 637b89ccbe..8c164111f2 100644
--- a/src/nvim/message.c
+++ b/src/nvim/message.c
@@ -508,20 +508,22 @@ int emsg(char_u *s)
* But do write it to the redirection file.
*/
if (emsg_silent != 0) {
- msg_start();
- p = get_emsg_source();
- if (p != NULL) {
- STRCAT(p, "\n");
- redir_write(p, STRLEN(p));
- xfree(p);
- }
- p = get_emsg_lnum();
- if (p != NULL) {
- STRCAT(p, "\n");
- redir_write(p, STRLEN(p));
- xfree(p);
+ if (!emsg_noredir) {
+ msg_start();
+ p = get_emsg_source();
+ if (p != NULL) {
+ STRCAT(p, "\n");
+ redir_write(p, STRLEN(p));
+ xfree(p);
+ }
+ p = get_emsg_lnum();
+ if (p != NULL) {
+ STRCAT(p, "\n");
+ redir_write(p, STRLEN(p));
+ xfree(p);
+ }
+ redir_write(s, STRLEN(s));
}
- redir_write(s, STRLEN(s));
return true;
}
@@ -2508,7 +2510,7 @@ static void redir_write(char_u *str, int maxlen)
int redirecting(void)
{
return redir_fd != NULL || *p_vfile != NUL
- || redir_reg || redir_vname
+ || redir_reg || redir_vname || capture_ga != NULL
;
}
diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim
index 818ff7cf54..60248bf430 100644
--- a/src/nvim/testdir/test_alot.vim
+++ b/src/nvim/testdir/test_alot.vim
@@ -4,6 +4,7 @@
source test_assign.vim
source test_autocmd.vim
source test_cursor_func.vim
+source test_execute_func.vim
source test_ex_undo.vim
source test_expr.vim
source test_expr_utf8.vim
diff --git a/src/nvim/testdir/test_execute_func.vim b/src/nvim/testdir/test_execute_func.vim
new file mode 100644
index 0000000000..6f61bede93
--- /dev/null
+++ b/src/nvim/testdir/test_execute_func.vim
@@ -0,0 +1,55 @@
+" 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
+" Nvim supports execute('... :redir ...'), so this test is intentionally
+" disabled.
+" 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:')
+" Nvim supports execute('... :redir ...'), so this test is intentionally
+" disabled.
+" 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(""))
+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(v:_null_list))
+endfunc