changeset 9980:b222552cf0c4 v7.4.2263

commit https://github.com/vim/vim/commit/d29459baa61819e59961804ed258efac5733ec70 Author: Bram Moolenaar <Bram@vim.org> Date: Fri Aug 26 22:29:11 2016 +0200 patch 7.4.2263 Problem: :filter does not work for many commands. Can only get matching messages. Solution: Make :filter work for :command, :map, :list, :number and :print. Make ":filter!" show non-matching lines.
author Christian Brabandt <cb@256bit.org>
date Fri, 26 Aug 2016 22:30:07 +0200
parents 782064bf4bc1
children 9137289034e5
files src/ex_cmds.c src/ex_cmds.h src/ex_docmd.c src/getchar.c src/message.c src/structs.h src/testdir/test_filter_cmd.vim src/version.c
diffstat 8 files changed, 68 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -2918,6 +2918,10 @@ print_line(linenr_T lnum, int use_number
 {
     int		save_silent = silent_mode;
 
+    /* apply :filter /pat/ */
+    if (message_filtered(ml_get(lnum)))
+	return;
+
     msg_start();
     silent_mode = FALSE;
     info_message = TRUE;	/* use mch_msg(), not mch_errmsg() */
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -545,7 +545,7 @@ EX(CMD_filetype,	"filetype",	ex_filetype
 			EXTRA|TRLBAR|CMDWIN,
 			ADDR_LINES),
 EX(CMD_filter,		"filter",	ex_wrongmodifier,
-			NEEDARG|EXTRA|NOTRLCOM,
+			BANG|NEEDARG|EXTRA|NOTRLCOM,
 			ADDR_LINES),
 EX(CMD_find,		"find",		ex_find,
 			RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR,
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1925,6 +1925,13 @@ do_one_cmd(
 			    if (!checkforcmd(&p, "filter", 4)
 						|| *p == NUL || ends_excmd(*p))
 				break;
+			    if (*p == '!')
+			    {
+				cmdmod.filter_force = TRUE;
+				p = skipwhite(p + 1);
+				if (*p == NUL || ends_excmd(*p))
+				    break;
+			    }
 			    p = skip_vimgrep_pat(p, &reg_pat, NULL);
 			    if (p == NULL || *p == NUL)
 				break;
@@ -5928,8 +5935,10 @@ uc_list(char_u *name, size_t name_len)
 	    cmd = USER_CMD_GA(gap, i);
 	    a = (long)cmd->uc_argt;
 
-	    /* Skip commands which don't match the requested prefix */
-	    if (STRNCMP(name, cmd->uc_name, name_len) != 0)
+	    /* Skip commands which don't match the requested prefix and
+	     * commands filtered out. */
+	    if (STRNCMP(name, cmd->uc_name, name_len) != 0
+		    || message_filtered(cmd->uc_name))
 		continue;
 
 	    /* Put out the title first time */
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1919,7 +1919,7 @@ vungetc(int c)
  *	This may do a blocking wait if "advance" is TRUE.
  *
  * if "advance" is TRUE (vgetc()):
- *	really get the character.
+ *	Really get the character.
  *	KeyTyped is set to TRUE in the case the user typed the key.
  *	KeyStuffed is TRUE if the character comes from the stuff buffer.
  * if "advance" is FALSE (vpeekc()):
@@ -3987,6 +3987,9 @@ showmap(
     int		len = 1;
     char_u	*mapchars;
 
+    if (message_filtered(mp->m_keys) && message_filtered(mp->m_str))
+	return;
+
     if (msg_didout || msg_silent != 0)
     {
 	msg_putchar('\n');
--- a/src/message.c
+++ b/src/message.c
@@ -2161,8 +2161,12 @@ msg_puts_display(
     int
 message_filtered(char_u *msg)
 {
-    return cmdmod.filter_regmatch.regprog != NULL
-		     && !vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0);
+    int match;
+
+    if (cmdmod.filter_regmatch.regprog == NULL)
+	return FALSE;
+    match = vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0);
+    return cmdmod.filter_force ? match : !match;
 }
 
 /*
--- a/src/structs.h
+++ b/src/structs.h
@@ -572,6 +572,7 @@ typedef struct
     char_u	*save_ei;		/* saved value of 'eventignore' */
 # endif
     regmatch_T	filter_regmatch;	/* set by :filter /pat/ */
+    int		filter_force;		/* set for :filter! */
 } cmdmod_T;
 
 #define MF_SEED_LEN	8
--- a/src/testdir/test_filter_cmd.vim
+++ b/src/testdir/test_filter_cmd.vim
@@ -4,6 +4,39 @@ func Test_filter()
   edit Xdoesnotmatch
   edit Xwillmatch
   call assert_equal('"Xwillmatch"', substitute(execute('filter willma ls'), '[^"]*\(".*"\)[^"]*', '\1', ''))
+  bwipe Xdoesnotmatch
+  bwipe Xwillmatch
+
+  new
+  call setline(1, ['foo1', 'foo2', 'foo3', 'foo4', 'foo5'])
+  call assert_equal("\nfoo2\nfoo4", execute('filter /foo[24]/ 1,$print'))
+  call assert_equal("\n  2 foo2\n  4 foo4", execute('filter /foo[24]/ 1,$number'))
+  call assert_equal("\nfoo2$\nfoo4$", execute('filter /foo[24]/ 1,$list'))
+
+  call assert_equal("\nfoo1$\nfoo3$\nfoo5$", execute('filter! /foo[24]/ 1,$list'))
+  bwipe!
+
+  command XTryThis echo 'this'
+  command XTryThat echo 'that'
+  command XDoThat echo 'that'
+  let lines = split(execute('filter XTry command'), "\n")
+  call assert_equal(3, len(lines))
+  call assert_match("XTryThat", lines[1])
+  call assert_match("XTryThis", lines[2])
+  delcommand XTryThis
+  delcommand XTryThat
+  delcommand XDoThat
+
+  map f1 the first key
+  map f2 the second key
+  map f3 not a key
+  let lines = split(execute('filter the map f'), "\n")
+  call assert_equal(2, len(lines))
+  call assert_match("f2", lines[0])
+  call assert_match("f1", lines[1])
+  unmap f1
+  unmap f2
+  unmap f3
 endfunc
 
 func Test_filter_fails()
@@ -12,4 +45,10 @@ func Test_filter_fails()
   call assert_fails('filter /pat', 'E476:')
   call assert_fails('filter /pat/', 'E476:')
   call assert_fails('filter /pat/ asdf', 'E492:')
+
+  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
--- 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 */
 /**/
+    2263,
+/**/
     2262,
 /**/
     2261,