mirror of
https://github.com/vim/vim.git
synced 2025-09-23 03:43:49 -04:00
patch 8.2.0321: Vim9: ":execute" does not work yet
Problem: Vim9: ":execute" does not work yet. Solution: Add ISN_EXECUTE. (closes #5699) Also make :echo work with more than one argument.
This commit is contained in:
@@ -690,4 +690,37 @@ def Test_disassemble_compare()
|
||||
" delete('Xdisassemble')
|
||||
enddef
|
||||
|
||||
def s:Execute()
|
||||
execute 'help vim9.txt'
|
||||
let cmd = 'help vim9.txt'
|
||||
execute cmd
|
||||
let tag = 'vim9.txt'
|
||||
execute 'help ' .. tag
|
||||
enddef
|
||||
|
||||
def Test_disassemble_execute()
|
||||
let res = execute('disass s:Execute')
|
||||
assert_match('\<SNR>\d*_Execute.*'
|
||||
\ .. "execute 'help vim9.txt'.*"
|
||||
\ .. '\d PUSHS "help vim9.txt".*'
|
||||
\ .. '\d EXECUTE 1.*'
|
||||
\ .. "let cmd = 'help vim9.txt'.*"
|
||||
\ .. '\d PUSHS "help vim9.txt".*'
|
||||
\ .. '\d STORE $0.*'
|
||||
\ .. 'execute cmd.*'
|
||||
\ .. '\d LOAD $0.*'
|
||||
\ .. '\d EXECUTE 1.*'
|
||||
\ .. "let tag = 'vim9.txt'.*"
|
||||
\ .. '\d PUSHS "vim9.txt".*'
|
||||
\ .. '\d STORE $1.*'
|
||||
\ .. "execute 'help ' .. tag.*"
|
||||
\ .. '\d PUSHS "help ".*'
|
||||
\ .. '\d LOAD $1.*'
|
||||
\ .. '\d CONCAT.*'
|
||||
\ .. '\d EXECUTE 1.*'
|
||||
\ .. '\d PUSHNR 0.*'
|
||||
\ .. '\d RETURN'
|
||||
\, res)
|
||||
enddef
|
||||
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
|
@@ -1,6 +1,7 @@
|
||||
" Test various aspects of the Vim9 script language.
|
||||
|
||||
source check.vim
|
||||
source view_util.vim
|
||||
|
||||
" Check that "lines" inside ":def" results in an "error" message.
|
||||
func CheckDefFailure(lines, error)
|
||||
@@ -692,5 +693,33 @@ def Test_substitute_cmd()
|
||||
delete('Xvim9lines')
|
||||
enddef
|
||||
|
||||
def Test_execute_cmd()
|
||||
new
|
||||
setline(1, 'default')
|
||||
execute 'call setline(1, "execute-string")'
|
||||
assert_equal('execute-string', getline(1))
|
||||
let cmd1 = 'call setline(1,'
|
||||
let cmd2 = '"execute-var")'
|
||||
execute cmd1 cmd2
|
||||
assert_equal('execute-var', getline(1))
|
||||
execute cmd1 cmd2 '|call setline(1, "execute-var-string")'
|
||||
assert_equal('execute-var-string', getline(1))
|
||||
let cmd_first = 'call '
|
||||
let cmd_last = 'setline(1, "execute-var-var")'
|
||||
execute cmd_first .. cmd_last
|
||||
assert_equal('execute-var-var', getline(1))
|
||||
bwipe!
|
||||
enddef
|
||||
|
||||
def Test_echo_cmd()
|
||||
echo 'something'
|
||||
assert_match('^something$', Screenline(&lines))
|
||||
|
||||
let str1 = 'some'
|
||||
let str2 = 'more'
|
||||
echo str1 str2
|
||||
assert_match('^some more$', Screenline(&lines))
|
||||
enddef
|
||||
|
||||
|
||||
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
|
||||
|
@@ -738,6 +738,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
321,
|
||||
/**/
|
||||
320,
|
||||
/**/
|
||||
|
@@ -13,7 +13,8 @@
|
||||
|
||||
typedef enum {
|
||||
ISN_EXEC, // execute Ex command line isn_arg.string
|
||||
ISN_ECHO, // echo isn_arg.number items on top of stack
|
||||
ISN_ECHO, // echo isn_arg.echo.echo_count items on top of stack
|
||||
ISN_EXECUTE, // execute Ex commands isn_arg.number items on top of stack
|
||||
|
||||
// get and set variables
|
||||
ISN_LOAD, // push local variable isn_arg.number
|
||||
|
@@ -1116,6 +1116,21 @@ generate_ECHO(cctx_T *cctx, int with_white, int count)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Generate an ISN_EXECUTE instruction.
|
||||
*/
|
||||
static int
|
||||
generate_EXECUTE(cctx_T *cctx, int count)
|
||||
{
|
||||
isn_T *isn;
|
||||
|
||||
if ((isn = generate_instr_drop(cctx, ISN_EXECUTE, count)) == NULL)
|
||||
return FAIL;
|
||||
isn->isn_arg.number = count;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static int
|
||||
generate_EXEC(cctx_T *cctx, char_u *line)
|
||||
{
|
||||
@@ -4671,14 +4686,40 @@ compile_echo(char_u *arg, int with_white, cctx_T *cctx)
|
||||
char_u *p = arg;
|
||||
int count = 0;
|
||||
|
||||
// for ()
|
||||
for (;;)
|
||||
{
|
||||
if (compile_expr1(&p, cctx) == FAIL)
|
||||
return NULL;
|
||||
++count;
|
||||
p = skipwhite(p);
|
||||
if (ends_excmd(*p))
|
||||
break;
|
||||
}
|
||||
|
||||
generate_ECHO(cctx, with_white, count);
|
||||
return p;
|
||||
}
|
||||
|
||||
/*
|
||||
* compile "execute expr"
|
||||
*/
|
||||
static char_u *
|
||||
compile_execute(char_u *arg, cctx_T *cctx)
|
||||
{
|
||||
char_u *p = arg;
|
||||
int count = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (compile_expr1(&p, cctx) == FAIL)
|
||||
return NULL;
|
||||
++count;
|
||||
p = skipwhite(p);
|
||||
if (ends_excmd(*p))
|
||||
break;
|
||||
}
|
||||
|
||||
generate_EXECUTE(cctx, count);
|
||||
|
||||
return p;
|
||||
}
|
||||
@@ -5017,12 +5058,14 @@ compile_def_function(ufunc_T *ufunc, int set_return_type)
|
||||
case CMD_echon:
|
||||
line = compile_echo(p, FALSE, &cctx);
|
||||
break;
|
||||
case CMD_execute:
|
||||
line = compile_execute(p, &cctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
// Not recognized, execute with do_cmdline_cmd().
|
||||
// TODO:
|
||||
// CMD_echomsg
|
||||
// CMD_execute
|
||||
// etc.
|
||||
generate_EXEC(&cctx, line);
|
||||
line = (char_u *)"";
|
||||
@@ -5150,6 +5193,7 @@ delete_instr(isn_T *isn)
|
||||
case ISN_DCALL:
|
||||
case ISN_DROP:
|
||||
case ISN_ECHO:
|
||||
case ISN_EXECUTE:
|
||||
case ISN_ENDTRY:
|
||||
case ISN_FOR:
|
||||
case ISN_FUNCREF:
|
||||
|
@@ -533,6 +533,48 @@ call_def_function(
|
||||
}
|
||||
break;
|
||||
|
||||
// execute :execute {string} ...
|
||||
case ISN_EXECUTE:
|
||||
{
|
||||
int count = iptr->isn_arg.number;
|
||||
garray_T ga;
|
||||
char_u buf[NUMBUFLEN];
|
||||
char_u *p;
|
||||
int len;
|
||||
int failed = FALSE;
|
||||
|
||||
ga_init2(&ga, 1, 80);
|
||||
for (idx = 0; idx < count; ++idx)
|
||||
{
|
||||
tv = STACK_TV_BOT(idx - count);
|
||||
if (tv->v_type == VAR_CHANNEL || tv->v_type == VAR_JOB)
|
||||
{
|
||||
emsg(_(e_inval_string));
|
||||
break;
|
||||
}
|
||||
else
|
||||
p = tv_get_string_buf(tv, buf);
|
||||
|
||||
len = (int)STRLEN(p);
|
||||
if (ga_grow(&ga, len + 2) == FAIL)
|
||||
failed = TRUE;
|
||||
else
|
||||
{
|
||||
if (ga.ga_len > 0)
|
||||
((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
|
||||
STRCPY((char_u *)(ga.ga_data) + ga.ga_len, p);
|
||||
ga.ga_len += len;
|
||||
}
|
||||
clear_tv(tv);
|
||||
}
|
||||
ectx.ec_stack.ga_len -= count;
|
||||
|
||||
if (!failed && ga.ga_data != NULL)
|
||||
do_cmdline_cmd((char_u *)ga.ga_data);
|
||||
ga_clear(&ga);
|
||||
}
|
||||
break;
|
||||
|
||||
// load local variable or argument
|
||||
case ISN_LOAD:
|
||||
if (ga_grow(&ectx.ec_stack, 1) == FAIL)
|
||||
@@ -1666,6 +1708,9 @@ ex_disassemble(exarg_T *eap)
|
||||
echo->echo_count);
|
||||
}
|
||||
break;
|
||||
case ISN_EXECUTE:
|
||||
smsg("%4d EXECUTE %d", current, iptr->isn_arg.number);
|
||||
break;
|
||||
case ISN_LOAD:
|
||||
if (iptr->isn_arg.number < 0)
|
||||
smsg("%4d LOAD arg[%lld]", current,
|
||||
|
Reference in New Issue
Block a user