patch 7.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.
diff --git a/src/Makefile b/src/Makefile
index 690e08a..af0ffc0 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -2072,6 +2072,7 @@
 	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 b6e9488..81b3ff8 100644
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -544,6 +544,9 @@
 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 @@
 			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 9f1d227..94216b3 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1781,6 +1781,7 @@
     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 @@
 			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 @@
 	}
 	break;
     }
+    after_modifier = ea.cmd;
 
 #ifdef FEAT_EVAL
     ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0
@@ -2374,7 +2394,14 @@
 	{
 	    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 @@
 	    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 @@
 	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 @@
     {"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 @@
 	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 a7398f6..f24bc28 100644
--- a/src/message.c
+++ b/src/message.c
@@ -137,6 +137,11 @@
     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 @@
 }
 
 /*
+ * 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 ba8ff37..7112b09 100644
--- a/src/proto/message.pro
+++ b/src/proto/message.pro
@@ -43,6 +43,7 @@
 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 f918442..1dfe131 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -571,6 +571,7 @@
 # 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 b89d4b0..f8804e0 100644
--- a/src/testdir/test_alot.vim
+++ b/src/testdir/test_alot.vim
@@ -13,6 +13,7 @@
 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 0000000..f85a11c
--- /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 d4ec6f7..264baa1 100644
--- a/src/testdir/test_viminfo.vim
+++ b/src/testdir/test_viminfo.vim
@@ -476,7 +476,7 @@
   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 644cd6b..0e17219 100644
--- a/src/version.c
+++ b/src/version.c
@@ -764,6 +764,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    2244,
+/**/
     2243,
 /**/
     2242,