To: vim_dev@googlegroups.com Subject: Patch 7.4.2244 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ 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. Files: src/structs.h, src/ex_docmd.c, src/ex_cmds.h, src/message.c, src/proto/message.pro, runtime/doc/starting.txt, runtime/doc/various.txt, src/testdir/test_viminfo.vim, src/testdir/test_alot.vim, src/testdir/test_filter_cmd.vim, src/Makefile *** ../vim-7.4.2243/src/structs.h 2016-08-22 23:04:29.206161702 +0200 --- src/structs.h 2016-08-23 22:01:52.378554550 +0200 *************** *** 571,576 **** --- 571,577 ---- # 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 *** ../vim-7.4.2243/src/ex_docmd.c 2016-08-21 19:07:14.261008144 +0200 --- src/ex_docmd.c 2016-08-23 22:33:12.762029931 +0200 *************** *** 1781,1786 **** --- 1781,1787 ---- 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,1922 **** --- 1918,1941 ---- 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, ®_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,2046 **** --- 2060,2066 ---- } break; } + after_modifier = ea.cmd; #ifdef FEAT_EVAL ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0 *************** *** 2374,2380 **** { STRCPY(IObuff, _("E492: Not an editor command")); if (!sourcing) ! append_command(*cmdlinep); errormsg = IObuff; did_emsg_syntax = TRUE; } --- 2394,2407 ---- { STRCPY(IObuff, _("E492: Not an editor command")); if (!sourcing) ! { ! /* 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,2823 **** --- 2845,2851 ---- case CMD_echomsg: case CMD_echon: case CMD_execute: + case CMD_filter: case CMD_help: case CMD_hide: case CMD_ijump: *************** *** 2989,2994 **** --- 3017,3024 ---- free_string_option(cmdmod.save_ei); } #endif + if (cmdmod.filter_regmatch.regprog != NULL) + vim_regfree(cmdmod.filter_regmatch.regprog); cmdmod = save_cmdmod; *************** *** 3323,3328 **** --- 3353,3359 ---- {"botright", 2, FALSE}, {"browse", 3, FALSE}, {"confirm", 4, FALSE}, + {"filter", 4, FALSE}, {"hide", 3, FALSE}, {"keepalt", 5, FALSE}, {"keepjumps", 5, FALSE}, *************** *** 3833,3838 **** --- 3864,3870 ---- case CMD_cfdo: case CMD_confirm: case CMD_debug: + case CMD_filter: case CMD_folddoclosed: case CMD_folddoopen: case CMD_hide: *** ../vim-7.4.2243/src/ex_cmds.h 2016-08-20 18:36:48.296969153 +0200 --- src/ex_cmds.h 2016-08-23 22:52:33.835678370 +0200 *************** *** 544,549 **** --- 544,552 ---- 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,998 **** RANGE|BANG|EXTRA, ADDR_LINES), EX(CMD_oldfiles, "oldfiles", ex_oldfiles, ! BANG|TRLBAR|NOTADR|EXTRA|SBOXOK|CMDWIN, ADDR_LINES), EX(CMD_omap, "omap", ex_map, EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN, --- 995,1001 ---- RANGE|BANG|EXTRA, ADDR_LINES), EX(CMD_oldfiles, "oldfiles", ex_oldfiles, ! BANG|TRLBAR|SBOXOK|CMDWIN, ADDR_LINES), EX(CMD_omap, "omap", ex_map, EXTRA|TRLBAR|NOTRLCOM|USECTRLV|CMDWIN, *** ../vim-7.4.2243/src/message.c 2016-08-16 21:58:36.726878365 +0200 --- src/message.c 2016-08-23 23:39:55.077845915 +0200 *************** *** 137,142 **** --- 137,147 ---- 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,2155 **** --- 2155,2171 ---- } /* + * 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 *** ../vim-7.4.2243/src/proto/message.pro 2016-08-10 20:53:01.679116172 +0200 --- src/proto/message.pro 2016-08-23 22:55:25.546141638 +0200 *************** *** 43,48 **** --- 43,49 ---- 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); *** ../vim-7.4.2243/runtime/doc/starting.txt 2016-08-20 18:36:48.296969153 +0200 --- runtime/doc/starting.txt 2016-08-23 23:13:27.296449466 +0200 *************** *** 1563,1580 **** file. This list is read on startup and only changes 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 --- 1631,1642 ---- file. This list is read on startup and only changes afterwards with `:rviminfo!`. Also see |v:oldfiles|. The number can be used with |c_#<|. + The output can be filtered with |:filter|, e.g.: > + filter /\\.vim/ oldfiles + < The filtering happens on the file name. {not in Vi, only when compiled with the |+eval| feature} :bro[wse] ol[dfiles][!] List file names as with |:oldfiles|, and then prompt for a number. When the number is valid that file from *** ../vim-7.4.2243/runtime/doc/various.txt 2016-07-01 18:16:47.481936426 +0200 --- runtime/doc/various.txt 2016-08-23 23:21:54.391667974 +0200 *************** *** 500,512 **** redirection starts, if the variable is removed or locked or the variable type is changed, then further command output messages will cause errors. {not in Vi} :redi[r] =>> {var} Append messages to an existing variable. Only string variables can be used. {not in Vi} :redi[r] END End redirecting messages. {not in Vi} ! *:sil* *:silent* :sil[ent][!] {command} Execute {command} silently. Normal messages will not be given or added to the message history. When [!] is added, error messages will also be --- 516,549 ---- redirection starts, if the variable is removed or locked or the variable type is changed, then further command output messages will cause errors. {not in Vi} + To get the output of one command the |execute()| + function can be used. :redi[r] =>> {var} Append messages to an existing variable. Only string variables can be used. {not in Vi} :redi[r] END End redirecting messages. {not in Vi} ! *:filt* *:filter* ! :filt[er] {pat} {command} ! :filt[er] /{pat}/ {command} ! Restrict the output of {command} to matches with {pat}. ! ! {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. ! ! The pattern is matched against the relevant part of ! the output, not necessarily the whole line. Only some ! commands support filtering, try it out to check if it ! works. ! ! Only normal messages are filtered, error messages are ! not. ! ! *:sil* *:silent* *:silent!* :sil[ent][!] {command} Execute {command} silently. Normal messages will not be given or added to the message history. When [!] is added, error messages will also be *** ../vim-7.4.2243/src/testdir/test_viminfo.vim 2016-08-20 18:36:48.308969048 +0200 --- src/testdir/test_viminfo.vim 2016-08-23 22:56:34.645523554 +0200 *************** *** 476,482 **** 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 --- 476,482 ---- 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('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 *** ../vim-7.4.2243/src/testdir/test_alot.vim 2016-08-20 16:56:48.254624304 +0200 --- src/testdir/test_alot.vim 2016-08-23 23:26:21.653224287 +0200 *************** *** 13,18 **** --- 13,19 ---- 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 *** ../vim-7.4.2243/src/testdir/test_filter_cmd.vim 2016-08-23 23:31:32.510403543 +0200 --- src/testdir/test_filter_cmd.vim 2016-08-23 23:45:44.730683338 +0200 *************** *** 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 *** ../vim-7.4.2243/src/Makefile 2016-08-20 16:56:48.254624304 +0200 --- src/Makefile 2016-08-23 23:26:55.476917275 +0200 *************** *** 2072,2077 **** --- 2082,2088 ---- test_farsi \ test_feedkeys \ test_file_perm \ + test_filter_cmd \ test_filter_map \ test_fnamemodify \ test_glob2regpat \ *** ../vim-7.4.2243/src/version.c 2016-08-22 23:04:29.222161560 +0200 --- src/version.c 2016-08-23 23:19:12.481191890 +0200 *************** *** 765,766 **** --- 765,768 ---- { /* Add new patch number below this line */ + /**/ + 2244, /**/ -- Over the years, I've developed my sense of deja vu so acutely that now I can remember things that *have* happened before ... /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///