# HG changeset patch # User Christian Brabandt # Date 1471711505 -7200 # Node ID 4da1a38791009aabc577a156a1383a850186f5f7 # Parent a0884512c30076475df2343bb03edebe6d412214 commit https://github.com/vim/vim/commit/e11d61a3b1cdedf3144de697a2b38af62c3a78d8 Author: Bram Moolenaar 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) diff --git a/runtime/doc/starting.txt b/runtime/doc/starting.txt --- 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 diff --git a/src/eval.c b/src/eval.c --- 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) diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- 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, ®_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(®match, 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 + diff --git a/src/ex_cmds.h b/src/ex_cmds.h --- 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, diff --git a/src/proto/eval.pro b/src/proto/eval.pro --- 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); diff --git a/src/proto/ex_cmds.pro b/src/proto/ex_cmds.pro --- 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 : */ diff --git a/src/testdir/test_viminfo.vim b/src/testdir/test_viminfo.vim --- 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 diff --git a/src/version.c b/src/version.c --- 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,