summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/ex_cmds2.c30
-rw-r--r--src/globals.h4
-rw-r--r--src/message.c9
-rw-r--r--src/testdir/test_timers.vim18
-rw-r--r--src/version.c2
5 files changed, 49 insertions, 14 deletions
diff --git a/src/ex_cmds2.c b/src/ex_cmds2.c
index 18930a6cfb..710a2789e8 100644
--- a/src/ex_cmds2.c
+++ b/src/ex_cmds2.c
@@ -1219,30 +1219,40 @@ check_due_timer(void)
{
int save_timer_busy = timer_busy;
int save_vgetc_busy = vgetc_busy;
- int did_emsg_save = did_emsg;
- int called_emsg_save = called_emsg;
- int did_throw_save = did_throw;
+ int save_did_emsg = did_emsg;
+ int save_called_emsg = called_emsg;
int save_must_redraw = must_redraw;
+ int save_trylevel = trylevel;
+ int save_did_throw = did_throw;
+ except_T *save_current_exception = current_exception;
+ /* Create a scope for running the timer callback, ignoring most of
+ * the current scope, such as being inside a try/catch. */
timer_busy = timer_busy > 0 || vgetc_busy > 0;
vgetc_busy = 0;
called_emsg = FALSE;
+ did_emsg = FALSE;
+ did_uncaught_emsg = FALSE;
must_redraw = 0;
+ trylevel = 0;
+ did_throw = FALSE;
+ current_exception = NULL;
+
timer->tr_firing = TRUE;
timer_callback(timer);
timer->tr_firing = FALSE;
+
timer_next = timer->tr_next;
did_one = TRUE;
timer_busy = save_timer_busy;
vgetc_busy = save_vgetc_busy;
- if (called_emsg)
- {
+ if (did_uncaught_emsg)
++timer->tr_emsg_count;
- if (!did_throw_save && did_throw && current_exception != NULL)
- discard_current_exception();
- }
- did_emsg = did_emsg_save;
- called_emsg = called_emsg_save;
+ did_emsg = save_did_emsg;
+ called_emsg = save_called_emsg;
+ trylevel = save_trylevel;
+ did_throw = save_did_throw;
+ current_exception = save_current_exception;
if (must_redraw != 0)
need_update_screen = TRUE;
must_redraw = must_redraw > save_must_redraw
diff --git a/src/globals.h b/src/globals.h
index 0b887d35bb..ac2727f7c8 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -182,6 +182,10 @@ EXTERN dict_T globvardict; /* Dictionary with g: variables */
#endif
EXTERN int did_emsg; /* set by emsg() when the message
is displayed or thrown */
+#ifdef FEAT_EVAL
+EXTERN int did_uncaught_emsg; /* emsg() was called and did not
+ cause an exception */
+#endif
EXTERN int did_emsg_syntax; /* did_emsg set because of a
syntax error */
EXTERN int called_emsg; /* always set by emsg() */
diff --git a/src/message.c b/src/message.c
index 57f33dd87c..af22607591 100644
--- a/src/message.c
+++ b/src/message.c
@@ -609,11 +609,9 @@ emsg(char_u *s)
called_emsg = TRUE;
- /*
- * If "emsg_severe" is TRUE: When an error exception is to be thrown,
- * prefer this message over previous messages for the same command.
- */
#ifdef FEAT_EVAL
+ /* If "emsg_severe" is TRUE: When an error exception is to be thrown,
+ * prefer this message over previous messages for the same command. */
severe = emsg_severe;
emsg_severe = FALSE;
#endif
@@ -684,6 +682,9 @@ emsg(char_u *s)
else
flush_buffers(FALSE); /* flush internal buffers */
did_emsg = TRUE; /* flag for DoOneCmd() */
+#ifdef FEAT_EVAL
+ did_uncaught_emsg = TRUE;
+#endif
}
emsg_on_display = TRUE; /* remember there is an error message */
diff --git a/src/testdir/test_timers.vim b/src/testdir/test_timers.vim
index c9171b7b96..b5b9d67db1 100644
--- a/src/testdir/test_timers.vim
+++ b/src/testdir/test_timers.vim
@@ -208,6 +208,24 @@ func Test_timer_errors()
call assert_equal(3, g:call_count)
endfunc
+func FuncWithCaughtError(timer)
+ let g:call_count += 1
+ try
+ doesnotexist
+ catch
+ " nop
+ endtry
+endfunc
+
+func Test_timer_catch_error()
+ let g:call_count = 0
+ let timer = timer_start(10, 'FuncWithCaughtError', {'repeat': 4})
+ " Timer will not be stopped.
+ call WaitFor('g:call_count == 4')
+ sleep 50m
+ call assert_equal(4, g:call_count)
+endfunc
+
func FeedAndPeek(timer)
call test_feedinput('a')
call getchar(1)
diff --git a/src/version.c b/src/version.c
index a3ab6edf54..2ce3d26d37 100644
--- a/src/version.c
+++ b/src/version.c
@@ -770,6 +770,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 1067,
+/**/
1066,
/**/
1065,