# HG changeset patch # User Christian Brabandt # Date 1534256104 -7200 # Node ID 213f1a519378b691a14a29f0c471be5d0e7894e8 # Parent 2e7cca4372f330cb063bced629c31a731911ffa8 patch 8.1.0282: 'incsearch' does not work with command modifiers commit https://github.com/vim/vim/commit/33c4dbb74bdf41aadd193a704f597d4df20f0e47 Author: Bram Moolenaar Date: Tue Aug 14 16:06:16 2018 +0200 patch 8.1.0282: 'incsearch' does not work with command modifiers Problem: 'incsearch' does not work with command modifiers. Solution: Skip command modifiers. diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -68,6 +68,7 @@ static char_u *do_one_cmd(char_u **, int 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, ch 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, ch && 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, ch 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, ch if (*p == NUL || ends_excmd(*p)) break; } - p = skip_vimgrep_pat(p, ®_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, ®_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, ch 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, ch 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, ch 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, ch } 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, ch } /* + * 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 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -283,11 +283,24 @@ do_incsearch_highlighting(int firstc, in 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, in 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, in *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 --- 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 --- 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, "\") + " 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, "\") + call StopVimInTerminal(buf) call delete('Xis_subst_script') endfunc diff --git a/src/version.c b/src/version.c --- 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,