]> granicus.if.org Git - vim/commitdiff
patch 8.1.0282: 'incsearch' does not work with command modifiers v8.1.0282
authorBram Moolenaar <Bram@vim.org>
Tue, 14 Aug 2018 14:06:16 +0000 (16:06 +0200)
committerBram Moolenaar <Bram@vim.org>
Tue, 14 Aug 2018 14:06:16 +0000 (16:06 +0200)
Problem:    'incsearch' does not work with command modifiers.
Solution:   Skip command modifiers.

src/ex_docmd.c
src/ex_getln.c
src/proto/ex_docmd.pro
src/testdir/test_search.vim
src/version.c

index 9491e235d91abae181fb923c84066ded3430584c..169cb7a64e96481bf11d3c7bffa99838bc3b9ef5 100644 (file)
@@ -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;
        }
@@ -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.
index fb16743f0c01fe18163e795dcc651680986740c7..a8c5cfb001cb4f5bf7dfd84d043fb0242f1927bd 100644 (file)
@@ -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)
index 50a2c0c2ad3dd854f5666bd0bfdaf3be61c2ddb5..bfd4f056d8bd8d451e0921dd5519ab264c2f7245 100644 (file)
@@ -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);
index 8d4b7cc604bec6b91367305b8bbb7975fd58a540..851811b199ca07e3bf07884432b43e523c877a8d 100644 (file)
@@ -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
index 8afd943b93abf760a5a44a1f0b50a82d82865ec6..d96c6a5d2f9c413475b7ca37f7369da14de65cd4 100644 (file)
@@ -794,6 +794,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    282,
 /**/
     281,
 /**/