mirror of
https://github.com/neovim/neovim.git
synced 2026-08-28 01:51:52 +00:00
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:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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"},
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
55
src/nvim/testdir/test_execute_func.vim
Normal file
55
src/nvim/testdir/test_execute_func.vim
Normal 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
|
||||
Reference in New Issue
Block a user