From dbdc2d40bb7a950e294c6e50906f546707ccf390 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Fri, 28 Apr 2017 21:04:17 -0400 Subject: vim-patch:7.4.2231 Problem: ":oldfiles" output is a very long list. Solution: Add a pattern argument. (Coot, closes vim/vim#575) https://github.com/vim/vim/commit/e11d61a3b1cdedf3144de697a2b38af62c3a78d8 --- src/nvim/eval.c | 46 ----------------------------------- src/nvim/ex_cmds.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/nvim/ex_cmds.lua | 2 +- src/nvim/version.c | 2 +- 4 files changed, 70 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/nvim/eval.c b/src/nvim/eval.c index b0f47d8e45..1bf85ccd8b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -21779,52 +21779,6 @@ void last_set_msg(scid_T scriptID) } } -/* - * List v:oldfiles in a nice way. - */ -void ex_oldfiles(exarg_T *eap) -{ - list_T *l = get_vim_var_list(VV_OLDFILES); - listitem_T *li; - long 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(++nr); - MSG_PUTS(": "); - msg_outtrans((char_u *)tv_get_string(&li->li_tv)); - msg_clr_eos(); - msg_putchar('\n'); - ui_flush(); /* output one line at a time */ - os_breakcheck(); - } - /* Assume "got_int" was set to truncate the listing. */ - got_int = FALSE; - - // File selection prompt on ":browse oldfiles" - if (cmdmod.browse) { - quit_more = false; - nr = prompt_for_number(false); - msg_starthere(); - if (nr > 0 && nr <= l->lv_len) { - const char *const p = tv_list_find_str(l, nr - 1); - if (p == NULL) { - return; - } - char *const s = (char *)expand_env_save((char_u *)p); - eap->arg = (char_u *)s; - eap->cmdidx = CMD_edit; - do_exedit(eap, NULL); - xfree(s); - } - } - } -} - // reset v:option_new, v:option_old and v:option_type void reset_v_option_vars(void) { diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 7726e0fc6d..ab85bb766f 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -6158,3 +6158,71 @@ void ex_substitute(exarg_T *eap) ga_clear(&save_view); unblock_autocmds(); } + +/// List v:oldfiles in a nice way. +void ex_oldfiles(exarg_T *eap) +{ + list_T *l = get_vim_var_list(VV_OLDFILES); + listitem_T *li; + long nr = 0; + + if (l == NULL) { + msg((char_u *)_("No old files")); + } else { + char_u *reg_pat = NULL; + regmatch_T regmatch; + + 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++; + const char *fname = tv_get_string(&li->li_tv); + if (reg_pat == NULL || *reg_pat == NUL + || vim_regexec(®match, (char_u *)fname, (colnr_T)0)) { + msg_outnum(nr); + MSG_PUTS(": "); + msg_outtrans((char_u *)tv_get_string(&li->li_tv)); + msg_clr_eos(); + msg_putchar('\n'); + ui_flush(); // output one line at a time + os_breakcheck(); + } + } + if (*eap->arg != NUL) { + vim_regfree(regmatch.regprog); + } + + /* Assume "got_int" was set to truncate the listing. */ + got_int = FALSE; + + // File selection prompt on ":browse oldfiles" + if (cmdmod.browse) { + quit_more = false; + nr = prompt_for_number(false); + msg_starthere(); + if (nr > 0 && nr <= l->lv_len) { + const char *const p = tv_list_find_str(l, nr - 1); + if (p == NULL) { + return; + } + char *const s = (char *)expand_env_save((char_u *)p); + eap->arg = (char_u *)s; + eap->cmdidx = CMD_edit; + cmdmod.browse = false; + do_exedit(eap, NULL); + xfree(s); + } + } + } +} diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 92f0669422..844d46ab26 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -1810,7 +1810,7 @@ return { }, { command='oldfiles', - flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN), + flags=bit.bor(BANG, TRLBAR, NOTADR, EXTRA, SBOXOK, CMDWIN), addr_type=ADDR_LINES, func='ex_oldfiles', }, diff --git a/src/nvim/version.c b/src/nvim/version.c index b1aa8e2a4b..b3ab5d0d2c 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -213,7 +213,7 @@ static const int included_patches[] = { // 2234 NA 2233, // 2232 NA - // 2231, + 2231, 2230, // 2229, 2228, -- cgit From 059c3fc2f952b42824ca37610c040c938a75de5c Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 29 Apr 2017 07:55:15 -0400 Subject: vim-patch:7.4.2239 Problem: Warning for missing declaration of skip_vimgrep_pat(). (John Marriott) Solution: Move it to another file. https://github.com/vim/vim/commit/9baf297c99cc35adb921bee04369499d76438889 --- src/nvim/ex_cmds.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/nvim/quickfix.c | 46 ---------------------------------------------- src/nvim/version.c | 2 +- 3 files changed, 45 insertions(+), 47 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index ab85bb766f..95cbcbbcb9 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -6159,6 +6159,50 @@ void ex_substitute(exarg_T *eap) unblock_autocmds(); } +/// Skip over the pattern argument of ":vimgrep /pat/[g][j]". +/// Put the start of the pattern in "*s", unless "s" is NULL. +/// If "flags" is not NULL put the flags in it: VGR_GLOBAL, VGR_NOJUMP. +/// If "s" is not NULL terminate the pattern with a NUL. +/// Return a pointer to the char just past the pattern plus flags. +char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags) +{ + int c; + + if (vim_isIDc(*p)) { + // ":vimgrep pattern fname" + if (s != NULL) + *s = p; + p = skiptowhite(p); + if (s != NULL && *p != NUL) + *p++ = NUL; + } else { + // ":vimgrep /pattern/[g][j] fname" + if (s != NULL) + *s = p + 1; + c = *p; + p = skip_regexp(p + 1, c, TRUE, NULL); + if (*p != c) + return NULL; + + // Truncate the pattern. + if (s != NULL) + *p = NUL; + ++p; + + // Find the flags + while (*p == 'g' || *p == 'j') { + if (flags != NULL) { + if (*p == 'g') + *flags |= VGR_GLOBAL; + else + *flags |= VGR_NOJUMP; + } + ++p; + } + } + return p; +} + /// List v:oldfiles in a nice way. void ex_oldfiles(exarg_T *eap) { diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c index 112498ae20..0ec0d5df9d 100644 --- a/src/nvim/quickfix.c +++ b/src/nvim/quickfix.c @@ -3765,52 +3765,6 @@ theend: vim_regfree(regmatch.regprog); } -/* - * Skip over the pattern argument of ":vimgrep /pat/[g][j]". - * Put the start of the pattern in "*s", unless "s" is NULL. - * If "flags" is not NULL put the flags in it: VGR_GLOBAL, VGR_NOJUMP. - * If "s" is not NULL terminate the pattern with a NUL. - * Return a pointer to the char just past the pattern plus flags. - */ -char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags) -{ - int c; - - if (vim_isIDc(*p)) { - /* ":vimgrep pattern fname" */ - if (s != NULL) - *s = p; - p = skiptowhite(p); - if (s != NULL && *p != NUL) - *p++ = NUL; - } else { - /* ":vimgrep /pattern/[g][j] fname" */ - if (s != NULL) - *s = p + 1; - c = *p; - p = skip_regexp(p + 1, c, TRUE, NULL); - if (*p != c) - return NULL; - - /* Truncate the pattern. */ - if (s != NULL) - *p = NUL; - ++p; - - /* Find the flags */ - while (*p == 'g' || *p == 'j') { - if (flags != NULL) { - if (*p == 'g') - *flags |= VGR_GLOBAL; - else - *flags |= VGR_NOJUMP; - } - ++p; - } - } - return p; -} - /* * Restore current working directory to "dirname_start" if they differ, taking * into account whether it is set locally or globally. diff --git a/src/nvim/version.c b/src/nvim/version.c index b3ab5d0d2c..cdd617e68c 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -205,7 +205,7 @@ static const int included_patches[] = { 2242, 2241, 2240, - // 2239, + 2239, // 2238 NA 2237, 2236, -- cgit From 7bd97127b4e45dcef1159603834b04ef0dcadfd7 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 29 Apr 2017 07:58:49 -0400 Subject: vim-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. https://github.com/vim/vim/commit/7b668e83d0635d082b7ec90d7d2aa30a9d7d8928 --- src/nvim/ex_cmds.lua | 8 +++++++- src/nvim/ex_cmds_defs.h | 26 ++++++++++++++------------ src/nvim/ex_docmd.c | 34 +++++++++++++++++++++++++++++++++- src/nvim/message.c | 15 +++++++++++++++ src/nvim/testdir/test_alot.vim | 1 + src/nvim/testdir/test_filter_cmd.vim | 15 +++++++++++++++ src/nvim/version.c | 2 +- 7 files changed, 86 insertions(+), 15 deletions(-) create mode 100644 src/nvim/testdir/test_filter_cmd.vim (limited to 'src') diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 844d46ab26..2566dd2f48 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -930,6 +930,12 @@ return { addr_type=ADDR_LINES, func='ex_filetype', }, + { + command='filter', + flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), + addr_type=ADDR_LINES, + func='ex_wrongmodifier', + }, { command='find', flags=bit.bor(RANGE, NOTADR, BANG, FILE1, EDITCMD, ARGOPT, TRLBAR), @@ -1810,7 +1816,7 @@ return { }, { command='oldfiles', - flags=bit.bor(BANG, TRLBAR, NOTADR, EXTRA, SBOXOK, CMDWIN), + flags=bit.bor(BANG, TRLBAR, SBOXOK, CMDWIN), addr_type=ADDR_LINES, func='ex_oldfiles', }, diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index 133c37cef4..b10775c001 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -6,6 +6,7 @@ #include "nvim/pos.h" // for linenr_T #include "nvim/normal.h" +#include "nvim/regexp_defs.h" #ifdef INCLUDE_GENERATED_DECLARATIONS # include "ex_cmds_enum.generated.h" @@ -163,18 +164,19 @@ struct expand { /// flag. This needs to be saved for recursive commands, put them in a /// structure for easy manipulation. typedef struct { - int split; ///< flags for win_split() - int tab; ///< > 0 when ":tab" was used - bool browse; ///< true to invoke file dialog - bool confirm; ///< true to invoke yes/no dialog - bool hide; ///< true when ":hide" was used - bool keepalt; ///< true when ":keepalt" was used - bool keepjumps; ///< true when ":keepjumps" was used - bool keepmarks; ///< true when ":keepmarks" was used - bool keeppatterns; ///< true when ":keeppatterns" was used - bool lockmarks; ///< true when ":lockmarks" was used - bool noswapfile; ///< true when ":noswapfile" was used - char_u *save_ei; ///< saved value of 'eventignore' + int split; ///< flags for win_split() + int tab; ///< > 0 when ":tab" was used + bool browse; ///< true to invoke file dialog + bool confirm; ///< true to invoke yes/no dialog + bool hide; ///< true when ":hide" was used + bool keepalt; ///< true when ":keepalt" was used + bool keepjumps; ///< true when ":keepjumps" was used + bool keepmarks; ///< true when ":keepmarks" was used + bool keeppatterns; ///< true when ":keeppatterns" was used + bool lockmarks; ///< true when ":lockmarks" was used + bool noswapfile; ///< true when ":noswapfile" was used + char_u *save_ei; ///< saved value of 'eventignore' + regmatch_T filter_regmatch; ///< set by :filter /pat/ } cmdmod_T; #endif // NVIM_EX_CMDS_DEFS_H diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 7568d71ac0..45a11482d0 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1350,6 +1350,24 @@ static char_u * do_one_cmd(char_u **cmdlinep, 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)) @@ -1452,6 +1470,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, } break; } + char_u *after_modifier = ea.cmd; ea.skip = did_emsg || got_int || did_throw || (cstack->cs_idx >= 0 && !(cstack->cs_flags[cstack-> @@ -1734,7 +1753,13 @@ static char_u * do_one_cmd(char_u **cmdlinep, if (!ea.skip) { STRCPY(IObuff, _("E492: Not an editor command")); if (!(flags & DOCMD_VERBOSE)) { - 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; @@ -2104,6 +2129,7 @@ static char_u * do_one_cmd(char_u **cmdlinep, case CMD_echomsg: case CMD_echon: case CMD_execute: + case CMD_filter: case CMD_help: case CMD_hide: case CMD_ijump: @@ -2255,6 +2281,10 @@ doend: free_string_option(cmdmod.save_ei); } + if (cmdmod.filter_regmatch.regprog != NULL) { + vim_regfree(cmdmod.filter_regmatch.regprog); + } + cmdmod = save_cmdmod; if (save_msg_silent != -1) { @@ -2545,6 +2575,7 @@ static struct cmdmod { {"botright", 2, FALSE}, {"browse", 3, FALSE}, {"confirm", 4, FALSE}, + {"filter", 4, FALSE}, {"hide", 3, FALSE}, {"keepalt", 5, FALSE}, {"keepjumps", 5, FALSE}, @@ -3007,6 +3038,7 @@ const char * set_one_cmd_context( 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/nvim/message.c b/src/nvim/message.c index 696855e3aa..c83dfcd63f 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -31,6 +31,7 @@ #include "nvim/ops.h" #include "nvim/option.h" #include "nvim/normal.h" +#include "nvim/regexp.h" #include "nvim/screen.h" #include "nvim/strings.h" #include "nvim/ui.h" @@ -148,6 +149,12 @@ msg_attr_keep ( int retval; char_u *buf = NULL; + // Skip messages not match ":filter pattern". + // Don't filter when there is an error. + if (!emsg_on_display && message_filtered(s)) { + return true; + } + if (attr == 0) { set_vim_var_string(VV_STATUSMSG, (char *) s, -1); } @@ -1783,6 +1790,14 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, msg_check(); } +/// Return true when ":filter pattern" was used and "msg" does not match +/// "pattern". +bool 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. */ diff --git a/src/nvim/testdir/test_alot.vim b/src/nvim/testdir/test_alot.vim index 99d9835996..5da9a8b0f4 100644 --- a/src/nvim/testdir/test_alot.vim +++ b/src/nvim/testdir/test_alot.vim @@ -8,6 +8,7 @@ source test_ex_undo.vim source test_expr.vim source test_expr_utf8.vim source test_feedkeys.vim +source test_filter_cmd.vim source test_filter_map.vim source test_goto.vim source test_jumps.vim diff --git a/src/nvim/testdir/test_filter_cmd.vim b/src/nvim/testdir/test_filter_cmd.vim new file mode 100644 index 0000000000..f85a11ce45 --- /dev/null +++ b/src/nvim/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/nvim/version.c b/src/nvim/version.c index cdd617e68c..a4125f9eac 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -200,7 +200,7 @@ static const int included_patches[] = { // 2247 NA // 2246, // 2245, - // 2244, + 2244, // 2243 NA 2242, 2241, -- cgit From f477c23c6282bffb8908f53592923e81443bac24 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 29 Apr 2017 21:22:22 -0400 Subject: vim-patch:7.4.2245 Problem: Filter test fails. Solution: Include missing changes. https://github.com/vim/vim/commit/77401add71853d7a3da7ccc489f2a1bca58551ec --- src/nvim/buffer.c | 6 +++++- src/nvim/version.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 7477118d6f..5007cb5015 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2365,12 +2365,16 @@ void buflist_list(exarg_T *eap) && (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) { continue; } - msg_putchar('\n'); if (buf_spname(buf) != NULL) STRLCPY(NameBuff, buf_spname(buf), MAXPATHL); else home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE); + if (message_filtered(NameBuff)) { + continue; + } + + msg_putchar('\n'); len = vim_snprintf((char *)IObuff, IOSIZE - 20, "%3d%c%c%c%c%c \"%s\"", buf->b_fnum, buf->b_p_bl ? ' ' : 'u', diff --git a/src/nvim/version.c b/src/nvim/version.c index a4125f9eac..c94e2b9f96 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -199,7 +199,7 @@ static const int included_patches[] = { 2248, // 2247 NA // 2246, - // 2245, + 2245, 2244, // 2243 NA 2242, -- cgit From ab50c1fdb73aa58f620491d50c6fcd222d37cb9d Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 29 Apr 2017 21:24:42 -0400 Subject: vim-patch:7.4.2246 Problem: Oldfiles test fails. Solution: Include missing changes. https://github.com/vim/vim/commit/d6f2ee32dcfa18c781ef157918b524318a2215a2 --- src/nvim/ex_cmds.c | 20 +------------------- src/nvim/version.c | 2 +- 2 files changed, 2 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 95cbcbbcb9..772527532e 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -6213,27 +6213,12 @@ void ex_oldfiles(exarg_T *eap) if (l == NULL) { msg((char_u *)_("No old files")); } else { - char_u *reg_pat = NULL; - regmatch_T regmatch; - - 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++; const char *fname = tv_get_string(&li->li_tv); - if (reg_pat == NULL || *reg_pat == NUL - || vim_regexec(®match, (char_u *)fname, (colnr_T)0)) { + if (!message_filtered((char_u *)fname)) { msg_outnum(nr); MSG_PUTS(": "); msg_outtrans((char_u *)tv_get_string(&li->li_tv)); @@ -6243,9 +6228,6 @@ void ex_oldfiles(exarg_T *eap) os_breakcheck(); } } - if (*eap->arg != NUL) { - vim_regfree(regmatch.regprog); - } /* Assume "got_int" was set to truncate the listing. */ got_int = FALSE; diff --git a/src/nvim/version.c b/src/nvim/version.c index c94e2b9f96..f2a97cf360 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -198,7 +198,7 @@ static const int included_patches[] = { 2249, 2248, // 2247 NA - // 2246, + 2246, 2245, 2244, // 2243 NA -- cgit From f219657453271f19519148d76536879bec044534 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 29 Apr 2017 21:29:44 -0400 Subject: 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. https://github.com/vim/vim/commit/d29459baa61819e59961804ed258efac5733ec70 --- src/nvim/ex_cmds.c | 5 +++++ src/nvim/ex_cmds.lua | 2 +- src/nvim/ex_cmds_defs.h | 1 + src/nvim/ex_docmd.c | 14 +++++++++++-- src/nvim/getchar.c | 6 +++++- src/nvim/message.c | 8 ++++++-- src/nvim/testdir/runtest.vim | 1 + src/nvim/testdir/test_filter_cmd.vim | 39 ++++++++++++++++++++++++++++++++++++ src/nvim/version.c | 2 +- 9 files changed, 71 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 772527532e..1b2eb774c9 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -1490,6 +1490,11 @@ void print_line(linenr_T lnum, int use_number, int list) { int save_silent = silent_mode; + // apply :filter /pat/ + if (message_filtered(ml_get(lnum))) { + return; + } + msg_start(); silent_mode = FALSE; info_message = TRUE; /* use mch_msg(), not mch_errmsg() */ diff --git a/src/nvim/ex_cmds.lua b/src/nvim/ex_cmds.lua index 2566dd2f48..523740444d 100644 --- a/src/nvim/ex_cmds.lua +++ b/src/nvim/ex_cmds.lua @@ -932,7 +932,7 @@ return { }, { command='filter', - flags=bit.bor(NEEDARG, EXTRA, NOTRLCOM), + flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM), addr_type=ADDR_LINES, func='ex_wrongmodifier', }, diff --git a/src/nvim/ex_cmds_defs.h b/src/nvim/ex_cmds_defs.h index b10775c001..d72b83404e 100644 --- a/src/nvim/ex_cmds_defs.h +++ b/src/nvim/ex_cmds_defs.h @@ -177,6 +177,7 @@ typedef struct { bool noswapfile; ///< true when ":noswapfile" was used char_u *save_ei; ///< saved value of 'eventignore' regmatch_T filter_regmatch; ///< set by :filter /pat/ + bool filter_force; ///< set for :filter! } cmdmod_T; #endif // NVIM_EX_CMDS_DEFS_H diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 45a11482d0..2eaf92df00 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1356,6 +1356,13 @@ static char_u * do_one_cmd(char_u **cmdlinep, if (!checkforcmd(&p, "filter", 4) || *p == NUL || ends_excmd(*p)) { break; } + if (*p == '!') { + cmdmod.filter_force = true; + p = skipwhite(p + 1); + if (*p == NUL || ends_excmd(*p)) { + break; + } + } p = skip_vimgrep_pat(p, ®_pat, NULL); if (p == NULL || *p == NUL) { break; @@ -4883,9 +4890,12 @@ static void uc_list(char_u *name, size_t name_len) cmd = USER_CMD_GA(gap, i); a = cmd->uc_argt; - /* Skip commands which don't match the requested prefix */ - if (STRNCMP(name, cmd->uc_name, name_len) != 0) + // Skip commands which don't match the requested prefix and + // commands filtered out. + if (STRNCMP(name, cmd->uc_name, name_len) != 0 + || message_filtered(cmd->uc_name)) { continue; + } /* Put out the title first time */ if (!found) diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index 9d32df5a68..6e21ee96e8 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1592,7 +1592,7 @@ vungetc ( /* unget one character (can only be done once!) */ /// This may do a blocking wait if "advance" is TRUE. /// /// 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. /// KeyStuffed is TRUE if the character comes from the stuff buffer. /// if "advance" is FALSE (vpeekc()): @@ -3168,6 +3168,10 @@ showmap ( { size_t len = 1; + if (message_filtered(mp->m_keys) && message_filtered(mp->m_str)) { + return; + } + if (msg_didout || msg_silent != 0) { msg_putchar('\n'); if (got_int) /* 'q' typed at MORE prompt */ diff --git a/src/nvim/message.c b/src/nvim/message.c index c83dfcd63f..057ce75f79 100644 --- a/src/nvim/message.c +++ b/src/nvim/message.c @@ -1794,8 +1794,12 @@ static void msg_puts_display(const char_u *str, int maxlen, int attr, /// "pattern". bool message_filtered(char_u *msg) { - return cmdmod.filter_regmatch.regprog != NULL - && !vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0); + if (cmdmod.filter_regmatch.regprog == NULL) { + return false; + } + + bool match = vim_regexec(&cmdmod.filter_regmatch, msg, (colnr_T)0); + return cmdmod.filter_force ? match : !match; } /* diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim index 1cf7ab475c..140b67a1a5 100644 --- a/src/nvim/testdir/runtest.vim +++ b/src/nvim/testdir/runtest.vim @@ -72,6 +72,7 @@ let v:testing = 1 set directory^=. set backspace= set nohidden smarttab noautoindent noautoread complete-=i noruler noshowcmd +set listchars=eol:$ " Prevent Nvim log from writing to stderr. let $NVIM_LOG_FILE='Xnvim.log' diff --git a/src/nvim/testdir/test_filter_cmd.vim b/src/nvim/testdir/test_filter_cmd.vim index f85a11ce45..0bbd905c85 100644 --- a/src/nvim/testdir/test_filter_cmd.vim +++ b/src/nvim/testdir/test_filter_cmd.vim @@ -4,6 +4,39 @@ func Test_filter() edit Xdoesnotmatch edit Xwillmatch 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 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/ 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 diff --git a/src/nvim/version.c b/src/nvim/version.c index f2a97cf360..b579cdef12 100644 --- a/src/nvim/version.c +++ b/src/nvim/version.c @@ -181,7 +181,7 @@ static const int included_patches[] = { 2266, 2265, 2264, - // 2263, + 2263, // 2262 NA // 2261 NA // 2260 NA -- cgit From b6e36558d1e119a4382e96495b0e1faf402197f3 Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 29 Apr 2017 21:49:19 -0400 Subject: vim-patch:8.0.0150 Problem: When the pattern of :filter does not have a separator then completion of the command fails. Solution: Skip over the pattern. (Ozaki Kiichi, clodes vim/vim#1299) https://github.com/vim/vim/commit/7069bf18e1b1b7bc7640335e07d1022b5acc9048 --- src/nvim/ex_docmd.c | 11 ++++++++++- src/nvim/testdir/test_filter_cmd.vim | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 2eaf92df00..e844c89516 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -3045,7 +3045,6 @@ const char * set_one_cmd_context( case CMD_cfdo: case CMD_confirm: case CMD_debug: - case CMD_filter: case CMD_folddoclosed: case CMD_folddoopen: case CMD_hide: @@ -3070,6 +3069,16 @@ const char * set_one_cmd_context( case CMD_windo: return arg; + case CMD_filter: + if (*arg != NUL) { + arg = (const char *)skip_vimgrep_pat((char_u *)arg, NULL, NULL); + } + if (arg == NULL || *arg == NUL) { + xp->xp_context = EXPAND_NOTHING; + return NULL; + } + return (const char *)skipwhite((const char_u *)arg); + case CMD_match: if (*arg == NUL || !ends_excmd(*arg)) { /* also complete "None" */ diff --git a/src/nvim/testdir/test_filter_cmd.vim b/src/nvim/testdir/test_filter_cmd.vim index 0bbd905c85..5aa5fa64df 100644 --- a/src/nvim/testdir/test_filter_cmd.vim +++ b/src/nvim/testdir/test_filter_cmd.vim @@ -52,3 +52,25 @@ func Test_filter_fails() call assert_fails('filter! /pat/', 'E476:') call assert_fails('filter! /pat/ asdf', 'E492:') endfunc + +function s:complete_filter_cmd(filtcmd) + let keystroke = "\\=execute('let cmdline = getcmdline()')\\" + let cmdline = '' + call feedkeys(':' . a:filtcmd . keystroke, 'ntx') + return cmdline +endfunction + +func Test_filter_cmd_completion() + " Do not complete pattern + call assert_equal("filter \t", s:complete_filter_cmd('filter ')) + call assert_equal("filter pat\t", s:complete_filter_cmd('filter pat')) + call assert_equal("filter /pat\t", s:complete_filter_cmd('filter /pat')) + call assert_equal("filter /pat/\t", s:complete_filter_cmd('filter /pat/')) + + " Complete after string pattern + call assert_equal('filter pat print', s:complete_filter_cmd('filter pat pri')) + + " Complete after regexp pattern + call assert_equal('filter /pat/ print', s:complete_filter_cmd('filter /pat/ pri')) + call assert_equal('filter #pat# print', s:complete_filter_cmd('filter #pat# pri')) +endfunc -- cgit From 2b191ac5b9a18f31eadb4f14ed8a220d0c03ebdc Mon Sep 17 00:00:00 2001 From: James McCoy Date: Sat, 29 Apr 2017 22:09:09 -0400 Subject: lint --- src/nvim/buffer.c | 7 ++++--- src/nvim/ex_cmds.c | 32 +++++++++++++++++++------------- src/nvim/ex_docmd.c | 46 +++++++++++++++++++++++----------------------- 3 files changed, 46 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 5007cb5015..7def8c1684 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -2365,10 +2365,11 @@ void buflist_list(exarg_T *eap) && (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) { continue; } - if (buf_spname(buf) != NULL) + if (buf_spname(buf) != NULL) { STRLCPY(NameBuff, buf_spname(buf), MAXPATHL); - else - home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, TRUE); + } else { + home_replace(buf, buf->b_fname, NameBuff, MAXPATHL, true); + } if (message_filtered(NameBuff)) { continue; diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index 1b2eb774c9..f73d4c16b6 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -6175,34 +6175,40 @@ char_u *skip_vimgrep_pat(char_u *p, char_u **s, int *flags) if (vim_isIDc(*p)) { // ":vimgrep pattern fname" - if (s != NULL) + if (s != NULL) { *s = p; + } p = skiptowhite(p); - if (s != NULL && *p != NUL) + if (s != NULL && *p != NUL) { *p++ = NUL; + } } else { // ":vimgrep /pattern/[g][j] fname" - if (s != NULL) + if (s != NULL) { *s = p + 1; + } c = *p; - p = skip_regexp(p + 1, c, TRUE, NULL); - if (*p != c) + p = skip_regexp(p + 1, c, true, NULL); + if (*p != c) { return NULL; + } // Truncate the pattern. - if (s != NULL) + if (s != NULL) { *p = NUL; - ++p; + } + p++; // Find the flags while (*p == 'g' || *p == 'j') { if (flags != NULL) { - if (*p == 'g') + if (*p == 'g') { *flags |= VGR_GLOBAL; - else + } else { *flags |= VGR_NOJUMP; + } } - ++p; + p++; } } return p; @@ -6219,7 +6225,7 @@ void ex_oldfiles(exarg_T *eap) msg((char_u *)_("No old files")); } else { msg_start(); - msg_scroll = TRUE; + msg_scroll = true; for (li = l->lv_first; li != NULL && !got_int; li = li->li_next) { nr++; const char *fname = tv_get_string(&li->li_tv); @@ -6234,8 +6240,8 @@ void ex_oldfiles(exarg_T *eap) } } - /* Assume "got_int" was set to truncate the listing. */ - got_int = FALSE; + // Assume "got_int" was set to truncate the listing. + got_int = false; // File selection prompt on ":browse oldfiles" if (cmdmod.browse) { diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index e844c89516..72b2e0f29b 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2577,29 +2577,29 @@ static struct cmdmod { int minlen; int has_count; /* :123verbose :3tab */ } cmdmods[] = { - {"aboveleft", 3, FALSE}, - {"belowright", 3, FALSE}, - {"botright", 2, FALSE}, - {"browse", 3, FALSE}, - {"confirm", 4, FALSE}, - {"filter", 4, FALSE}, - {"hide", 3, FALSE}, - {"keepalt", 5, FALSE}, - {"keepjumps", 5, FALSE}, - {"keepmarks", 3, FALSE}, - {"keeppatterns", 5, FALSE}, - {"leftabove", 5, FALSE}, - {"lockmarks", 3, FALSE}, - {"noautocmd", 3, FALSE}, - {"noswapfile", 3, FALSE}, - {"rightbelow", 6, FALSE}, - {"sandbox", 3, FALSE}, - {"silent", 3, FALSE}, - {"tab", 3, TRUE}, - {"topleft", 2, FALSE}, - {"unsilent", 3, FALSE}, - {"verbose", 4, TRUE}, - {"vertical", 4, FALSE}, + { "aboveleft", 3, false }, + { "belowright", 3, false }, + { "botright", 2, false }, + { "browse", 3, false }, + { "confirm", 4, false }, + { "filter", 4, false }, + { "hide", 3, false }, + { "keepalt", 5, false }, + { "keepjumps", 5, false }, + { "keepmarks", 3, false }, + { "keeppatterns", 5, false }, + { "leftabove", 5, false }, + { "lockmarks", 3, false }, + { "noautocmd", 3, false }, + { "noswapfile", 3, false }, + { "rightbelow", 6, false }, + { "sandbox", 3, false }, + { "silent", 3, false }, + { "tab", 3, true }, + { "topleft", 2, false }, + { "unsilent", 3, false }, + { "verbose", 4, true }, + { "vertical", 4, false }, }; /* -- cgit