diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2025-04-09 23:10:51 -0600 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2025-04-16 17:41:19 +0000 |
commit | d9f4bc7bbd305c0a0a57ee78f99f8349ff97964e (patch) | |
tree | 5eaec96065860fccefad1ff47f64e6e7fc6ed231 | |
parent | 2034a8419e1c5675592cdd0d0ffeaadfda58001a (diff) | |
download | rneovim-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.c | 6 |
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(); } |