Patch 8.2.1894
Problem: Vim9: command modifiers are not supported.
Solution: Support "silent" and "silent!".
Files: src/structs.h, src/vim9compile.c, src/vim9.h, src/vim9execute.c,
src/evalvars.c, src/testdir/test_vim9_disassemble.vim,
src/testdir/test_vim9_cmd.vim
*** ../vim-8.2.1893/src/structs.h 2020-10-20 14:25:03.926883018 +0200
--- src/structs.h 2020-10-23 17:01:56.746351150 +0200
***************
*** 643,648 ****
--- 643,650 ----
char_u *save_ei; // saved value of 'eventignore'
regmatch_T filter_regmatch; // set by :filter /pat/
int filter_force; // set for :filter!
+ int msg_silent; // TRUE when ":silent" was used
+ int emsg_silent; // TRUE when ":silent!" was used
} cmdmod_T;
#define MF_SEED_LEN 8
*** ../vim-8.2.1893/src/vim9compile.c 2020-10-22 21:22:54.740905315 +0200
--- src/vim9compile.c 2020-10-23 17:18:51.747503070 +0200
***************
*** 141,146 ****
--- 141,148 ----
garray_T ctx_type_stack; // type of each item on the stack
garray_T *ctx_type_list; // list of pointers to allocated types
+
+ int ctx_silent; // set when ISN_SILENT was generated
};
static void delete_def_function_contents(dfunc_T *dfunc);
***************
*** 1821,1826 ****
--- 1823,1862 ----
}
/*
+ * Generate any instructions for side effects of "cmdmod".
+ */
+ static int
+ generate_cmdmods(cctx_T *cctx)
+ {
+ isn_T *isn;
+
+ // TODO: use more modifiers in the command
+ if (cmdmod.msg_silent || cmdmod.emsg_silent)
+ {
+ if ((isn = generate_instr(cctx, ISN_SILENT)) == NULL)
+ return FAIL;
+ isn->isn_arg.number = cmdmod.emsg_silent;
+ cctx->ctx_silent = cmdmod.emsg_silent ? 2 : 1;
+ }
+ return OK;
+ }
+
+ static int
+ generate_restore_cmdmods(cctx_T *cctx)
+ {
+ isn_T *isn;
+
+ if (cctx->ctx_silent > 0)
+ {
+ if ((isn = generate_instr(cctx, ISN_UNSILENT)) == NULL)
+ return FAIL;
+ isn->isn_arg.number = cctx->ctx_silent == 2;
+ cctx->ctx_silent = 0;
+ }
+ return OK;
+ }
+
+ /*
* Reserve space for a local variable.
* Return the variable or NULL if it failed.
*/
***************
*** 7149,7155 ****
line = (char_u *)"";
continue;
}
! // TODO: use modifiers in the command
undo_cmdmod(&ea, save_msg_scroll);
cmdmod = save_cmdmod;
--- 7185,7192 ----
line = (char_u *)"";
continue;
}
! generate_cmdmods(&cctx);
!
undo_cmdmod(&ea, save_msg_scroll);
cmdmod = save_cmdmod;
***************
*** 7461,7466 ****
--- 7498,7506 ----
goto erret;
line = skipwhite(line);
+ // Undo any command modifiers.
+ generate_restore_cmdmods(&cctx);
+
if (cctx.ctx_type_stack.ga_len < 0)
{
iemsg("Type stack underflow");
***************
*** 7767,7772 ****
--- 7807,7813 ----
case ISN_PUT:
case ISN_RETURN:
case ISN_SHUFFLE:
+ case ISN_SILENT:
case ISN_SLICE:
case ISN_STORE:
case ISN_STOREDICT:
***************
*** 7780,7785 ****
--- 7821,7827 ----
case ISN_STRSLICE:
case ISN_THROW:
case ISN_TRY:
+ case ISN_UNSILENT:
// nothing allocated
break;
}
*** ../vim-8.2.1893/src/vim9.h 2020-10-19 20:45:32.376596657 +0200
--- src/vim9.h 2020-10-23 17:13:57.592331841 +0200
***************
*** 142,147 ****
--- 142,150 ----
ISN_PUT, // ":put", uses isn_arg.put
+ ISN_SILENT, // set msg_silent or emsg_silent if arg_number is non-zero
+ ISN_UNSILENT, // undo ISN_SILENT
+
ISN_SHUFFLE, // move item on stack up or down
ISN_DROP // pop stack and discard value
} isntype_T;
*** ../vim-8.2.1893/src/vim9execute.c 2020-10-19 23:01:42.507664521 +0200
--- src/vim9execute.c 2020-10-23 17:23:15.826776946 +0200
***************
*** 832,837 ****
--- 832,839 ----
int save_suppress_errthrow = suppress_errthrow;
msglist_T **saved_msg_list = NULL;
msglist_T *private_msg_list = NULL;
+ int save_msg_silent = -1;
+ int save_emsg_silent = -1;
// Get pointer to item in the stack.
#define STACK_TV(idx) (((typval_T *)ectx.ec_stack.ga_data) + idx)
***************
*** 2814,2819 ****
--- 2816,2839 ----
}
break;
+ case ISN_SILENT:
+ if (save_msg_silent == -1)
+ save_msg_silent = msg_silent;
+ ++msg_silent;
+ if (iptr->isn_arg.number)
+ {
+ if (save_emsg_silent == -1)
+ save_emsg_silent = emsg_silent;
+ ++emsg_silent;
+ }
+ break;
+
+ case ISN_UNSILENT:
+ --msg_silent;
+ if (iptr->isn_arg.number)
+ --emsg_silent;
+ break;
+
case ISN_SHUFFLE:
{
typval_T tmp_tv;
***************
*** 2885,2890 ****
--- 2905,2915 ----
}
msg_list = saved_msg_list;
+ if (save_msg_silent != -1)
+ msg_silent = save_msg_silent;
+ if (save_emsg_silent != -1)
+ emsg_silent = save_emsg_silent;
+
failed_early:
// Free all local variables, but not arguments.
for (idx = 0; idx < ectx.ec_stack.ga_len; ++idx)
***************
*** 3502,3507 ****
--- 3527,3537 ----
(long)iptr->isn_arg.put.put_lnum);
break;
+ case ISN_SILENT: smsg("%4d SILENT%s", current,
+ iptr->isn_arg.number ? "!" : ""); break;
+ case ISN_UNSILENT: smsg("%4d UNSILENT%s", current,
+ iptr->isn_arg.number ? "!" : ""); break;
+
case ISN_SHUFFLE: smsg("%4d SHUFFLE %d up %d", current,
iptr->isn_arg.shuffle.shfl_item,
iptr->isn_arg.shuffle.shfl_up);
*** ../vim-8.2.1893/src/evalvars.c 2020-10-21 20:58:47.710889972 +0200
--- src/evalvars.c 2020-10-23 17:53:26.761147435 +0200
***************
*** 3577,3585 ****
tv.v_type = VAR_STRING;
tv.vval.v_string = (char_u *)"";
if (append)
! set_var_lval(redir_lval, redir_endp, &tv, TRUE, 0, (char_u *)".");
else
! set_var_lval(redir_lval, redir_endp, &tv, TRUE, 0, (char_u *)"=");
clear_lval(redir_lval);
if (called_emsg > called_emsg_before)
{
--- 3577,3587 ----
tv.v_type = VAR_STRING;
tv.vval.v_string = (char_u *)"";
if (append)
! set_var_lval(redir_lval, redir_endp, &tv, TRUE,
! ASSIGN_NO_DECL, (char_u *)".");
else
! set_var_lval(redir_lval, redir_endp, &tv, TRUE,
! ASSIGN_NO_DECL, (char_u *)"=");
clear_lval(redir_lval);
if (called_emsg > called_emsg_before)
{
*** ../vim-8.2.1893/src/testdir/test_vim9_disassemble.vim 2020-10-19 20:45:32.376596657 +0200
--- src/testdir/test_vim9_disassemble.vim 2020-10-23 17:29:25.925776064 +0200
***************
*** 1617,1620 ****
--- 1617,1644 ----
res)
enddef
+
+ def s:SilentMessage()
+ silent echomsg "text"
+ silent! echoerr "error"
+ enddef
+
+ def Test_silent()
+ var res = execute('disass s:SilentMessage')
+ assert_match('<SNR>\d*_SilentMessage\_s*' ..
+ 'silent echomsg "text"\_s*' ..
+ '\d SILENT\_s*' ..
+ '\d PUSHS "text"\_s*' ..
+ '\d ECHOMSG 1\_s*' ..
+ '\d UNSILENT\_s*' ..
+ 'silent! echoerr "error"\_s*' ..
+ '\d SILENT!\_s*' ..
+ '\d PUSHS "error"\_s*' ..
+ '\d ECHOERR 1\_s*' ..
+ '\d UNSILENT!\_s*' ..
+ '\d PUSHNR 0\_s*' ..
+ '\d RETURN',
+ res)
+ enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
*** ../vim-8.2.1893/src/testdir/test_vim9_cmd.vim 2020-10-22 21:22:54.744905305 +0200
--- src/testdir/test_vim9_cmd.vim 2020-10-23 17:55:03.888831736 +0200
***************
*** 401,405 ****
--- 401,417 ----
CheckScriptSuccess(lines)
enddef
+ def Test_modifier_silent()
+ echomsg 'last one'
+ silent echomsg "text"
+ redir => g:testmsg
+ :1messages
+ redir END
+ assert_equal("\nlast one", g:testmsg)
+ unlet g:testmsg
+
+ silent! echoerr "error"
+ enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
*** ../vim-8.2.1893/src/version.c 2020-10-23 16:49:30.116311438 +0200
--- src/version.c 2020-10-23 18:00:38.307787900 +0200
***************
*** 752,753 ****
--- 752,755 ----
{ /* Add new patch number below this line */
+ /**/
+ 1894,
/**/
--
An actual excerpt from a classified section of a city newspaper:
"Illiterate? Write today for free help!"
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language --
http://www.Zimbu.org ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///