mirror of
https://github.com/vim/vim.git
synced 2025-09-24 03:44:06 -04:00
patch 8.1.0282: 'incsearch' does not work with command modifiers
Problem: 'incsearch' does not work with command modifiers. Solution: Skip command modifiers.
This commit is contained in:
@@ -68,6 +68,7 @@ static char_u *do_one_cmd(char_u **, int, struct condstack *, char_u *(*fgetline
|
||||
static char_u *do_one_cmd(char_u **, int, char_u *(*fgetline)(int, void *, int), void *cookie);
|
||||
static int if_level = 0; /* depth in :if */
|
||||
#endif
|
||||
static void free_cmdmod(void);
|
||||
static void append_command(char_u *cmd);
|
||||
static char_u *find_command(exarg_T *eap, int *full);
|
||||
|
||||
@@ -1742,9 +1743,10 @@ do_one_cmd(
|
||||
goto doend;
|
||||
|
||||
/*
|
||||
* Repeat until no more command modifiers are found.
|
||||
* The "ea" structure holds the arguments that can be used.
|
||||
* 1. Skip comment lines and leading white space and colons.
|
||||
* 2. Handle command modifiers.
|
||||
*/
|
||||
// The "ea" structure holds the arguments that can be used.
|
||||
ea.cmd = *cmdlinep;
|
||||
ea.cmdlinep = cmdlinep;
|
||||
ea.getline = fgetline;
|
||||
@@ -1752,7 +1754,7 @@ do_one_cmd(
|
||||
#ifdef FEAT_EVAL
|
||||
ea.cstack = cstack;
|
||||
#endif
|
||||
if (parse_command_modifiers(&ea, &errormsg) == FAIL)
|
||||
if (parse_command_modifiers(&ea, &errormsg, FALSE) == FAIL)
|
||||
goto doend;
|
||||
|
||||
after_modifier = ea.cmd;
|
||||
@@ -2553,17 +2555,7 @@ doend:
|
||||
if (ea.verbose_save >= 0)
|
||||
p_verbose = ea.verbose_save;
|
||||
|
||||
if (cmdmod.save_ei != NULL)
|
||||
{
|
||||
/* Restore 'eventignore' to the value before ":noautocmd". */
|
||||
set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
|
||||
OPT_FREE, SID_NONE);
|
||||
free_string_option(cmdmod.save_ei);
|
||||
}
|
||||
|
||||
if (cmdmod.filter_regmatch.regprog != NULL)
|
||||
vim_regfree(cmdmod.filter_regmatch.regprog);
|
||||
|
||||
free_cmdmod();
|
||||
cmdmod = save_cmdmod;
|
||||
|
||||
if (ea.save_msg_silent != -1)
|
||||
@@ -2609,13 +2601,16 @@ doend:
|
||||
* - store flags in "cmdmod".
|
||||
* - Set ex_pressedreturn for an empty command line.
|
||||
* - set msg_silent for ":silent"
|
||||
* - set 'eventignore' to "all" for ":noautocmd"
|
||||
* - set p_verbose for ":verbose"
|
||||
* - Increment "sandbox" for ":sandbox"
|
||||
* When "skip_only" is TRUE the global variables are not changed, except for
|
||||
* "cmdmod".
|
||||
* Return FAIL when the command is not to be executed.
|
||||
* May set "errormsg" to an error message.
|
||||
*/
|
||||
int
|
||||
parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
parse_command_modifiers(exarg_T *eap, char_u **errormsg, int skip_only)
|
||||
{
|
||||
char_u *p;
|
||||
|
||||
@@ -2623,11 +2618,9 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
eap->verbose_save = -1;
|
||||
eap->save_msg_silent = -1;
|
||||
|
||||
// Repeat until no more command modifiers are found.
|
||||
for (;;)
|
||||
{
|
||||
/*
|
||||
* 1. Skip comment lines and leading white space and colons.
|
||||
*/
|
||||
while (*eap->cmd == ' ' || *eap->cmd == '\t' || *eap->cmd == ':')
|
||||
++eap->cmd;
|
||||
|
||||
@@ -2638,6 +2631,7 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
|
||||
{
|
||||
eap->cmd = (char_u *)"+";
|
||||
if (!skip_only)
|
||||
ex_pressedreturn = TRUE;
|
||||
}
|
||||
|
||||
@@ -2646,13 +2640,11 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
return FAIL;
|
||||
if (*eap->cmd == NUL)
|
||||
{
|
||||
if (!skip_only)
|
||||
ex_pressedreturn = TRUE;
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2. Handle command modifiers.
|
||||
*/
|
||||
p = skip_range(eap->cmd, NULL);
|
||||
switch (*p)
|
||||
{
|
||||
@@ -2720,13 +2712,20 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
if (*p == NUL || ends_excmd(*p))
|
||||
break;
|
||||
}
|
||||
if (skip_only)
|
||||
p = skip_vimgrep_pat(p, NULL, NULL);
|
||||
else
|
||||
// NOTE: This puts a NUL after the pattern.
|
||||
p = skip_vimgrep_pat(p, ®_pat, NULL);
|
||||
if (p == NULL || *p == NUL)
|
||||
break;
|
||||
if (!skip_only)
|
||||
{
|
||||
cmdmod.filter_regmatch.regprog =
|
||||
vim_regcomp(reg_pat, RE_MAGIC);
|
||||
if (cmdmod.filter_regmatch.regprog == NULL)
|
||||
break;
|
||||
}
|
||||
eap->cmd = p;
|
||||
continue;
|
||||
}
|
||||
@@ -2752,7 +2751,7 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
|
||||
case 'n': if (checkforcmd(&eap->cmd, "noautocmd", 3))
|
||||
{
|
||||
if (cmdmod.save_ei == NULL)
|
||||
if (cmdmod.save_ei == NULL && !skip_only)
|
||||
{
|
||||
/* Set 'eventignore' to "all". Restore the
|
||||
* existing option value later. */
|
||||
@@ -2775,24 +2774,33 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
case 's': if (checkforcmd(&eap->cmd, "sandbox", 3))
|
||||
{
|
||||
#ifdef HAVE_SANDBOX
|
||||
if (!skip_only)
|
||||
{
|
||||
if (!eap->did_sandbox)
|
||||
++sandbox;
|
||||
eap->did_sandbox = TRUE;
|
||||
}
|
||||
#endif
|
||||
continue;
|
||||
}
|
||||
if (!checkforcmd(&eap->cmd, "silent", 3))
|
||||
break;
|
||||
if (!skip_only)
|
||||
{
|
||||
if (eap->save_msg_silent == -1)
|
||||
eap->save_msg_silent = msg_silent;
|
||||
++msg_silent;
|
||||
}
|
||||
if (*eap->cmd == '!' && !VIM_ISWHITE(eap->cmd[-1]))
|
||||
{
|
||||
/* ":silent!", but not "silent !cmd" */
|
||||
eap->cmd = skipwhite(eap->cmd + 1);
|
||||
if (!skip_only)
|
||||
{
|
||||
++emsg_silent;
|
||||
++eap->did_esilent;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case 't': if (checkforcmd(&p, "tab", 3))
|
||||
@@ -2820,9 +2828,12 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
|
||||
case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
|
||||
break;
|
||||
if (!skip_only)
|
||||
{
|
||||
if (eap->save_msg_silent == -1)
|
||||
eap->save_msg_silent = msg_silent;
|
||||
msg_silent = 0;
|
||||
}
|
||||
continue;
|
||||
|
||||
case 'v': if (checkforcmd(&eap->cmd, "vertical", 4))
|
||||
@@ -2832,12 +2843,15 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
}
|
||||
if (!checkforcmd(&p, "verbose", 4))
|
||||
break;
|
||||
if (!skip_only)
|
||||
{
|
||||
if (eap->verbose_save < 0)
|
||||
eap->verbose_save = p_verbose;
|
||||
if (vim_isdigit(*eap->cmd))
|
||||
p_verbose = atoi((char *)eap->cmd);
|
||||
else
|
||||
p_verbose = 1;
|
||||
}
|
||||
eap->cmd = p;
|
||||
continue;
|
||||
}
|
||||
@@ -2847,6 +2861,24 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
||||
return OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free contents of "cmdmod".
|
||||
*/
|
||||
static void
|
||||
free_cmdmod(void)
|
||||
{
|
||||
if (cmdmod.save_ei != NULL)
|
||||
{
|
||||
/* Restore 'eventignore' to the value before ":noautocmd". */
|
||||
set_string_option_direct((char_u *)"ei", -1, cmdmod.save_ei,
|
||||
OPT_FREE, SID_NONE);
|
||||
free_string_option(cmdmod.save_ei);
|
||||
}
|
||||
|
||||
if (cmdmod.filter_regmatch.regprog != NULL)
|
||||
vim_regfree(cmdmod.filter_regmatch.regprog);
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the address range, if any, in "eap".
|
||||
* Return FAIL and set "errormsg" or return OK.
|
||||
|
@@ -283,11 +283,24 @@ do_incsearch_highlighting(int firstc, incsearch_state_T *is_state,
|
||||
return TRUE;
|
||||
if (firstc == ':')
|
||||
{
|
||||
char_u *cmd = skip_range(ccline.cmdbuff, NULL);
|
||||
char_u *cmd;
|
||||
cmdmod_T save_cmdmod = cmdmod;
|
||||
char_u *p;
|
||||
int delim;
|
||||
char_u *end;
|
||||
char_u *dummy;
|
||||
exarg_T ea;
|
||||
|
||||
vim_memset(&ea, 0, sizeof(ea));
|
||||
ea.line1 = 1;
|
||||
ea.line2 = 1;
|
||||
ea.cmd = ccline.cmdbuff;
|
||||
ea.addr_type = ADDR_LINES;
|
||||
|
||||
parse_command_modifiers(&ea, &dummy, TRUE);
|
||||
cmdmod = save_cmdmod;
|
||||
|
||||
cmd = skip_range(ea.cmd, NULL);
|
||||
if (*cmd == 's' || *cmd == 'g' || *cmd == 'v')
|
||||
{
|
||||
// Skip over "substitute" to find the pattern separator.
|
||||
@@ -310,8 +323,6 @@ do_incsearch_highlighting(int firstc, incsearch_state_T *is_state,
|
||||
end = skip_regexp(p, delim, p_magic, NULL);
|
||||
if (end > p || *end == delim)
|
||||
{
|
||||
char_u *dummy;
|
||||
exarg_T ea;
|
||||
pos_T save_cursor = curwin->w_cursor;
|
||||
|
||||
// found a non-empty pattern
|
||||
@@ -319,11 +330,6 @@ do_incsearch_highlighting(int firstc, incsearch_state_T *is_state,
|
||||
*patlen = (int)(end - p);
|
||||
|
||||
// parse the address range
|
||||
vim_memset(&ea, 0, sizeof(ea));
|
||||
ea.line1 = 1;
|
||||
ea.line2 = 1;
|
||||
ea.cmd = ccline.cmdbuff;
|
||||
ea.addr_type = ADDR_LINES;
|
||||
curwin->w_cursor = is_state->search_start;
|
||||
parse_cmd_address(&ea, &dummy);
|
||||
if (ea.addr_count > 0)
|
||||
|
@@ -4,7 +4,7 @@ int do_cmdline_cmd(char_u *cmd);
|
||||
int do_cmdline(char_u *cmdline, char_u *(*fgetline)(int, void *, int), void *cookie, int flags);
|
||||
int getline_equal(char_u *(*fgetline)(int, void *, int), void *cookie, char_u *(*func)(int, void *, int));
|
||||
void *getline_cookie(char_u *(*fgetline)(int, void *, int), void *cookie);
|
||||
int parse_command_modifiers(exarg_T *eap, char_u **errormsg);
|
||||
int parse_command_modifiers(exarg_T *eap, char_u **errormsg, int skip_only);
|
||||
int parse_cmd_address(exarg_T *eap, char_u **errormsg);
|
||||
int checkforcmd(char_u **pp, char *cmd, int len);
|
||||
int modifier_len(char_u *cmd);
|
||||
|
@@ -884,6 +884,12 @@ func Test_incsearch_substitute_dump()
|
||||
call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
" Command modifiers are skipped
|
||||
call term_sendkeys(buf, ':above below browse botr confirm keepmar keepalt keeppat keepjum filter xxx hide lockm leftabove noau noswap rightbel sandbox silent silent! $tab top unsil vert verbose 4,5s/fo.')
|
||||
sleep 100m
|
||||
call VerifyScreenDump(buf, 'Test_incsearch_substitute_06', {})
|
||||
call term_sendkeys(buf, "\<Esc>")
|
||||
|
||||
call StopVimInTerminal(buf)
|
||||
call delete('Xis_subst_script')
|
||||
endfunc
|
||||
|
@@ -794,6 +794,8 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
282,
|
||||
/**/
|
||||
281,
|
||||
/**/
|
||||
|
Reference in New Issue
Block a user