diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/ex_docmd.c | 120 | ||||
-rw-r--r-- | src/nvim/ex_getln.c | 22 | ||||
-rw-r--r-- | src/nvim/testdir/test_search.vim | 6 |
3 files changed, 93 insertions, 55 deletions
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 9b0e05b19f..faafd511b1 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1269,17 +1269,17 @@ static char_u * do_one_cmd(char_u **cmdlinep, 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; ea.cookie = cookie; ea.cstack = cstack; - if (parse_command_modifiers(&ea, &errormsg) == FAIL) { + if (parse_command_modifiers(&ea, &errormsg, false) == FAIL) { goto doend; } @@ -1994,16 +1994,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; reg_executing = save_reg_executing; @@ -2045,11 +2036,14 @@ 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) +int parse_command_modifiers(exarg_T *eap, char_u **errormsg, bool skip_only) { char_u *p; @@ -2057,10 +2051,8 @@ int 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 == ':') { @@ -2073,7 +2065,9 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg) || getline_equal(eap->getline, eap->cookie, getexline)) && 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 @@ -2081,13 +2075,12 @@ int 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) { // When adding an entry, also modify cmd_exists(). @@ -2146,13 +2139,20 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg) 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 = vim_regcomp(reg_pat, RE_MAGIC); - if (cmdmod.filter_regmatch.regprog == NULL) { - 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; @@ -2179,7 +2179,7 @@ int 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. cmdmod.save_ei = vim_strsave(p_ei); @@ -2200,24 +2200,30 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg) continue; case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) { - if (!eap->did_sandbox) { - sandbox++; + if (!skip_only) { + if (!eap->did_sandbox) { + sandbox++; + } + eap->did_sandbox = true; } - eap->did_sandbox = true; continue; } if (!checkforcmd(&eap->cmd, "silent", 3)) { break; } - if (eap->save_msg_silent == -1) { - eap->save_msg_silent = msg_silent; + if (!skip_only) { + if (eap->save_msg_silent == -1) { + eap->save_msg_silent = msg_silent; + } + msg_silent++; } - msg_silent++; if (*eap->cmd == '!' && !ascii_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; @@ -2245,10 +2251,12 @@ int 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; + if (!skip_only) { + if (eap->save_msg_silent == -1) { + eap->save_msg_silent = msg_silent; + } + msg_silent = 0; } - msg_silent = 0; continue; case 'v': if (checkforcmd(&eap->cmd, "vertical", 4)) { @@ -2257,13 +2265,15 @@ int 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 (ascii_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 (ascii_isdigit(*eap->cmd)) { + p_verbose = atoi((char *)eap->cmd); + } else { + p_verbose = 1; + } } eap->cmd = p; continue; @@ -2274,6 +2284,22 @@ int 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. int parse_cmd_address(exarg_T *eap, char_u **errormsg) diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 9769d5f58b..2e10fbff91 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -287,11 +287,24 @@ static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s, 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; + 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. for (p = cmd; ASCII_ISALPHA(*p); p++) {} @@ -310,8 +323,6 @@ static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s, delim = *p++; 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 @@ static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s, *patlen = (int)(end - p); // parse the address range - memset(&ea, 0, sizeof(ea)); - ea.line1 = 1; - ea.line2 = 1; - ea.cmd = ccline.cmdbuff; - ea.addr_type = ADDR_LINES; curwin->w_cursor = s->search_start; parse_cmd_address(&ea, &dummy); if (ea.addr_count > 0) { diff --git a/src/nvim/testdir/test_search.vim b/src/nvim/testdir/test_search.vim index 01e6f2d61c..6708f30f4e 100644 --- a/src/nvim/testdir/test_search.vim +++ b/src/nvim/testdir/test_search.vim @@ -659,6 +659,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 |