Merge pull request #17194 from zeertzjq/inccommand-prev-sub

fix(inccommand): do not change reg_prev_sub when previewing
This commit is contained in:
zeertzjq 2022-02-06 10:18:59 +08:00 committed by GitHub
commit 8215c05945
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 84 additions and 5 deletions

View File

@ -3652,8 +3652,14 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
// We do it here once to avoid it to be replaced over and over again.
// But don't do it when it starts with "\=", then it's an expression.
assert(sub != NULL);
bool sub_needs_free = false;
if (!(sub[0] == '\\' && sub[1] == '=')) {
char_u *source = sub;
sub = regtilde(sub, p_magic);
// When previewing, the new pattern allocated by regtilde() needs to be freed
// in this function because it will not be used or freed by regtilde() later.
sub_needs_free = preview && sub != source;
}
// Check for a match on each line.
@ -4450,6 +4456,10 @@ skip:
kv_destroy(preview_lines.subresults);
if (sub_needs_free) {
xfree(sub);
}
return preview_buf;
#undef ADJUST_SUB_FIRSTLNUM
#undef PUSH_PREVIEW_LINES

View File

@ -6534,11 +6534,16 @@ char_u *regtilde(char_u *source, int magic)
}
}
xfree(reg_prev_sub);
if (newsub != source) /* newsub was allocated, just keep it */
reg_prev_sub = newsub;
else /* no ~ found, need to save newsub */
reg_prev_sub = vim_strsave(newsub);
// Only change reg_prev_sub when not previewing.
if (!(State & CMDPREVIEW)) {
xfree(reg_prev_sub);
if (newsub != source) { // newsub was allocated, just keep it
reg_prev_sub = newsub;
} else { // no ~ found, need to save newsub
reg_prev_sub = vim_strsave(newsub);
}
}
return newsub;
}

View File

@ -293,6 +293,70 @@ describe(":substitute, 'inccommand' preserves", function()
end)
end
for _, case in ipairs({'', 'split', 'nosplit'}) do
it('previous substitute string ~ (inccommand='..case..') #12109', function()
local screen = Screen.new(30,10)
common_setup(screen, case, default_text)
feed(':%s/Inc/SUB<CR>')
expect([[
SUB substitution on
two lines
]])
feed(':%s/line/')
poke_eventloop()
feed('~')
poke_eventloop()
feed('<CR>')
expect([[
SUB substitution on
two SUBs
]])
feed(':%s/sti/')
poke_eventloop()
feed('~')
poke_eventloop()
feed('B')
poke_eventloop()
feed('<CR>')
expect([[
SUB subSUBBtution on
two SUBs
]])
feed(':%s/ion/NEW<CR>')
expect([[
SUB subSUBBtutNEW on
two SUBs
]])
feed(':%s/two/')
poke_eventloop()
feed('N')
poke_eventloop()
feed('~')
poke_eventloop()
feed('<CR>')
expect([[
SUB subSUBBtutNEW on
NNEW SUBs
]])
feed(':%s/bS/')
poke_eventloop()
feed('~')
poke_eventloop()
feed('W')
poke_eventloop()
feed('<CR>')
expect([[
SUB suNNEWWUBBtutNEW on
NNEW SUBs
]])
end)
end
end)
describe(":substitute, 'inccommand' preserves undo", function()