summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-08-14 16:06:16 +0200
committerBram Moolenaar <Bram@vim.org>2018-08-14 16:06:16 +0200
commit33c4dbb74bdf41aadd193a704f597d4df20f0e47 (patch)
treee5ab03ee47116aeed841ddeeb635165c3ef3e720 /src
parenteffed9315c6c5a35fc2824b90da4af753c7a02dc (diff)
patch 8.1.0282: 'incsearch' does not work with command modifiersv8.1.0282
Problem: 'incsearch' does not work with command modifiers. Solution: Skip command modifiers.
Diffstat (limited to 'src')
-rw-r--r--src/ex_docmd.c126
-rw-r--r--src/ex_getln.c30
-rw-r--r--src/proto/ex_docmd.pro2
-rw-r--r--src/testdir/test_search.vim6
-rw-r--r--src/version.c2
5 files changed, 106 insertions, 60 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 9491e235d9..169cb7a64e 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -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);
@@ -1741,10 +1742,11 @@ do_one_cmd(
if ((*cmdlinep)[0] == '#' && (*cmdlinep)[1] == '!')
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,7 +2631,8 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count)
{
eap->cmd = (char_u *)"+";
- ex_pressedreturn = TRUE;
+ if (!skip_only)
+ ex_pressedreturn = TRUE;
}
/* ignore comment and empty lines */
@@ -2646,13 +2640,11 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
return FAIL;
if (*eap->cmd == NUL)
{
- ex_pressedreturn = TRUE;
+ 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;
}
- p = skip_vimgrep_pat(p, &reg_pat, NULL);
+ if (skip_only)
+ p = skip_vimgrep_pat(p, NULL, NULL);
+ else
+ // NOTE: This puts a NUL after the pattern.
+ p = skip_vimgrep_pat(p, &reg_pat, NULL);
if (p == NULL || *p == NUL)
break;
- cmdmod.filter_regmatch.regprog =
+ if (!skip_only)
+ {
+ cmdmod.filter_regmatch.regprog =
vim_regcomp(reg_pat, RE_MAGIC);
- if (cmdmod.filter_regmatch.regprog == NULL)
- break;
+ 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,23 +2774,32 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
case 's': if (checkforcmd(&eap->cmd, "sandbox", 3))
{
#ifdef HAVE_SANDBOX
- if (!eap->did_sandbox)
- ++sandbox;
- eap->did_sandbox = TRUE;
+ if (!skip_only)
+ {
+ if (!eap->did_sandbox)
+ ++sandbox;
+ eap->did_sandbox = TRUE;
+ }
#endif
continue;
}
if (!checkforcmd(&eap->cmd, "silent", 3))
break;
- if (eap->save_msg_silent == -1)
- eap->save_msg_silent = msg_silent;
- ++msg_silent;
+ 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);
- ++emsg_silent;
- ++eap->did_esilent;
+ if (!skip_only)
+ {
+ ++emsg_silent;
+ ++eap->did_esilent;
+ }
}
continue;
@@ -2820,9 +2828,12 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
break;
- if (eap->save_msg_silent == -1)
- eap->save_msg_silent = msg_silent;
- msg_silent = 0;
+ 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 (eap->verbose_save < 0)
- eap->verbose_save = p_verbose;
- if (vim_isdigit(*eap->cmd))
- p_verbose = atoi((char *)eap->cmd);
- else
- p_verbose = 1;
+ 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;
}
@@ -2848,6 +2862,24 @@ parse_command_modifiers(exarg_T *eap, char_u **errormsg)
}
/*
+ * 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.
*/
diff --git a/src/ex_getln.c b/src/ex_getln.c
index fb16743f0c..a8c5cfb001 100644
--- a/src/ex_getln.c
+++ b/src/ex_getln.c
@@ -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 *p;
- int delim;
- char_u *end;
-
+ 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)
diff --git a/src/proto/ex_docmd.pro b/src/proto/ex_docmd.pro
index 50a2c0c2ad..bfd4f056d8 100644
--- a/src/proto/ex_docmd.pro
+++ b/src/proto/ex_docmd.pro
@@ -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);
diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim
index 8d4b7cc604..851811b199 100644
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index 8afd943b93..d96c6a5d2f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -795,6 +795,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 282,
+/**/
281,
/**/
280,