mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
Merge pull request #6621 from jamessan/vim-7.4.2231
vim-patch:7.4.2231,7.4.2239,7.4.2244,7.4.2245,7.4.2246,7.4.2263,8.0.0150
This commit is contained in:
commit
5d73a6e5df
@ -518,7 +518,8 @@ accordingly. Vim proceeds in this order:
|
||||
The |v:vim_did_enter| variable is set to 1.
|
||||
The |VimEnter| autocommands are executed.
|
||||
|
||||
Some hints on using initializations:
|
||||
|
||||
Some hints on using initializations ~
|
||||
|
||||
Standard setup:
|
||||
Create a vimrc file to set the default settings and mappings for all your edit
|
||||
@ -540,17 +541,23 @@ the ":version" command. NOTE: System vimrc file needs specific compilation
|
||||
options (one needs to define SYS_VIMRC_FILE macros). If :version command does
|
||||
not show anything like this, consider contacting the nvim package maintainer.
|
||||
|
||||
Saving the current state of Vim to a file:
|
||||
|
||||
Saving the current state of Vim to a file ~
|
||||
|
||||
Whenever you have changed values of options or when you have created a
|
||||
mapping, then you may want to save them in a vimrc file for later use. See
|
||||
|save-settings| about saving the current state of settings to a file.
|
||||
|
||||
Avoiding setup problems for Vi users:
|
||||
|
||||
Avoiding setup problems for Vi users ~
|
||||
|
||||
Vi uses the variable EXINIT and the file "~/.exrc". So if you do not want to
|
||||
interfere with Vi, then use the variable VIMINIT and the file init.vim
|
||||
instead.
|
||||
|
||||
MS-DOS line separators:
|
||||
|
||||
MS-DOS line separators: ~
|
||||
|
||||
On Windows systems Vim assumes that all the vimrc files have <CR> <NL> pairs
|
||||
as line separators. This will give problems if you have a file with only
|
||||
<NL>s and have a line like ":map xx yy^M". The trailing ^M will be ignored.
|
||||
@ -558,8 +565,10 @@ as line separators. This will give problems if you have a file with only
|
||||
The $MYVIMRC or $MYGVIMRC file will be set to the first found vimrc and/or
|
||||
gvimrc file.
|
||||
|
||||
Avoiding trojan horses: *trojan-horse*
|
||||
While reading the vimrc or the exrc file in the current directory, some
|
||||
|
||||
Avoiding trojan horses ~
|
||||
*trojan-horse*
|
||||
While reading the "vimrc" or the "exrc" file in the current directory, some
|
||||
commands can be disabled for security reasons by setting the 'secure' option.
|
||||
This is always done when executing the command from a tags file. Otherwise it
|
||||
would be possible that you accidentally use a vimrc or tags file that somebody
|
||||
@ -581,6 +590,8 @@ Be careful!
|
||||
part of the line in the tags file) is always done in secure mode. This works
|
||||
just like executing a command from a vimrc/exrc in the current directory.
|
||||
|
||||
|
||||
If Vim startup is slow ~
|
||||
*slow-start*
|
||||
If Vim takes a long time to start up, use the |--startuptime| argument to find
|
||||
out what happens.
|
||||
@ -590,6 +601,8 @@ while. You can find out if this is the problem by disabling ShaDa for a
|
||||
moment (use the Vim argument "-i NONE", |-i|). Try reducing the number of
|
||||
lines stored in a register with ":set shada='20,<50,s10". |shada-file|.
|
||||
|
||||
|
||||
Intro message ~
|
||||
*:intro*
|
||||
When Vim starts without a file name, an introductory message is displayed (for
|
||||
those who don't know what Vim is). It is removed as soon as the display is
|
||||
@ -1182,7 +1195,7 @@ running) you have additional options:
|
||||
*:o* *:ol* *:oldfiles*
|
||||
:o[ldfiles] List the files that have marks stored in the ShaDa
|
||||
file. This list is read on startup and only changes
|
||||
afterwards with ":rshada!". Also see |v:oldfiles|.
|
||||
afterwards with `:rshada!`. Also see |v:oldfiles|.
|
||||
The number can be used with |c_#<|.
|
||||
The output can be filtered with |:filter|, e.g.: >
|
||||
filter /\.vim/ oldfiles
|
||||
|
@ -2365,12 +2365,17 @@ void buflist_list(exarg_T *eap)
|
||||
&& (buf == curbuf || curwin->w_alt_fnum != buf->b_fnum))) {
|
||||
continue;
|
||||
}
|
||||
msg_putchar('\n');
|
||||
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;
|
||||
}
|
||||
|
||||
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',
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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() */
|
||||
@ -6158,3 +6163,103 @@ void ex_substitute(exarg_T *eap)
|
||||
ga_clear(&save_view);
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
nr++;
|
||||
const char *fname = tv_get_string(&li->li_tv);
|
||||
if (!message_filtered((char_u *)fname)) {
|
||||
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;
|
||||
cmdmod.browse = false;
|
||||
do_exedit(eap, NULL);
|
||||
xfree(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -930,6 +930,12 @@ return {
|
||||
addr_type=ADDR_LINES,
|
||||
func='ex_filetype',
|
||||
},
|
||||
{
|
||||
command='filter',
|
||||
flags=bit.bor(BANG, NEEDARG, EXTRA, NOTRLCOM),
|
||||
addr_type=ADDR_LINES,
|
||||
func='ex_wrongmodifier',
|
||||
},
|
||||
{
|
||||
command='find',
|
||||
flags=bit.bor(RANGE, NOTADR, BANG, FILE1, EDITCMD, ARGOPT, TRLBAR),
|
||||
|
@ -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,20 @@ 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/
|
||||
bool filter_force; ///< set for :filter!
|
||||
} cmdmod_T;
|
||||
|
||||
#endif // NVIM_EX_CMDS_DEFS_H
|
||||
|
@ -1350,6 +1350,31 @@ 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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
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 +1477,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 +1760,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 +2136,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 +2288,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) {
|
||||
@ -2540,28 +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},
|
||||
{"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 },
|
||||
};
|
||||
|
||||
/*
|
||||
@ -3031,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" */
|
||||
@ -4851,9 +4899,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)
|
||||
|
@ -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 */
|
||||
|
@ -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,18 @@ 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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scroll the screen up one line for displaying the next message line.
|
||||
*/
|
||||
|
@ -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.
|
||||
|
@ -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'
|
||||
|
||||
|
@ -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
|
||||
|
76
src/nvim/testdir/test_filter_cmd.vim
Normal file
76
src/nvim/testdir/test_filter_cmd.vim
Normal file
@ -0,0 +1,76 @@
|
||||
" Test the :filter command modifier
|
||||
|
||||
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()
|
||||
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:')
|
||||
|
||||
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
|
||||
|
||||
function s:complete_filter_cmd(filtcmd)
|
||||
let keystroke = "\<TAB>\<C-R>=execute('let cmdline = getcmdline()')\<CR>\<C-C>"
|
||||
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
|
@ -181,7 +181,7 @@ static const int included_patches[] = {
|
||||
2266,
|
||||
2265,
|
||||
2264,
|
||||
// 2263,
|
||||
2263,
|
||||
// 2262 NA
|
||||
// 2261 NA
|
||||
// 2260 NA
|
||||
@ -198,14 +198,14 @@ static const int included_patches[] = {
|
||||
2249,
|
||||
2248,
|
||||
// 2247 NA
|
||||
// 2246,
|
||||
// 2245,
|
||||
// 2244,
|
||||
2246,
|
||||
2245,
|
||||
2244,
|
||||
// 2243 NA
|
||||
2242,
|
||||
2241,
|
||||
2240,
|
||||
// 2239,
|
||||
2239,
|
||||
// 2238 NA
|
||||
2237,
|
||||
2236,
|
||||
@ -213,7 +213,7 @@ static const int included_patches[] = {
|
||||
// 2234 NA
|
||||
2233,
|
||||
// 2232 NA
|
||||
// 2231,
|
||||
2231,
|
||||
2230,
|
||||
// 2229,
|
||||
2228,
|
||||
|
@ -4,13 +4,15 @@ local helpers = require('test.functional.helpers')(after_each)
|
||||
local buf, eq, feed_command = helpers.curbufmeths, helpers.eq, helpers.feed_command
|
||||
local feed, nvim_prog, wait = helpers.feed, helpers.nvim_prog, helpers.wait
|
||||
local ok, set_session, spawn = helpers.ok, helpers.set_session, helpers.spawn
|
||||
local eval = helpers.eval
|
||||
|
||||
local shada_file = 'test.shada'
|
||||
local shada_file = 'Xtest.shada'
|
||||
|
||||
local function _clear()
|
||||
set_session(spawn({nvim_prog, '--embed', '-u', 'NONE', '--cmd',
|
||||
set_session(spawn({nvim_prog, '--embed', '-u', 'NONE',
|
||||
-- Need shada for these tests.
|
||||
'set noswapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'}))
|
||||
'-i', shada_file,
|
||||
'--cmd', 'set noswapfile undodir=. directory=. viewdir=. backupdir=. belloff= noshowcmd noruler'}))
|
||||
end
|
||||
|
||||
describe(':oldfiles', function()
|
||||
@ -29,8 +31,8 @@ describe(':oldfiles', function()
|
||||
screen:attach()
|
||||
feed_command('edit testfile1')
|
||||
feed_command('edit testfile2')
|
||||
feed_command('wshada ' .. shada_file)
|
||||
feed_command('rshada! ' .. shada_file)
|
||||
feed_command('wshada')
|
||||
feed_command('rshada!')
|
||||
local oldfiles = helpers.meths.get_vvar('oldfiles')
|
||||
feed_command('oldfiles')
|
||||
screen:expect([[
|
||||
@ -41,6 +43,38 @@ describe(':oldfiles', function()
|
||||
Press ENTER or type command to continue^ |
|
||||
]])
|
||||
end)
|
||||
|
||||
it('can be filtered with :filter', function()
|
||||
feed_command('edit file_one.txt')
|
||||
local file1 = buf.get_name()
|
||||
feed_command('edit file_two.txt')
|
||||
local file2 = buf.get_name()
|
||||
feed_command('edit another.txt')
|
||||
local another = buf.get_name()
|
||||
feed_command('wshada')
|
||||
feed_command('rshada!')
|
||||
|
||||
local function get_oldfiles(cmd)
|
||||
local t = eval([[split(execute(']]..cmd..[['), "\n")]])
|
||||
for i, _ in ipairs(t) do
|
||||
t[i] = t[i]:gsub('^%d+:%s+', '')
|
||||
end
|
||||
table.sort(t)
|
||||
return t
|
||||
end
|
||||
|
||||
local oldfiles = get_oldfiles('oldfiles')
|
||||
eq({another, file1, file2}, oldfiles)
|
||||
|
||||
oldfiles = get_oldfiles('filter file_ oldfiles')
|
||||
eq({file1, file2}, oldfiles)
|
||||
|
||||
oldfiles = get_oldfiles('filter /another/ oldfiles')
|
||||
eq({another}, oldfiles)
|
||||
|
||||
oldfiles = get_oldfiles('filter! file_ oldfiles')
|
||||
eq({another}, oldfiles)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe(':browse oldfiles', function()
|
||||
@ -54,10 +88,9 @@ describe(':browse oldfiles', function()
|
||||
filename = buf.get_name()
|
||||
feed_command('edit testfile2')
|
||||
filename2 = buf.get_name()
|
||||
feed_command('wshada ' .. shada_file)
|
||||
feed_command('wshada')
|
||||
wait()
|
||||
_clear()
|
||||
feed_command('rshada! ' .. shada_file)
|
||||
|
||||
-- Ensure nvim is out of "Press ENTER..." prompt.
|
||||
feed('<cr>')
|
||||
|
Loading…
Reference in New Issue
Block a user