diff src/vim9compile.c @ 22703:f2bfee4ac356 v8.2.1900

patch 8.2.1900: Vim9: command modifiers do not work Commit: https://github.com/vim/vim/commit/02194d2bd54eacd0b7b9a017a3fe1702ecb80971 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Oct 24 23:08:38 2020 +0200 patch 8.2.1900: Vim9: command modifiers do not work Problem: Vim9: command modifiers do not work. Solution: Make most command modifiers work.
author Bram Moolenaar <Bram@vim.org>
date Sat, 24 Oct 2020 23:15:04 +0200
parents e82579016863
children 02b782e80ee4
line wrap: on
line diff
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -142,7 +142,7 @@ struct cctx_S {
     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_EXECCONCAT(cctx_T *cctx, int co
 }
 
 /*
- * 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 ((isn = generate_instr(cctx, ISN_SILENT)) == NULL)
+    if (cmod->cmod_flags != 0
+	    || cmod->cmod_split != 0
+	    || cmod->cmod_verbose != 0
+	    || cmod->cmod_tab != 0
+	    || cmod->cmod_filter_regmatch.regprog != 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 ((isn = generate_instr(cctx, ISN_UNSILENT)) == NULL)
+    if (cctx->ctx_has_cmdmod)
+    {
+	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 @@ compile_def_function(ufunc_T *ufunc, int
     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 @@ compile_def_function(ufunc_T *ufunc, int
 	/*
 	 * 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 @@ nextline:
 	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 @@ delete_instr(isn_T *isn)
 	    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 @@ delete_instr(isn_T *isn)
 	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 @@ delete_instr(isn_T *isn)
 	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 @@ delete_instr(isn_T *isn)
 	case ISN_STRSLICE:
 	case ISN_THROW:
 	case ISN_TRY:
-	case ISN_UNSILENT:
 	    // nothing allocated
 	    break;
     }