patch 8.2.1900: Vim9: command modifiers do not work
Problem: Vim9: command modifiers do not work.
Solution: Make most command modifiers work.
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 7ce55d0..60b55d5 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -142,7 +142,7 @@
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
+ int ctx_has_cmdmod; // ISN_CMDMOD was generated
};
static void delete_def_function_contents(dfunc_T *dfunc);
@@ -1823,36 +1823,45 @@
}
/*
- * Generate any instructions for side effects of "cmdmod".
+ * Generate an instruction for any command modifiers.
*/
static int
generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod)
{
isn_T *isn;
- // TODO: use more modifiers in the command
- if (cmod->cmod_flags & (CMOD_SILENT | CMOD_ERRSILENT))
+ if (cmod->cmod_flags != 0
+ || cmod->cmod_split != 0
+ || cmod->cmod_verbose != 0
+ || cmod->cmod_tab != 0
+ || cmod->cmod_filter_regmatch.regprog != NULL)
{
- if ((isn = generate_instr(cctx, ISN_SILENT)) == NULL)
+ cctx->ctx_has_cmdmod = TRUE;
+
+ if ((isn = generate_instr(cctx, ISN_CMDMOD)) == NULL)
return FAIL;
- isn->isn_arg.number = (cmod->cmod_flags & CMOD_ERRSILENT) != 0;
- cctx->ctx_silent = (cmod->cmod_flags & CMOD_ERRSILENT) ? 2 : 1;
+ isn->isn_arg.cmdmod.cf_cmdmod = ALLOC_ONE(cmdmod_T);
+ if (isn->isn_arg.cmdmod.cf_cmdmod == NULL)
+ return FAIL;
+ mch_memmove(isn->isn_arg.cmdmod.cf_cmdmod, cmod, sizeof(cmdmod_T));
+ // filter progam now belongs to the instruction
+ cmod->cmod_filter_regmatch.regprog = NULL;
}
+
return OK;
}
static int
-generate_restore_cmdmods(cctx_T *cctx)
+generate_undo_cmdmods(cctx_T *cctx)
{
isn_T *isn;
- if (cctx->ctx_silent > 0)
+ if (cctx->ctx_has_cmdmod)
{
- if ((isn = generate_instr(cctx, ISN_UNSILENT)) == NULL)
+ if ((isn = generate_instr(cctx, ISN_CMDMOD_REV)) == NULL)
return FAIL;
- isn->isn_arg.number = cctx->ctx_silent == 2;
- cctx->ctx_silent = 0;
}
+
return OK;
}
@@ -7092,9 +7101,9 @@
for (;;)
{
exarg_T ea;
- cmdmod_T local_cmdmod;
int starts_with_colon = FALSE;
char_u *cmd;
+ cmdmod_T local_cmdmod;
// Bail out on the first error to avoid a flood of errors and report
// the right line number when inside try/catch.
@@ -7175,7 +7184,7 @@
/*
* COMMAND MODIFIERS
*/
- CLEAR_FIELD(local_cmdmod);
+ cctx.ctx_has_cmdmod = FALSE;
if (parse_command_modifiers(&ea, &errormsg, &local_cmdmod, FALSE)
== FAIL)
{
@@ -7497,7 +7506,7 @@
line = skipwhite(line);
// Undo any command modifiers.
- generate_restore_cmdmods(&cctx);
+ generate_undo_cmdmods(&cctx);
if (cctx.ctx_type_stack.ga_len < 0)
{
@@ -7742,6 +7751,12 @@
free_type(isn->isn_arg.type.ct_type);
break;
+ case ISN_CMDMOD:
+ vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
+ ->cmod_filter_regmatch.regprog);
+ vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
+ break;
+
case ISN_2BOOL:
case ISN_2STRING:
case ISN_2STRING_ANY:
@@ -7754,6 +7769,7 @@
case ISN_CATCH:
case ISN_CHECKLEN:
case ISN_CHECKNR:
+ case ISN_CMDMOD_REV:
case ISN_COMPAREANY:
case ISN_COMPAREBLOB:
case ISN_COMPAREBOOL:
@@ -7805,7 +7821,6 @@
case ISN_PUT:
case ISN_RETURN:
case ISN_SHUFFLE:
- case ISN_SILENT:
case ISN_SLICE:
case ISN_STORE:
case ISN_STOREDICT:
@@ -7819,7 +7834,6 @@
case ISN_STRSLICE:
case ISN_THROW:
case ISN_TRY:
- case ISN_UNSILENT:
// nothing allocated
break;
}