vim-patch:7.4.2008

Problem:    evalcmd() has a confusing name.
Solution:   Rename to execute().  Make silent optional.  Support a list of
            commands.

79815f1ec7
This commit is contained in:
James McCoy
2017-01-08 23:13:51 -05:00
parent 9fcf6d577f
commit 6520517e22
8 changed files with 207 additions and 45 deletions

View File

@@ -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;
}

View File

@@ -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"},

View File

@@ -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 */

View File

@@ -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);
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));
}
p = get_emsg_lnum();
if (p != NULL) {
STRCAT(p, "\n");
redir_write(p, STRLEN(p));
xfree(p);
}
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
;
}

View File

@@ -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

View File

@@ -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