changeset 9915:4da1a3879100 v7.4.2231

commit https://github.com/vim/vim/commit/e11d61a3b1cdedf3144de697a2b38af62c3a78d8 Author: Bram Moolenaar <Bram@vim.org> Date: Sat Aug 20 18:36:54 2016 +0200 patch 7.4.2231 Problem: ":oldfiles" output is a very long list. Solution: Add a pattern argument. (Coot, closes https://github.com/vim/vim/issues/575)
author Christian Brabandt <cb@256bit.org>
date Sat, 20 Aug 2016 18:45:05 +0200
parents a0884512c300
children 039792bc5800
files runtime/doc/starting.txt src/eval.c src/ex_cmds.c src/ex_cmds.h src/proto/eval.pro src/proto/ex_cmds.pro src/testdir/test_viminfo.vim src/version.c
diffstat 8 files changed, 120 insertions(+), 57 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/starting.txt
+++ b/runtime/doc/starting.txt
@@ -1611,11 +1611,20 @@ most of the information will be restored
 						*:ol* *:oldfiles*
 :ol[dfiles]		List the files that have marks stored in the viminfo
 			file.  This list is read on startup and only changes
-			afterwards with ":rviminfo!".  Also see |v:oldfiles|.
+			afterwards with `:rviminfo!`.  Also see |v:oldfiles|.
 			The number can be used with |c_#<|.
 			{not in Vi, only when compiled with the |+eval|
 			feature}
 
+:ol[dfiles] {pat}
+:ol[dfiles] /{pat}/
+			Like `:oldfiles` but only files matching {pat} will
+			be included.  {pat} is a Vim search pattern.  Instead
+			of enclosing it in / any non-ID character (see
+			|'isident'|) can be used, so long as it does not
+			appear in {pat}.  Without the enclosing character the
+			pattern cannot include the bar character.
+
 :bro[wse] ol[dfiles][!]
 			List file names as with |:oldfiles|, and then prompt
 			for a number.  When the number is valid that file from
--- a/src/eval.c
+++ b/src/eval.c
@@ -8929,60 +8929,6 @@ last_set_msg(scid_T scriptID)
     }
 }
 
-/*
- * List v:oldfiles in a nice way.
- */
-    void
-ex_oldfiles(exarg_T *eap UNUSED)
-{
-    list_T	*l = vimvars[VV_OLDFILES].vv_list;
-    listitem_T	*li;
-    int		nr = 0;
-
-    if (l == NULL)
-	msg((char_u *)_("No old files"));
-    else
-    {
-	msg_start();
-	msg_scroll = TRUE;
-	for (li = l->lv_first; li != NULL && !got_int; li = li->li_next)
-	{
-	    msg_outnum((long)++nr);
-	    MSG_PUTS(": ");
-	    msg_outtrans(get_tv_string(&li->li_tv));
-	    msg_putchar('\n');
-	    out_flush();	    /* output one line at a time */
-	    ui_breakcheck();
-	}
-	/* Assume "got_int" was set to truncate the listing. */
-	got_int = FALSE;
-
-#ifdef FEAT_BROWSE_CMD
-	if (cmdmod.browse)
-	{
-	    quit_more = FALSE;
-	    nr = prompt_for_number(FALSE);
-	    msg_starthere();
-	    if (nr > 0)
-	    {
-		char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES),
-								    (long)nr);
-
-		if (p != NULL)
-		{
-		    p = expand_env_save(p);
-		    eap->arg = p;
-		    eap->cmdidx = CMD_edit;
-		    cmdmod.browse = FALSE;
-		    do_exedit(eap, NULL);
-		    vim_free(p);
-		}
-	    }
-	}
-#endif
-    }
-}
-
 /* reset v:option_new, v:option_old and v:option_type */
     void
 reset_v_option_vars(void)
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -8391,3 +8391,84 @@ ex_drop(exarg_T *eap)
     }
 }
 #endif
