aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ex_cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r--src/nvim/ex_cmds.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 71b3517adc..65cb544efd 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -3627,15 +3627,22 @@ static buf_T *do_sub(exarg_T *eap, proftime_T timeout, bool do_buf_event, handle
sub_firstline = NULL;
- // ~ in the substitute pattern is replaced with the old pattern.
- // 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 *sub_copy = NULL;
+
+ // If the substitute pattern starts with "\=" then it's an expression.
+ // Make a copy, a recursive function may free it.
+ // Otherwise, '~' in the substitute pattern is replaced with the old
+ // pattern. We do it here once to avoid it to be replaced over and over
+ // again.
+ if (sub[0] == '\\' && sub[1] == '=') {
+ sub = vim_strsave(sub);
+ sub_copy = sub;
+ } else {
char_u *source = sub;
- sub = regtilde(sub, p_magic);
+ sub = regtilde(sub, p_magic, preview);
// 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;
@@ -4412,6 +4419,10 @@ skip:
}
vim_regfree(regmatch.regprog);
+ xfree(sub_copy);
+ if (sub_needs_free) {
+ xfree(sub);
+ }
// Restore the flag values, they can be used for ":&&".
subflags.do_all = save_do_all;
@@ -4444,10 +4455,6 @@ skip:
kv_destroy(preview_lines.subresults);
- if (sub_needs_free) {
- xfree(sub);
- }
-
return preview_buf;
#undef ADJUST_SUB_FIRSTLNUM
#undef PUSH_PREVIEW_LINES