aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-11-05 17:34:21 -0800
committerJustin M. Keyes <justinkz@gmail.com>2019-11-05 17:34:21 -0800
commit3e21d498362f8cfff7ee467be6402fb00a53eeb5 (patch)
treecffcd0e03a35fc4f8496e1eac084913c31bc5a1e
parent610755ff62049bd38cc72524a26ac0a27d951c3c (diff)
parent4f124702c079fba4502b077c8c832538c0f0b386 (diff)
downloadrneovim-3e21d498362f8cfff7ee467be6402fb00a53eeb5.tar.gz
rneovim-3e21d498362f8cfff7ee467be6402fb00a53eeb5.tar.bz2
rneovim-3e21d498362f8cfff7ee467be6402fb00a53eeb5.zip
Merge #11319 'inccommand: fix issues with modifiers and prompting'
-rwxr-xr-xscripts/shadacat.py2
-rw-r--r--src/nvim/ex_cmds.c6
-rw-r--r--src/nvim/ex_docmd.c31
-rw-r--r--src/nvim/ex_getln.c2
-rw-r--r--test/functional/ui/inccommand_spec.lua100
5 files changed, 130 insertions, 11 deletions
diff --git a/scripts/shadacat.py b/scripts/shadacat.py
index 89846427a5..2b71fc2385 100755
--- a/scripts/shadacat.py
+++ b/scripts/shadacat.py
@@ -66,7 +66,7 @@ except IndexError:
def filt(entry): return True
else:
_filt = filt
- def filt(entry): return eval(_filt, globals(), {'entry': entry})
+ def filt(entry): return eval(_filt, globals(), {'entry': entry}) # noqa
poswidth = len(str(os.stat(fname).st_size or 1000))
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 04aa8f7ef6..1b6d9b50e9 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -5540,6 +5540,7 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr,
// We keep a special-purpose buffer around, but don't assume it exists.
buf_T *preview_buf = bufnr ? buflist_findnr(bufnr) : 0;
+ cmdmod.split = 0; // disable :leftabove/botright modifiers
cmdmod.tab = 0; // disable :tab modifier
cmdmod.noswapfile = true; // disable swap for preview buffer
// disable file info message
@@ -5586,6 +5587,9 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr,
highest_num_line = kv_last(lines.subresults).end.lnum;
col_width = log10(highest_num_line) + 1 + 3;
}
+ } else {
+ // Failed to split the window, don't show 'inccommand' preview.
+ preview_buf = NULL;
}
char *str = NULL; // construct the line to show in here
@@ -5598,7 +5602,7 @@ static buf_T *show_sub(exarg_T *eap, pos_T old_cusr,
for (size_t matchidx = 0; matchidx < lines.subresults.size; matchidx++) {
SubResult match = lines.subresults.items[matchidx];
- if (split && preview_buf) {
+ if (preview_buf) {
lpos_T p_start = { 0, match.start.col }; // match starts here in preview
lpos_T p_end = { 0, match.end.col }; // ... and ends here
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index da0184aa45..d3e2120721 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -1201,6 +1201,23 @@ static void get_wincmd_addr_type(char_u *arg, exarg_T *eap)
}
}
+/// Skip colons and trailing whitespace, returning a pointer to the first
+/// non-colon, non-whitespace character.
+//
+/// @param skipleadingwhite Skip leading whitespace too
+static char_u *skip_colon_white(const char_u *p, bool skipleadingwhite)
+{
+ if (skipleadingwhite) {
+ p = skipwhite(p);
+ }
+
+ while (*p == ':') {
+ p = skipwhite(p + 1);
+ }
+
+ return (char_u *)p;
+}
+
/*
* Execute one Ex command.
*
@@ -1705,9 +1722,7 @@ static char_u * do_one_cmd(char_u **cmdlinep,
/*
* Skip ':' and any white space
*/
- ea.cmd = skipwhite(ea.cmd);
- while (*ea.cmd == ':')
- ea.cmd = skipwhite(ea.cmd + 1);
+ ea.cmd = skip_colon_white(ea.cmd, true);
/*
* If we got a line, but no command, then go to the line.
@@ -3580,9 +3595,8 @@ char_u *skip_range(
++cmd;
}
- /* Skip ":" and white space. */
- while (*cmd == ':')
- cmd = skipwhite(cmd + 1);
+ // Skip ":" and white space.
+ cmd = skip_colon_white(cmd, false);
return (char_u *)cmd;
}
@@ -10206,10 +10220,13 @@ bool cmd_can_preview(char_u *cmd)
return false;
}
+ // Ignore additional colons at the start...
+ cmd = skip_colon_white(cmd, true);
+
// Ignore any leading modifiers (:keeppatterns, :verbose, etc.)
for (int len = modifier_len(cmd); len != 0; len = modifier_len(cmd)) {
cmd += len;
- cmd = skipwhite(cmd);
+ cmd = skip_colon_white(cmd, true);
}
exarg_T ea;
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index f2665ca0b5..9e2671ca5e 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -1927,7 +1927,9 @@ static int command_line_changed(CommandLineState *s)
// - Immediately undo the effects.
State |= CMDPREVIEW;
emsg_silent++; // Block error reporting as the command may be incomplete
+ msg_silent++; // Block messages, namely ones that prompt
do_cmdline(ccline.cmdbuff, NULL, NULL, DOCMD_KEEPLINE|DOCMD_NOWAIT);
+ msg_silent--; // Unblock messages
emsg_silent--; // Unblock error reporting
// Restore the window "view".
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index d60cd08fb0..b841574643 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -88,14 +88,14 @@ local function common_setup(screen, inccommand, text)
})
end
- command("set inccommand=" .. (inccommand and inccommand or ""))
+ command("set inccommand=" .. (inccommand or ""))
if text then
insert(text)
end
end
-describe(":substitute, inccommand=split", function()
+describe(":substitute, inccommand=split interactivity", function()
before_each(function()
clear()
common_setup(nil, "split", default_text)
@@ -779,6 +779,59 @@ describe(":substitute, inccommand=split", function()
{15:~ }|
:silent tabedit %s/tw/to^ |
]])
+ feed('<Esc>')
+
+ -- leading colons
+ feed(':::%s/tw/to')
+ screen:expect{any=[[{12:to}o lines]]}
+ feed('<Esc>')
+ screen:expect{any=[[two lines]]}
+ end)
+
+ it("ignores new-window modifiers when splitting the preview window", function()
+ -- one modifier
+ feed(':topleft %s/tw/to')
+ screen:expect([[
+ Inc substitution on |
+ {12:to}o lines |
+ Inc substitution on |
+ {12:to}o lines |
+ |
+ {11:[No Name] [+] }|
+ |2| {12:to}o lines |
+ |4| {12:to}o lines |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :topleft %s/tw/to^ |
+ ]])
+ feed('<Esc>')
+ screen:expect{any=[[two lines]]}
+
+ -- multiple modifiers
+ feed(':topleft vert %s/tw/to')
+ screen:expect([[
+ Inc substitution on |
+ {12:to}o lines |
+ Inc substitution on |
+ {12:to}o lines |
+ |
+ {11:[No Name] [+] }|
+ |2| {12:to}o lines |
+ |4| {12:to}o lines |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :topleft vert %s/tw/to^ |
+ ]])
+ feed('<Esc>')
+ screen:expect{any=[[two lines]]}
end)
it('shows split window when typing the pattern', function()
@@ -2529,6 +2582,49 @@ describe(":substitute", function()
:%s/some\(thing\)\@!/every/^ |
]])
end)
+
+ it("doesn't prompt to swap cmd range", function()
+ screen = Screen.new(50, 8) -- wide to avoid hit-enter prompt
+ common_setup(screen, "split", default_text)
+ feed(':2,1s/tw/MO/g')
+
+ -- substitution preview should have been made, without prompting
+ screen:expect([[
+ {12:MO}o lines |
+ {11:[No Name] [+] }|
+ |2| {12:MO}o lines |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ :2,1s/tw/MO/g^ |
+ ]])
+
+ -- but should be prompted on hitting enter
+ feed('<CR>')
+ screen:expect([[
+ {12:MO}o lines |
+ {11:[No Name] [+] }|
+ |2| {12:MO}o lines |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {10:[Preview] }|
+ {13:Backwards range given, OK to swap (y/n)?}^ |
+ ]])
+
+ feed('y')
+ screen:expect([[
+ Inc substitution on |
+ ^MOo lines |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {13:Backwards range given, OK to swap (y/n)?}y |
+ ]])
+ end)
end)
it(':substitute with inccommand during :terminal activity', function()