mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:8.1.0282: 'incsearch' does not work with command modifiers
Problem: 'incsearch' does not work with command modifiers.
Solution: Skip command modifiers.
33c4dbb74b
This commit is contained in:
parent
ba59ee9a15
commit
b24dabf266
@ -1269,17 +1269,17 @@ static char_u * do_one_cmd(char_u **cmdlinep,
|
|||||||
goto doend;
|
goto doend;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
// 1. Skip comment lines and leading white space and colons.
|
||||||
* Repeat until no more command modifiers are found.
|
// 2. Handle command modifiers.
|
||||||
* The "ea" structure holds the arguments that can be used.
|
|
||||||
*/
|
// The "ea" structure holds the arguments that can be used.
|
||||||
ea.cmd = *cmdlinep;
|
ea.cmd = *cmdlinep;
|
||||||
ea.cmdlinep = cmdlinep;
|
ea.cmdlinep = cmdlinep;
|
||||||
ea.getline = fgetline;
|
ea.getline = fgetline;
|
||||||
ea.cookie = cookie;
|
ea.cookie = cookie;
|
||||||
ea.cstack = cstack;
|
ea.cstack = cstack;
|
||||||
|
|
||||||
if (parse_command_modifiers(&ea, &errormsg) == FAIL) {
|
if (parse_command_modifiers(&ea, &errormsg, false) == FAIL) {
|
||||||
goto doend;
|
goto doend;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1994,16 +1994,7 @@ doend:
|
|||||||
if (ea.verbose_save >= 0) {
|
if (ea.verbose_save >= 0) {
|
||||||
p_verbose = ea.verbose_save;
|
p_verbose = ea.verbose_save;
|
||||||
}
|
}
|
||||||
if (cmdmod.save_ei != NULL) {
|
free_cmdmod();
|
||||||
/* 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
cmdmod = save_cmdmod;
|
cmdmod = save_cmdmod;
|
||||||
reg_executing = save_reg_executing;
|
reg_executing = save_reg_executing;
|
||||||
@ -2045,11 +2036,14 @@ doend:
|
|||||||
// - store flags in "cmdmod".
|
// - store flags in "cmdmod".
|
||||||
// - Set ex_pressedreturn for an empty command line.
|
// - Set ex_pressedreturn for an empty command line.
|
||||||
// - set msg_silent for ":silent"
|
// - set msg_silent for ":silent"
|
||||||
|
// - set 'eventignore' to "all" for ":noautocmd"
|
||||||
// - set p_verbose for ":verbose"
|
// - set p_verbose for ":verbose"
|
||||||
// - Increment "sandbox" for ":sandbox"
|
// - 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.
|
// Return FAIL when the command is not to be executed.
|
||||||
// May set "errormsg" to an error message.
|
// 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;
|
char_u *p;
|
||||||
|
|
||||||
@ -2057,10 +2051,8 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
|||||||
eap->verbose_save = -1;
|
eap->verbose_save = -1;
|
||||||
eap->save_msg_silent = -1;
|
eap->save_msg_silent = -1;
|
||||||
|
|
||||||
|
// Repeat until no more command modifiers are found.
|
||||||
for (;; ) {
|
for (;; ) {
|
||||||
/*
|
|
||||||
* 1. Skip comment lines and leading white space and colons.
|
|
||||||
*/
|
|
||||||
while (*eap->cmd == ' '
|
while (*eap->cmd == ' '
|
||||||
|| *eap->cmd == '\t'
|
|| *eap->cmd == '\t'
|
||||||
|| *eap->cmd == ':') {
|
|| *eap->cmd == ':') {
|
||||||
@ -2073,7 +2065,9 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
|||||||
|| getline_equal(eap->getline, eap->cookie, getexline))
|
|| getline_equal(eap->getline, eap->cookie, getexline))
|
||||||
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
|
&& curwin->w_cursor.lnum < curbuf->b_ml.ml_line_count) {
|
||||||
eap->cmd = (char_u *)"+";
|
eap->cmd = (char_u *)"+";
|
||||||
ex_pressedreturn = true;
|
if (!skip_only) {
|
||||||
|
ex_pressedreturn = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ignore comment and empty lines
|
// ignore comment and empty lines
|
||||||
@ -2081,13 +2075,12 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
if (*eap->cmd == NUL) {
|
if (*eap->cmd == NUL) {
|
||||||
ex_pressedreturn = true;
|
if (!skip_only) {
|
||||||
|
ex_pressedreturn = true;
|
||||||
|
}
|
||||||
return FAIL;
|
return FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* 2. Handle command modifiers.
|
|
||||||
*/
|
|
||||||
p = skip_range(eap->cmd, NULL);
|
p = skip_range(eap->cmd, NULL);
|
||||||
switch (*p) {
|
switch (*p) {
|
||||||
// When adding an entry, also modify cmd_exists().
|
// When adding an entry, also modify cmd_exists().
|
||||||
@ -2146,13 +2139,20 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
|||||||
break;
|
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) {
|
if (p == NULL || *p == NUL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
cmdmod.filter_regmatch.regprog = vim_regcomp(reg_pat, RE_MAGIC);
|
if (!skip_only) {
|
||||||
if (cmdmod.filter_regmatch.regprog == NULL) {
|
cmdmod.filter_regmatch.regprog = vim_regcomp(reg_pat, RE_MAGIC);
|
||||||
break;
|
if (cmdmod.filter_regmatch.regprog == NULL) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
eap->cmd = p;
|
eap->cmd = p;
|
||||||
continue;
|
continue;
|
||||||
@ -2179,7 +2179,7 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
|||||||
|
|
||||||
case 'n':
|
case 'n':
|
||||||
if (checkforcmd(&eap->cmd, "noautocmd", 3)) {
|
if (checkforcmd(&eap->cmd, "noautocmd", 3)) {
|
||||||
if (cmdmod.save_ei == NULL) {
|
if (cmdmod.save_ei == NULL && !skip_only) {
|
||||||
// Set 'eventignore' to "all". Restore the
|
// Set 'eventignore' to "all". Restore the
|
||||||
// existing option value later.
|
// existing option value later.
|
||||||
cmdmod.save_ei = vim_strsave(p_ei);
|
cmdmod.save_ei = vim_strsave(p_ei);
|
||||||
@ -2200,24 +2200,30 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) {
|
case 's': if (checkforcmd(&eap->cmd, "sandbox", 3)) {
|
||||||
if (!eap->did_sandbox) {
|
if (!skip_only) {
|
||||||
sandbox++;
|
if (!eap->did_sandbox) {
|
||||||
|
sandbox++;
|
||||||
|
}
|
||||||
|
eap->did_sandbox = true;
|
||||||
}
|
}
|
||||||
eap->did_sandbox = true;
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!checkforcmd(&eap->cmd, "silent", 3)) {
|
if (!checkforcmd(&eap->cmd, "silent", 3)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (eap->save_msg_silent == -1) {
|
if (!skip_only) {
|
||||||
eap->save_msg_silent = msg_silent;
|
if (eap->save_msg_silent == -1) {
|
||||||
|
eap->save_msg_silent = msg_silent;
|
||||||
|
}
|
||||||
|
msg_silent++;
|
||||||
}
|
}
|
||||||
msg_silent++;
|
|
||||||
if (*eap->cmd == '!' && !ascii_iswhite(eap->cmd[-1])) {
|
if (*eap->cmd == '!' && !ascii_iswhite(eap->cmd[-1])) {
|
||||||
// ":silent!", but not "silent !cmd"
|
// ":silent!", but not "silent !cmd"
|
||||||
eap->cmd = skipwhite(eap->cmd + 1);
|
eap->cmd = skipwhite(eap->cmd + 1);
|
||||||
emsg_silent++;
|
if (!skip_only) {
|
||||||
eap->did_esilent++;
|
emsg_silent++;
|
||||||
|
eap->did_esilent++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -2245,10 +2251,12 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
|||||||
|
|
||||||
case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
|
case 'u': if (!checkforcmd(&eap->cmd, "unsilent", 3))
|
||||||
break;
|
break;
|
||||||
if (eap->save_msg_silent == -1) {
|
if (!skip_only) {
|
||||||
eap->save_msg_silent = msg_silent;
|
if (eap->save_msg_silent == -1) {
|
||||||
|
eap->save_msg_silent = msg_silent;
|
||||||
|
}
|
||||||
|
msg_silent = 0;
|
||||||
}
|
}
|
||||||
msg_silent = 0;
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 'v': if (checkforcmd(&eap->cmd, "vertical", 4)) {
|
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))
|
if (!checkforcmd(&p, "verbose", 4))
|
||||||
break;
|
break;
|
||||||
if (eap->verbose_save < 0) {
|
if (!skip_only) {
|
||||||
eap->verbose_save = p_verbose;
|
if (eap->verbose_save < 0) {
|
||||||
}
|
eap->verbose_save = p_verbose;
|
||||||
if (ascii_isdigit(*eap->cmd)) {
|
}
|
||||||
p_verbose = atoi((char *)eap->cmd);
|
if (ascii_isdigit(*eap->cmd)) {
|
||||||
} else {
|
p_verbose = atoi((char *)eap->cmd);
|
||||||
p_verbose = 1;
|
} else {
|
||||||
|
p_verbose = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
eap->cmd = p;
|
eap->cmd = p;
|
||||||
continue;
|
continue;
|
||||||
@ -2274,6 +2284,22 @@ int parse_command_modifiers(exarg_T *eap, char_u **errormsg)
|
|||||||
return OK;
|
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".
|
// Parse the address range, if any, in "eap".
|
||||||
// Return FAIL and set "errormsg" or return OK.
|
// Return FAIL and set "errormsg" or return OK.
|
||||||
int parse_cmd_address(exarg_T *eap, char_u **errormsg)
|
int parse_cmd_address(exarg_T *eap, char_u **errormsg)
|
||||||
|
@ -287,11 +287,24 @@ static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (firstc == ':') {
|
if (firstc == ':') {
|
||||||
char_u *cmd = skip_range(ccline.cmdbuff, NULL);
|
char_u *cmd;
|
||||||
|
cmdmod_T save_cmdmod = cmdmod;
|
||||||
char_u *p;
|
char_u *p;
|
||||||
int delim;
|
int delim;
|
||||||
char_u *end;
|
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') {
|
if (*cmd == 's' || *cmd == 'g' || *cmd == 'v') {
|
||||||
// Skip over "substitute" to find the pattern separator.
|
// Skip over "substitute" to find the pattern separator.
|
||||||
for (p = cmd; ASCII_ISALPHA(*p); p++) {}
|
for (p = cmd; ASCII_ISALPHA(*p); p++) {}
|
||||||
@ -310,8 +323,6 @@ static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s,
|
|||||||
delim = *p++;
|
delim = *p++;
|
||||||
end = skip_regexp(p, delim, p_magic, NULL);
|
end = skip_regexp(p, delim, p_magic, NULL);
|
||||||
if (end > p || *end == delim) {
|
if (end > p || *end == delim) {
|
||||||
char_u *dummy;
|
|
||||||
exarg_T ea;
|
|
||||||
pos_T save_cursor = curwin->w_cursor;
|
pos_T save_cursor = curwin->w_cursor;
|
||||||
|
|
||||||
// found a non-empty pattern
|
// found a non-empty pattern
|
||||||
@ -319,11 +330,6 @@ static bool do_incsearch_highlighting(int firstc, incsearch_state_T *s,
|
|||||||
*patlen = (int)(end - p);
|
*patlen = (int)(end - p);
|
||||||
|
|
||||||
// parse the address range
|
// 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;
|
curwin->w_cursor = s->search_start;
|
||||||
parse_cmd_address(&ea, &dummy);
|
parse_cmd_address(&ea, &dummy);
|
||||||
if (ea.addr_count > 0) {
|
if (ea.addr_count > 0) {
|
||||||
|
@ -659,6 +659,12 @@ func Test_incsearch_substitute_dump()
|
|||||||
call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
|
call VerifyScreenDump(buf, 'Test_incsearch_substitute_05', {})
|
||||||
call term_sendkeys(buf, "\<Esc>")
|
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 StopVimInTerminal(buf)
|
||||||
call delete('Xis_subst_script')
|
call delete('Xis_subst_script')
|
||||||
endfunc
|
endfunc
|
||||||
|
Loading…
Reference in New Issue
Block a user