summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-06-06 21:38:09 +0200
committerBram Moolenaar <Bram@vim.org>2021-06-06 21:38:09 +0200
commite729ce294f9756165020ad86e3b98b4112e1a6ab (patch)
tree9bfd11d59b2a6e1592dc7ee8dc8a7f4d943631ac
parent6db7b6375a3ea3afef5295b1366896902012e640 (diff)
patch 8.2.2955: Vim9: using filter in compiled command does not workv8.2.2955
Problem: Vim9: using filter in compiled command does not work. Solution: Generate EXEC including the command modifier.
-rw-r--r--src/ex_cmds.c24
-rw-r--r--src/ex_docmd.c10
-rw-r--r--src/proto/ex_cmds.pro1
-rw-r--r--src/testdir/test_vim9_cmd.vim8
-rw-r--r--src/version.c2
-rw-r--r--src/vim9compile.c23
6 files changed, 63 insertions, 5 deletions
diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index e1497a5a4a..614d41d69f 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -5278,6 +5278,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;
if (vim_isIDc(*p))
@@ -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
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index fbf2c7d0dd..4aaccb593f 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -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;
diff --git a/src/proto/ex_cmds.pro b/src/proto/ex_cmds.pro
index 1711af4537..c083cec5cc 100644
--- a/src/proto/ex_cmds.pro
+++ b/src/proto/ex_cmds.pro
@@ -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 : */
diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index 8481ecc595..23c5cfacf6 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -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()
diff --git a/src/version.c b/src/version.c
index f9529abc1d..4dc6bd523b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2955,
+/**/
2954,
/**/
2953,
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 0c73433d5f..1256bfaac4 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -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;