1
0
forked from aniani/vim

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.
This commit is contained in:
Bram Moolenaar
2016-08-26 22:29:11 +02:00
parent 2570957607
commit d29459baa6
8 changed files with 68 additions and 6 deletions

View File

@@ -2918,6 +2918,10 @@ print_line(linenr_T lnum, int use_number, int list)
{ {
int save_silent = silent_mode; int save_silent = silent_mode;
/* apply :filter /pat/ */
if (message_filtered(ml_get(lnum)))
return;
msg_start(); msg_start();
silent_mode = FALSE; silent_mode = FALSE;
info_message = TRUE; /* use mch_msg(), not mch_errmsg() */ info_message = TRUE; /* use mch_msg(), not mch_errmsg() */

View File

@@ -545,7 +545,7 @@ EX(CMD_filetype, "filetype", ex_filetype,
EXTRA|TRLBAR|CMDWIN, EXTRA|TRLBAR|CMDWIN,
ADDR_LINES), ADDR_LINES),
EX(CMD_filter, "filter", ex_wrongmodifier, EX(CMD_filter, "filter", ex_wrongmodifier,
NEEDARG|EXTRA|NOTRLCOM, BANG|NEEDARG|EXTRA|NOTRLCOM,
ADDR_LINES), ADDR_LINES),
EX(CMD_find, "find", ex_find, EX(CMD_find, "find", ex_find,
RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR, RANGE|NOTADR|BANG|FILE1|EDITCMD|ARGOPT|TRLBAR,

View File

@@ -1925,6 +1925,13 @@ do_one_cmd(
if (!checkforcmd(&p, "filter", 4) if (!checkforcmd(&p, "filter", 4)
|| *p == NUL || ends_excmd(*p)) || *p == NUL || ends_excmd(*p))
break; 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); p = skip_vimgrep_pat(p, &reg_pat, NULL);
if (p == NULL || *p == NUL) if (p == NULL || *p == NUL)
break; break;
@@ -5928,8 +5935,10 @@ uc_list(char_u *name, size_t name_len)
cmd = USER_CMD_GA(gap, i); cmd = USER_CMD_GA(gap, i);
a = (long)cmd->uc_argt; a = (long)cmd->uc_argt;
/* Skip commands which don't match the requested prefix */ /* Skip commands which don't match the requested prefix and
if (STRNCMP(name, cmd->uc_name, name_len) != 0) * commands filtered out. */
if (STRNCMP(name, cmd->uc_name, name_len) != 0
|| message_filtered(cmd->uc_name))
continue; continue;
/* Put out the title first time */ /* Put out the title first time */

View File

@@ -1919,7 +1919,7 @@ vungetc(int c)
* This may do a blocking wait if "advance" is TRUE. * This may do a blocking wait if "advance" is TRUE.
* *
* if "advance" is TRUE (vgetc()): * 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. * KeyTyped is set to TRUE in the case the user typed the key.
* KeyStuffed is TRUE if the character comes from the stuff buffer. * KeyStuffed is TRUE if the character comes from the stuff buffer.
* if "advance" is FALSE (vpeekc()): * if "advance" is FALSE (vpeekc()):
@@ -3987,6 +3987,9 @@ showmap(
int len = 1; int len = 1;
char_u *mapchars; char_u *mapchars;
if (message_filtered(mp->m_keys) && message_filtered(mp->m_str))
return;
if (msg_didout || msg_silent != 0) if (msg_didout || msg_silent != 0)
{ {
msg_putchar('\n'); msg_putchar('\n');

View File

@@ -2161,8 +2161,12 @@ msg_puts_display(
int int
message_filtered(char_u *msg) message_filtered(char_u *msg)
{ {
return cmdmod.filter_regmatch.regprog != NULL int match;
&& !vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0);
if (cmdmod.filter_regmatch.regprog == NULL)
return FALSE;
match = vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0);
return cmdmod.filter_force ? match : !match;
} }
/* /*

View File

@@ -572,6 +572,7 @@ typedef struct
char_u *save_ei; /* saved value of 'eventignore' */ char_u *save_ei; /* saved value of 'eventignore' */
# endif # endif
regmatch_T filter_regmatch; /* set by :filter /pat/ */ regmatch_T filter_regmatch; /* set by :filter /pat/ */
int filter_force; /* set for :filter! */
} cmdmod_T; } cmdmod_T;
#define MF_SEED_LEN 8 #define MF_SEED_LEN 8

View File

@@ -4,6 +4,39 @@ func Test_filter()
edit Xdoesnotmatch edit Xdoesnotmatch
edit Xwillmatch edit Xwillmatch
call assert_equal('"Xwillmatch"', substitute(execute('filter willma ls'), '[^"]*\(".*"\)[^"]*', '\1', '')) 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 endfunc
func Test_filter_fails() 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/', 'E476:') call assert_fails('filter /pat/', 'E476:')
call assert_fails('filter /pat/ asdf', 'E492:') 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 endfunc

View File

@@ -763,6 +763,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2263,
/**/ /**/
2262, 2262,
/**/ /**/