summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2016-08-23 23:51:21 +0200
committerBram Moolenaar <Bram@vim.org>2016-08-23 23:51:21 +0200
commit7b668e83d0635d082b7ec90d7d2aa30a9d7d8928 (patch)
tree5a766b46ad4395652cfe4d2545ee809047384fc9 /src
parent1b58cdd160c2e0ada0f638679a2aa27e4665fc48 (diff)
patch 7.4.2244v7.4.2244
Problem: Adding pattern to ":oldfiles" is not a generic solution. Solution: Add the ":filter /pat/ cmd" command modifier. Only works for some commands right now.
Diffstat (limited to 'src')
-rw-r--r--src/Makefile1
-rw-r--r--src/ex_cmds.h5
-rw-r--r--src/ex_docmd.c34
-rw-r--r--src/message.c16
-rw-r--r--src/proto/message.pro1
-rw-r--r--src/structs.h1
-rw-r--r--src/testdir/test_alot.vim1
-rw-r--r--src/testdir/test_filter_cmd.vim15
-rw-r--r--src/testdir/test_viminfo.vim6
-rw-r--r--src/version.c2
10 files changed, 77 insertions, 5 deletions
diff --git a/src/Makefile b/src/Makefile
index 690e08ab36..af0ffc08db 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2072,6 +2072,7 @@ test_arglist \
test_farsi \
test_feedkeys \
test_file_perm \
+ test_filter_cmd \
test_filter_map \
test_fnamemodify \
test_glob2regpat \
diff --git a/src/ex_cmds.h b/src/ex_cmds.h
index b6e9488ddc..81b3ff809a 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -544,6 +544,9 @@ EX(CMD_files, "files", buflist_list,
EX(CMD_filetype, "filetype", ex_filetype,
EXTRA|TRLBAR|CMDWIN,
ADDR_LINES),
+EX(CMD_filter, "filter", ex_wrongmodifier,
+ NEEDARG|EXTRA|NOTRLCOM,
+ ADDR_LINES),
EX(CMD_find, "find", ex_find,
RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR,
ADDR_LINES),
@@ -992,7 +995,7 @@ EX(CMD_open, "open", ex_open,
RANGE|BANG|EXTRA,
ADDR_LINES),
EX(CMD_oldfiles, "oldfiles", ex_oldfiles,
- BANG|TRLBAR|NOTADR|EXTRA|SBOXOK|CMDWIN,
+ BANG|TRLBAR|SBOXOK|CMDWIN,
ADDR_LINES),
EX(CMD_omap, "omap", ex_map,
EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN,
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 9f1d2279d3..94216b371e 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1781,6 +1781,7 @@ do_one_cmd(
linenr_T lnum;
long n;
char_u *errormsg = NULL; /* error message */
+ char_u *after_modifier = NULL;
exarg_T ea; /* Ex command arguments */
long verbose_save = -1;
int save_msg_scroll = msg_scroll;
@@ -1917,6 +1918,24 @@ do_one_cmd(
cmdmod.keepjumps = TRUE;
continue;
+ case 'f': /* only accept ":filter {pat} cmd" */
+ {
+ char_u *reg_pat;
+
+ if (!checkforcmd(&p, "filter", 4)
+ || *p == NUL || ends_excmd(*p))
+ break;
+ p = skip_vimgrep_pat(p, &reg_pat, NULL);
+ if (p == NULL || *p == NUL)
+ break;
+ cmdmod.filter_regmatch.regprog =
+ vim_regcomp(reg_pat, RE_MAGIC);
+ if (cmdmod.filter_regmatch.regprog == NULL)
+ break;
+ ea.cmd = p;
+ continue;
+ }
+
/* ":hide" and ":hide | cmd" are not modifiers */
case 'h': if (p != ea.cmd || !checkforcmd(&p, "hide", 3)
|| *p == NUL || ends_excmd(*p))
@@ -2041,6 +2060,7 @@ do_one_cmd(
}
break;
}
+ after_modifier = ea.cmd;
#ifdef FEAT_EVAL
ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0
@@ -2374,7 +2394,14 @@ do_one_cmd(
{
STRCPY(IObuff, _("E492: Not an editor command"));
if (!sourcing)
- append_command(*cmdlinep);
+ {
+ /* If the modifier was parsed OK the error must be in the
+ * following command */
+ if (after_modifier != NULL)
+ append_command(after_modifier);
+ else
+ append_command(*cmdlinep);
+ }
errormsg = IObuff;
did_emsg_syntax = TRUE;
}
@@ -2818,6 +2845,7 @@ do_one_cmd(
case CMD_echomsg:
case CMD_echon:
case CMD_execute:
+ case CMD_filter:
case CMD_help:
case CMD_hide:
case CMD_ijump:
@@ -2989,6 +3017,8 @@ doend:
free_string_option(cmdmod.save_ei);
}
#endif
+ if (cmdmod.filter_regmatch.regprog != NULL)
+ vim_regfree(cmdmod.filter_regmatch.regprog);
cmdmod = save_cmdmod;
@@ -3323,6 +3353,7 @@ static struct cmdmod
{"botright", 2, FALSE},
{"browse", 3, FALSE},
{"confirm", 4, FALSE},
+ {"filter", 4, FALSE},
{"hide", 3, FALSE},
{"keepalt", 5, FALSE},
{"keepjumps", 5, FALSE},
@@ -3833,6 +3864,7 @@ set_one_cmd_context(
case CMD_cfdo:
case CMD_confirm:
case CMD_debug:
+ case CMD_filter:
case CMD_folddoclosed:
case CMD_folddoopen:
case CMD_hide:
diff --git a/src/message.c b/src/message.c
index a7398f6eb0..f24bc28173 100644
--- a/src/message.c
+++ b/src/message.c
@@ -137,6 +137,11 @@ msg_attr_keep(
int retval;
char_u *buf = NULL;
+ /* Skip messages not matching ":filter pattern".
+ * Don't filter when there is an error. */
+ if (!emsg_on_display && message_filtered(s))
+ return TRUE;
+
#ifdef FEAT_EVAL
if (attr == 0)
set_vim_var_string(VV_STATUSMSG, s, -1);
@@ -2150,6 +2155,17 @@ msg_puts_display(
}
/*
+ * Return TRUE when ":filter pattern" was used and "msg" does not match
+ * "pattern".
+ */
+ int
+message_filtered(char_u *msg)
+{
+ return cmdmod.filter_regmatch.regprog != NULL
+ && !vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0);
+}
+
+/*
* Scroll the screen up one line for displaying the next message line.
*/
static void
diff --git a/src/proto/message.pro b/src/proto/message.pro
index ba8ff37c39..7112b0923f 100644
--- a/src/proto/message.pro
+++ b/src/proto/message.pro
@@ -43,6 +43,7 @@ void msg_puts_title(char_u *s);
void msg_puts_long_attr(char_u *longstr, int attr);
void msg_puts_long_len_attr(char_u *longstr, int len, int attr);
void msg_puts_attr(char_u *s, int attr);
+int message_filtered(char_u *msg);
void may_clear_sb_text(void);
void clear_sb_text(void);
void show_sb_text(void);
diff --git a/src/structs.h b/src/structs.h
index f91844277f..1dfe13129f 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -571,6 +571,7 @@ typedef struct
# ifdef FEAT_AUTOCMD
char_u *save_ei; /* saved value of 'eventignore' */
# endif
+ regmatch_T filter_regmatch; /* set by :filter /pat/ */
} cmdmod_T;
#define MF_SEED_LEN 8
diff --git a/src/testdir/test_alot.vim b/src/testdir/test_alot.vim
index b89d4b0db4..f8804e0c07 100644
--- a/src/testdir/test_alot.vim
+++ b/src/testdir/test_alot.vim
@@ -13,6 +13,7 @@ source test_expand_dllpath.vim
source test_feedkeys.vim
source test_fnamemodify.vim
source test_file_perm.vim
+source test_filter_cmd.vim
source test_filter_map.vim
source test_glob2regpat.vim
source test_goto.vim
diff --git a/src/testdir/test_filter_cmd.vim b/src/testdir/test_filter_cmd.vim
new file mode 100644
index 0000000000..f85a11ce45
--- /dev/null
+++ b/src/testdir/test_filter_cmd.vim
@@ -0,0 +1,15 @@
+" Test the :filter command modifier
+
+func Test_filter()
+ edit Xdoesnotmatch
+ edit Xwillmatch
+ call assert_equal('"Xwillmatch"', substitute(execute('filter willma ls'), '[^"]*\(".*"\)[^"]*', '\1', ''))
+endfunc
+
+func Test_filter_fails()
+ call assert_fails('filter', 'E471:')
+ call assert_fails('filter pat', 'E476:')
+ call assert_fails('filter /pat', 'E476:')
+ call assert_fails('filter /pat/', 'E476:')
+ call assert_fails('filter /pat/ asdf', 'E492:')
+endfunc
diff --git a/src/testdir/test_viminfo.vim b/src/testdir/test_viminfo.vim
index d4ec6f78f7..264baa1745 100644
--- a/src/testdir/test_viminfo.vim
+++ b/src/testdir/test_viminfo.vim
@@ -476,7 +476,7 @@ func Test_oldfiles()
rviminfo! Xviminfo
call delete('Xviminfo')
- call assert_equal(['1: /tmp/file_one.txt', '2: /tmp/file_two.txt', '3: /tmp/another.txt'], filter(split(execute('oldfile'), "\n"), {i, v -> v =~ '/tmp/'}))
- call assert_equal(['1: /tmp/file_one.txt', '2: /tmp/file_two.txt'], filter(split(execute('oldfile file_'), "\n"), {i, v -> v =~ '/tmp/'}))
- call assert_equal(['3: /tmp/another.txt'], filter(split(execute('oldfile /another/'), "\n"), {i, v -> v =~ '/tmp/'}))
+ call assert_equal(['1: /tmp/file_one.txt', '2: /tmp/file_two.txt', '3: /tmp/another.txt'], filter(split(execute('oldfiles'), "\n"), {i, v -> v =~ '/tmp/'}))
+ call assert_equal(['1: /tmp/file_one.txt', '2: /tmp/file_two.txt'], filter(split(execute('filter file_ oldfiles'), "\n"), {i, v -> v =~ '/tmp/'}))
+ call assert_equal(['3: /tmp/another.txt'], filter(split(execute('filter /another/ oldfiles'), "\n"), {i, v -> v =~ '/tmp/'}))
endfunc
diff --git a/src/version.c b/src/version.c
index 644cd6b6ab..0e172198e8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -764,6 +764,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2244,
+/**/
2243,
/**/
2242,