+
+#if defined(FEAT_EVAL) || defined(PROTO)
+/*
+ * List v:oldfiles in a nice way.
+ */
+    void
+ex_oldfiles(exarg_T *eap UNUSED)
+{
+    list_T	*l = get_vim_var_list(VV_OLDFILES);
+    listitem_T	*li;
+    int		nr = 0;
+    char_u	*reg_pat = NULL;
+    char_u	*fname;
+    regmatch_T	regmatch;
+
+    if (l == NULL)
+	msg((char_u *)_("No old files"));
+    else
+    {
+	if (*eap->arg != NUL)
+	{
+	    if (skip_vimgrep_pat(eap->arg, &reg_pat, NULL) == NULL)
+	    {
+		EMSG(_(e_invalpat));
+		return;
+	    }
+	    regmatch.regprog = vim_regcomp(reg_pat, p_magic ? RE_MAGIC : 0);
+	    if (regmatch.regprog == NULL)
+		return;
+	}
+
+	msg_start();
+	msg_scroll = TRUE;
+	for (li = l->lv_first; li != NULL && !got_int; li = li->li_next)
+	{
+	    ++nr;
+	    fname = get_tv_string(&li->li_tv);
+	    if (reg_pat == NULL || *reg_pat == NUL
+				  || vim_regexec(&regmatch, fname, (colnr_T)0))
+	    {
+		msg_outnum((long)nr);
+		MSG_PUTS(": ");
+		msg_outtrans(fname);
+		msg_putchar('\n');
+		out_flush();	    /* output one line at a time */
+		ui_breakcheck();
+	    }
+	}
+	if (*eap->arg != NUL)
+	    vim_regfree(regmatch.regprog);
+
+	/* Assume "got_int" was set to truncate the listing. */
+	got_int = FALSE;
+
+# ifdef FEAT_BROWSE_CMD
+	if (cmdmod.browse)
+	{
+	    quit_more = FALSE;
+	    nr = prompt_for_number(FALSE);
+	    msg_starthere();
+	    if (nr > 0)
+	    {
+		char_u *p = list_find_str(get_vim_var_list(VV_OLDFILES),
+								    (long)nr);
+
+		if (p != NULL)
+		{
+		    p = expand_env_save(p);
+		    eap->arg = p;
+		    eap->cmdidx = CMD_edit;
+		    cmdmod.browse = FALSE;
+		    do_exedit(eap, NULL);
+		    vim_free(p);
+		}
+	    }
+	}
+# endif
+    }
+}
+#endif
+
--- a/src/ex_cmds.h
+++ b/src/ex_cmds.h
@@ -992,7 +992,7 @@ EX(CMD_open,		"open",		ex_open,
 			RANGE|BANG|EXTRA,
 			ADDR_LINES),
 EX(CMD_oldfiles,	"oldfiles",	ex_oldfiles,
-			BANG|TRLBAR|SBOXOK|CMDWIN,
+			BANG|TRLBAR|NOTADR|EXTRA|SBOXOK|CMDWIN,
 			ADDR_LINES),
 EX(CMD_omap,		"omap",		ex_map,
 			EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN,
--- a/src/proto/eval.pro
+++ b/src/proto/eval.pro
@@ -117,7 +117,6 @@ int read_viminfo_varlist(vir_T *virp, in
 void write_viminfo_varlist(FILE *fp);
 int store_session_globals(FILE *fd);
 void last_set_msg(scid_T scriptID);
-void ex_oldfiles(exarg_T *eap);
 void reset_v_option_vars(void);
 void prepare_assert_error(garray_T *gap);
 void assert_error(garray_T *gap);
--- a/src/proto/ex_cmds.pro
+++ b/src/proto/ex_cmds.pro
@@ -65,4 +65,5 @@ char_u *get_sign_name(expand_T *xp, int 
 void set_context_in_sign_cmd(expand_T *xp, char_u *arg);
 void ex_smile(exarg_T *eap);
 void ex_drop(exarg_T *eap);
+void ex_oldfiles(exarg_T *eap);
 /* vim: set ft=c : */
--- a/src/testdir/test_viminfo.vim
+++ b/src/testdir/test_viminfo.vim
@@ -455,3 +455,28 @@ func Test_viminfo_file_mark_tabclose()
   call delete('Xviminfo')
   silent! bwipe Xtestfileintab
 endfunc
+
+func Test_oldfiles()
+  let v:oldfiles = []
+  let lines = [
+	\ '# comment line',
+	\ '*encoding=utf-8',
+	\ '',
+	\ "> /tmp/file_one.txt",
+	\ "\t\"\t11\t0",
+	\ "",
+	\ "> /tmp/file_two.txt",
+	\ "\t\"\t11\t0",
+	\ "",
+	\ "> /tmp/another.txt",
+	\ "\t\"\t11\t0",
+	\ "",
+	\ ]
+  call writefile(lines, 'Xviminfo')
+  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/'}))
+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 */
 /**/
+    2231,
+/**/
     2230,
 /**/
     2229,