summaryrefslogtreecommitdiffstats
path: root/src/ex_cmds2.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2018-05-12 15:38:26 +0200
committerBram Moolenaar <Bram@vim.org>2018-05-12 15:38:26 +0200
commitb0f42ba60d9e6d101d103421ba0c351811615c15 (patch)
tree083b82fcd12fc95a90d779898a6a2b9939ef7837 /src/ex_cmds2.c
parentff3be4fe1e2e723de48b826cb992c798e296c41e (diff)
patch 8.0.1817: a timer may change v:count unexpectedlyv8.0.1817
Problem: A timer may change v:count unexpectedly. Solution: Save and restore v:count and similar variables when a timer callback is invoked. (closes #2897)
Diffstat (limited to 'src/ex_cmds2.c')
-rw-r--r--src/ex_cmds2.c5
1 files changed, 5 insertions, 0 deletions
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index d27d0cdf59..01bc357f43 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1336,6 +1336,8 @@ check_due_timer(void)
this_due = proftime_time_left(&timer->tr_due, &now);
if (this_due <= 1)
{
+ /* Save and restore a lot of flags, because the timer fires while
+ * waiting for a character, which might be halfway a command. */
int save_timer_busy = timer_busy;
int save_vgetc_busy = vgetc_busy;
int save_did_emsg = did_emsg;
@@ -1345,6 +1347,7 @@ check_due_timer(void)
int save_did_throw = did_throw;
int save_ex_pressedreturn = get_pressedreturn();
except_T *save_current_exception = current_exception;
+ vimvars_save_T vvsave;
/* Create a scope for running the timer callback, ignoring most of
* the current scope, such as being inside a try/catch. */
@@ -1357,6 +1360,7 @@ check_due_timer(void)
trylevel = 0;
did_throw = FALSE;
current_exception = NULL;
+ save_vimvars(&vvsave);
timer->tr_firing = TRUE;
timer_callback(timer);
@@ -1373,6 +1377,7 @@ check_due_timer(void)
trylevel = save_trylevel;
did_throw = save_did_throw;
current_exception = save_current_exception;
+ restore_vimvars(&vvsave);
if (must_redraw != 0)
need_update_screen = TRUE;
must_redraw = must_redraw > save_must_redraw