]> granicus.if.org Git - vim/commitdiff
patch 8.2.2955: Vim9: using filter in compiled command does not work v8.2.2955
authorBram Moolenaar <Bram@vim.org>
Sun, 6 Jun 2021 19:38:09 +0000 (21:38 +0200)
committerBram Moolenaar <Bram@vim.org>
Sun, 6 Jun 2021 19:38:09 +0000 (21:38 +0200)
Problem:    Vim9: using filter in compiled command does not work.
Solution:   Generate EXEC including the command modifier.

src/ex_cmds.c
src/ex_docmd.c
src/proto/ex_cmds.pro
src/testdir/test_vim9_cmd.vim
src/version.c
src/vim9compile.c

index e1497a5a4a1859e2caee31a237cbf23b00d796cf..614d41d69fc9b79dabf07c4ac71235775e1acb4e 100644 (file)
@@ -5277,6 +5277,16 @@ ex_drop(exarg_T *eap)
  */
     char_u *
 skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
+{
+    return skip_vimgrep_pat_ext(p, s, flags, NULL, NULL);
+}
+
+/*
+ * As skip_vimgrep_pat() and store the character overwritten by NUL in "cp"
+ * and the pointer to it in "nulp".
+ */
+    char_u *
+skip_vimgrep_pat_ext(char_u *p, char_u **s, int *flags, char_u **nulp, int *cp)
 {
     int                c;
 
@@ -5287,7 +5297,14 @@ skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
            *s = p;
        p = skiptowhite(p);
        if (s != NULL && *p != NUL)
+       {
+           if (nulp != NULL)
+           {
+               *nulp = p;
+               *cp = *p;
+           }
            *p++ = NUL;
+       }
     }
     else
     {
@@ -5301,7 +5318,14 @@ skip_vimgrep_pat(char_u *p, char_u **s, int *flags)
 
        // Truncate the pattern.
        if (s != NULL)
+       {
+           if (nulp != NULL)
+           {
+               *nulp = p;
+               *cp = *p;
+           }
            *p = NUL;
+       }
        ++p;
 
        // Find the flags
index fbf2c7d0dd83fa43996e0cbe18d97debcc48d0b4..4aaccb593ff0bb6f70ef5c9b8034937bba31abfb 100644 (file)
@@ -2881,7 +2881,9 @@ parse_command_modifiers(
 
            case 'f':   // only accept ":filter {pat} cmd"
                        {
-                           char_u *reg_pat;
+                           char_u  *reg_pat;
+                           char_u  *nulp = NULL;
+                           int     c = 0;
 
                            if (!checkforcmd_noparen(&p, "filter", 4)
                                                || *p == NUL || ends_excmd(*p))
@@ -2902,7 +2904,8 @@ parse_command_modifiers(
                                p = skip_vimgrep_pat(p, NULL, NULL);
                            else
                                // NOTE: This puts a NUL after the pattern.
-                               p = skip_vimgrep_pat(p, &reg_pat, NULL);
+                               p = skip_vimgrep_pat_ext(p, &reg_pat, NULL,
+                                                                   &nulp, &c);
                            if (p == NULL || *p == NUL)
                                break;
                            if (!skip_only)
@@ -2911,6 +2914,9 @@ parse_command_modifiers(
                                                vim_regcomp(reg_pat, RE_MAGIC);
                                if (cmod->cmod_filter_regmatch.regprog == NULL)
                                    break;
+                               // restore the character overwritten by NUL
+                               if (nulp != NULL)
+                                   *nulp = c;
                            }
                            eap->cmd = p;
                            continue;
index 1711af4537cbd9c6d7c3de2f1f61485b76e08013..c083cec5ccd0622ac09a5a2ad8502eae07faf390 100644 (file)
@@ -39,5 +39,6 @@ int prepare_tagpreview(int undo_sync, int use_previewpopup, use_popup_T use_popu
 void ex_smile(exarg_T *eap);
 void ex_drop(exarg_T *eap);
 char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags);
+char_u *skip_vimgrep_pat_ext(char_u *p, char_u **s, int *flags, char_u **nulp, int *cp);
 void ex_oldfiles(exarg_T *eap);
 /* vim: set ft=c : */
index 8481ecc5955e102a7d3b18408085eae8d82a2c65..23c5cfacf67813e2370586e271b4b3a18dd4f321 100644 (file)
@@ -534,6 +534,14 @@ def Test_command_modifier_filter()
     assert_equal(execute('filter /piyo/ registers abc'), expected)
   END
   CheckDefAndScriptSuccess(lines)
+
+  # also do this compiled
+  lines =<< trim END
+      @a = 'very specific z3d37dh234 string'
+      filter z3d37dh234 registers
+      assert_match('very specific z3d37dh234 string', Screenline(&lines))
+  END
+  CheckDefAndScriptSuccess(lines)
 enddef
 
 def Test_win_command_modifiers()
index f9529abc1d2fa520325f04b5a380e5a1ff91ba5a..4dc6bd523b6048141f3217269f86737e0b6f64e3 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2955,
 /**/
     2954,
 /**/
index 0c73433d5fb9d7e4982fe6a74a60556edea64121..1256bfaac4603be0f4b894ebc252f345697a36fe 100644 (file)
@@ -8536,13 +8536,30 @@ compile_put(char_u *arg, exarg_T *eap, cctx_T *cctx)
     static char_u *
 compile_exec(char_u *line, exarg_T *eap, cctx_T *cctx)
 {
-    char_u  *p;
-    int            has_expr = FALSE;
-    char_u  *nextcmd = (char_u *)"";
+    char_u     *p;
+    int                has_expr = FALSE;
+    char_u     *nextcmd = (char_u *)"";
 
     if (cctx->ctx_skip == SKIP_YES)
        goto theend;
 
+    // If there was a prececing command modifier, drop it and include it in the
+    // EXEC command.
+    if (cctx->ctx_has_cmdmod)
+    {
+       garray_T        *instr = &cctx->ctx_instr;
+       isn_T           *isn = ((isn_T *)instr->ga_data) + instr->ga_len - 1;
+
+       if (isn->isn_type == ISN_CMDMOD)
+       {
+           vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
+                                              ->cmod_filter_regmatch.regprog);
+           vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
+           --instr->ga_len;
+           cctx->ctx_has_cmdmod = FALSE;
+       }
+    }
+
     if (eap->cmdidx >= 0 && eap->cmdidx < CMD_SIZE)
     {
        long    argt = eap->argt;