aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2025-04-09 23:10:51 -0600
committerJosh Rahm <joshuarahm@gmail.com>2025-04-16 17:41:19 +0000
commitd9f4bc7bbd305c0a0a57ee78f99f8349ff97964e (patch)
tree5eaec96065860fccefad1ff47f64e6e7fc6ed231
parent2034a8419e1c5675592cdd0d0ffeaadfda58001a (diff)
downloadrneovim-d9f4bc7bbd305c0a0a57ee78f99f8349ff97964e.tar.gz
rneovim-d9f4bc7bbd305c0a0a57ee78f99f8349ff97964e.tar.bz2
rneovim-d9f4bc7bbd305c0a0a57ee78f99f8349ff97964e.zip
fix(repeat_cmdline): Save the repeat_cmdline when calling a userfunc.userregs_2
There's a very subtle bug when calling a userfunc where the redo buffer is saved, but the repeat_cmdline is not. This causes the redo buffer on do-repeat to call the most recently executed userfunc rather than the userfunc it should be dot-repeating. This is only an issue when trying to dot-repeat a userfunction within a user function. I found this bug when experimenting with using text motions, specifically the Z* verbs in fieldmarshal. Specifically the Z* motions (for inserting/appending before/after a text object) would be dot-repeatable for builtin text objects, but would not be dot-repeatable for user-defined text objects.
-rw-r--r--src/nvim/eval/userfunc.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/src/nvim/eval/userfunc.c b/src/nvim/eval/userfunc.c
index 89bb1dca9b..52db600010 100644
--- a/src/nvim/eval/userfunc.c
+++ b/src/nvim/eval/userfunc.c
@@ -1006,6 +1006,7 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
bool started_profiling = false;
bool did_save_redo = false;
save_redo_T save_redo;
+ char* saved_repeat_cmdline = NULL;
// If depth of calling is getting too high, don't execute the function
if (depth >= p_mfd) {
@@ -1018,6 +1019,9 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
// Save search patterns and redo buffer.
save_search_patterns();
if (!ins_compl_active()) {
+ if (repeat_cmdline) {
+ saved_repeat_cmdline = xstrdup(repeat_cmdline);
+ }
saveRedobuff(&save_redo);
did_save_redo = true;
}
@@ -1362,6 +1366,8 @@ void call_user_func(ufunc_T *fp, int argcount, typval_T *argvars, typval_T *rett
// restore search patterns and redo buffer
if (did_save_redo) {
restoreRedobuff(&save_redo);
+ xfree(repeat_cmdline);
+ repeat_cmdline = saved_repeat_cmdline;
}
restore_search_patterns();
}