fix(inccommand): never preview if parsing command failed (#18944)

`errormsg` is not always set when parsing the command failed (e.g. when
the range contains invalid marks). Check the return value is better.
This commit is contained in:
zeertzjq
2022-06-14 10:55:04 +08:00
committed by GitHub
parent 7f8f8d6cb7
commit 619eb32c75
2 changed files with 32 additions and 4 deletions

View File

@@ -2393,11 +2393,12 @@ static void cmdpreview_show(CommandLineState *s)
// Copy the command line so we can modify it. // Copy the command line so we can modify it.
char *cmdline = xstrdup((char *)ccline.cmdbuff); char *cmdline = xstrdup((char *)ccline.cmdbuff);
char *errormsg = NULL; char *errormsg = NULL;
emsg_off++; // Block errors when parsing the command line, and don't update v:errmsg
parse_cmdline(cmdline, &ea, &cmdinfo, &errormsg); if (!parse_cmdline(cmdline, &ea, &cmdinfo, &errormsg)) {
if (errormsg != NULL) { emsg_off--;
goto end; goto end;
} }
emsg_off--;
// Swap invalid command range if needed // Swap invalid command range if needed
if ((ea.argt & EX_RANGE) && ea.line1 > ea.line2) { if ((ea.argt & EX_RANGE) && ea.line1 > ea.line2) {
@@ -2421,7 +2422,8 @@ static void cmdpreview_show(CommandLineState *s)
cmdmod_T save_cmdmod = cmdmod; cmdmod_T save_cmdmod = cmdmod;
cmdpreview = true; cmdpreview = true;
emsg_silent++; // Block error reporting as the command may be incomplete emsg_silent++; // Block error reporting as the command may be incomplete,
// but still update v:errmsg
msg_silent++; // Block messages, namely ones that prompt msg_silent++; // Block messages, namely ones that prompt
block_autocmds(); // Block events block_autocmds(); // Block events
garray_T save_view; garray_T save_view;

View File

@@ -2947,6 +2947,32 @@ it(':substitute with inccommand, allows :redraw before first separator is typed
]]) ]])
end) end)
it(':substitute with inccommand, does nothing if range contains invalid marks', function()
local screen = Screen.new(30, 6)
clear()
command('set undolevels=-1')
common_setup(screen, 'split', 'test')
feed([[:'a,'bs]])
screen:expect([[
test |
{15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
:'a,'bs^ |
]])
feed('/')
screen:expect([[
test |
{15:~ }|
{15:~ }|
{15:~ }|
{15:~ }|
:'a,'bs/^ |
]])
eq('', eval('v:errmsg'))
end)
it(":substitute doesn't crash with inccommand, if undo is empty #12932", function() it(":substitute doesn't crash with inccommand, if undo is empty #12932", function()
local screen = Screen.new(10,5) local screen = Screen.new(10,5)
clear() clear()