diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/eval.c | 53 | ||||
-rw-r--r-- | src/nvim/eval.lua | 2 | ||||
-rw-r--r-- | src/nvim/globals.h | 7 | ||||
-rw-r--r-- | src/nvim/message.c | 31 | ||||
-rw-r--r-- | src/nvim/testdir/test_alot.vim | 1 | ||||
-rw-r--r-- | src/nvim/testdir/test_execute_func.vim | 55 | ||||
-rw-r--r-- | src/nvim/version.c | 4 |
7 files changed, 125 insertions, 28 deletions
diff --git a/src/nvim/eval.c b/src/nvim/eval.c index a046b2a288..17e89e5757 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -8828,34 +8828,73 @@ 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()) { return; } + 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++; + } + 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[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..463f4fcd8d 100644 --- a/src/nvim/globals.h +++ b/src/nvim/globals.h @@ -869,9 +869,10 @@ EXTERN int mapped_ctrl_c INIT(= 0); // Modes where CTRL-C is mapped. 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 cmd_silent INIT(= FALSE); /* don't echo the command line */ +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 */ #define SEA_NONE 0 /* don't use dialog */ diff --git a/src/nvim/message.c b/src/nvim/message.c index 637b89ccbe..2f8feda6ec 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,8 +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 diff --git a/src/nvim/version.c b/src/nvim/version.c index 30371b2d02..b8f0acb96b 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -431,8 +431,8 @@ static int included_patches[] = { 2012, 2011, 2010, - // 2009, - // 2008, + 2009, + 2008, 2007, // 2006, 2005, |