diff src/getchar.c @ 18102:0d9ec3a2821f v8.1.2046

patch 8.1.2046: SafeState may be triggered at the wrong moment Commit: https://github.com/vim/vim/commit/69198cb8c08f124729c41a4681f2d142228a9139 Author: Bram Moolenaar <Bram@vim.org> Date: Mon Sep 16 21:58:13 2019 +0200 patch 8.1.2046: SafeState may be triggered at the wrong moment Problem: SafeState may be triggered at the wrong moment. Solution: Move it up higher to after where messages are processed. Add a SafeStateAgain event to tigger there.
author Bram Moolenaar <Bram@vim.org>
date Mon, 16 Sep 2019 22:00:04 +0200
parents a1396a35444c
children b456bba1276a
line wrap: on
line diff
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -933,6 +933,7 @@ ins_typebuf(
     init_typebuf();
     if (++typebuf.tb_change_cnt == 0)
 	typebuf.tb_change_cnt = 1;
+    state_no_longer_safe();
 
     addlen = (int)STRLEN(str);
 
@@ -1779,10 +1780,11 @@ vgetc(void)
      */
     may_garbage_collect = FALSE;
 #endif
+
 #ifdef FEAT_BEVAL_TERM
     if (c != K_MOUSEMOVE && c != K_IGNORE && c != K_CURSORHOLD)
     {
-	/* Don't trigger 'balloonexpr' unless only the mouse was moved. */
+	// Don't trigger 'balloonexpr' unless only the mouse was moved.
 	bevalexpr_due_set = FALSE;
 	ui_remove_balloon();
     }
@@ -1792,6 +1794,11 @@ vgetc(void)
 	c = K_IGNORE;
 #endif
 
+    // Need to process the character before we know it's safe to do something
+    // else.
+    if (c != K_IGNORE)
+	state_no_longer_safe();
+
     return c;
 }
 
@@ -2039,12 +2046,15 @@ parse_queued_messages(void)
     int	    old_curbuf_fnum = curbuf->b_fnum;
     int	    i;
     int	    save_may_garbage_collect = may_garbage_collect;
+    static int entered = 0;
 
     // Do not handle messages while redrawing, because it may cause buffers to
     // change or be wiped while they are being redrawn.
     if (updating_screen)
 	return;
 
+    ++entered;
+
     // may_garbage_collect is set in main_loop() to do garbage collection when
     // blocking to wait on a character.  We don't want that while parsing
     // messages, a callback may invoke vgetc() while lists and dicts are in use
@@ -2090,12 +2100,19 @@ parse_queued_messages(void)
 	break;
     }
 
+    // When not nested we'll go back to waiting for a typed character.  If it
+    // was safe before then this triggers a SafeStateAgain autocommand event.
+    if (entered == 1)
+	leave_unsafe_state();
+
     may_garbage_collect = save_may_garbage_collect;
 
     // If the current window or buffer changed we need to bail out of the
     // waiting loop.  E.g. when a job exit callback closes the terminal window.
     if (curwin->w_id != old_curwin_id || curbuf->b_fnum != old_curbuf_fnum)
 	ins_char_typebuf(K_IGNORE);
+
+    --entered;
 }
 #endif