changeset 25501:a1ed55c02e80 v8.2.3287

patch 8.2.3287: channel events not handled in BufEnter autocommand Commit: https://github.com/vim/vim/commit/57942237c1d54d8a236b43c56dc2b002339eb394 Author: Bram Moolenaar <Bram@vim.org> Date: Wed Aug 4 20:54:55 2021 +0200 patch 8.2.3287: channel events not handled in BufEnter autocommand Problem: Channel events not handled in BufEnter autocommand. Solution: Decrement dont_parse_messages earlier. (Tim Pope, closes https://github.com/vim/vim/issues/8697)
author Bram Moolenaar <Bram@vim.org>
date Wed, 04 Aug 2021 21:00:05 +0200
parents 4b868f9f92e6
children 4c2191b35282
files src/testdir/test_channel.vim src/version.c src/window.c
diffstat 3 files changed, 65 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/src/testdir/test_channel.vim
+++ b/src/testdir/test_channel.vim
@@ -2330,4 +2330,33 @@ func Test_cb_with_input()
   unlet g:wait_exit_cb
 endfunc
 
+function s:HandleBufEnter() abort
+  let queue = []
+  let job = job_start(['date'], {'callback': { j, d -> add(queue, d) }})
+  while empty(queue)
+    sleep! 10m
+  endwhile
+endfunction
+
+func Test_parse_messages_in_autocmd()
+  CheckUnix
+
+  " Check that in the BufEnter autocommand events are being handled
+  augroup bufenterjob
+    autocmd!
+    autocmd BufEnter Xbufenterjob call s:HandleBufEnter()
+  augroup END
+
+  only
+  split Xbufenterjob
+  wincmd p
+  redraw
+
+  close
+  augroup bufenterjob
+    autocmd!
+  augroup END
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
--- a/src/version.c
+++ b/src/version.c
@@ -756,6 +756,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    3287,
+/**/
     3286,
 /**/
     3285,
--- a/src/window.c
+++ b/src/window.c
@@ -40,7 +40,7 @@ static void enter_tabpage(tabpage_T *tp,
 static void frame_fix_height(win_T *wp);
 static int frame_minheight(frame_T *topfrp, win_T *next_curwin);
 static int may_open_tabpage(void);
-static void win_enter_ext(win_T *wp, int flags);
+static int win_enter_ext(win_T *wp, int flags);
 static void win_free(win_T *wp, tabpage_T *tp);
 static int win_unlisted(win_T *wp);
 static void win_append(win_T *after, win_T *wp);
@@ -73,6 +73,7 @@ static win_T *win_alloc(win_T *after, in
 #define WEE_TRIGGER_NEW_AUTOCMDS	0x04
 #define WEE_TRIGGER_ENTER_AUTOCMDS	0x08
 #define WEE_TRIGGER_LEAVE_AUTOCMDS	0x10
+#define WEE_ALLOW_PARSE_MESSAGES	0x20
 
 static char *m_onlyone = N_("Already only one window");
 
@@ -1338,8 +1339,8 @@ win_split_ins(
     /*
      * make the new window the current window
      */
-    win_enter_ext(wp, WEE_TRIGGER_NEW_AUTOCMDS | WEE_TRIGGER_ENTER_AUTOCMDS
-						 | WEE_TRIGGER_LEAVE_AUTOCMDS);
+    (void)win_enter_ext(wp, WEE_TRIGGER_NEW_AUTOCMDS
+		    | WEE_TRIGGER_ENTER_AUTOCMDS | WEE_TRIGGER_LEAVE_AUTOCMDS);
     if (flags & WSP_VERT)
 	p_wiw = i;
     else
@@ -2483,6 +2484,7 @@ win_close(win_T *win, int free_buf)
 #ifdef FEAT_DIFF
     int		had_diffmode = win->w_p_diff;
 #endif
+    int		did_decrement = FALSE;
 
 #if defined(FEAT_TERMINAL) && defined(FEAT_PROP_POPUP)
     // Can close a popup window with a terminal if the job has finished.
@@ -2661,8 +2663,11 @@ win_close(win_T *win, int free_buf)
 	win_comp_pos();
     if (close_curwin)
     {
-	win_enter_ext(wp, WEE_CURWIN_INVALID | WEE_TRIGGER_ENTER_AUTOCMDS
-						 | WEE_TRIGGER_LEAVE_AUTOCMDS);
+	// Pass WEE_ALLOW_PARSE_MESSAGES to decrement dont_parse_messages
+	// before autocommands.
+	did_decrement = win_enter_ext(wp,
+		WEE_CURWIN_INVALID | WEE_TRIGGER_ENTER_AUTOCMDS
+		      | WEE_TRIGGER_LEAVE_AUTOCMDS | WEE_ALLOW_PARSE_MESSAGES);
 	if (other_buffer)
 	    // careful: after this wp and win may be invalid!
 	    apply_autocmds(EVENT_BUFENTER, NULL, NULL, FALSE, curbuf);
@@ -2670,7 +2675,8 @@ win_close(win_T *win, int free_buf)
 
     --split_disallowed;
 #ifdef MESSAGE_QUEUE
-    --dont_parse_messages;
+    if (!did_decrement)
+	--dont_parse_messages;
 #endif
 
     /*
@@ -4188,7 +4194,7 @@ enter_tabpage(
     // We would like doing the TabEnter event first, but we don't have a
     // valid current window yet, which may break some commands.
     // This triggers autocommands, thus may make "tp" invalid.
-    win_enter_ext(tp->tp_curwin, WEE_CURWIN_INVALID
+    (void)win_enter_ext(tp->tp_curwin, WEE_CURWIN_INVALID
 		  | (trigger_enter_autocmds ? WEE_TRIGGER_ENTER_AUTOCMDS : 0)
 		  | (trigger_leave_autocmds ? WEE_TRIGGER_LEAVE_AUTOCMDS : 0));
     prevwin = next_prevwin;
@@ -4476,7 +4482,7 @@ win_goto(win_T *wp)
 #endif
 }
 
-#if defined(FEAT_PERL) || defined(PROTO)
+#if defined(FEAT_PERL) || defined(FEAT_LUA) || defined(PROTO)
 /*
  * Find window number "winnr" (counting top to bottom).
  */
@@ -4689,7 +4695,7 @@ win_goto_hor(
     void
 win_enter(win_T *wp, int undo_sync)
 {
-    win_enter_ext(wp, (undo_sync ? WEE_UNDO_SYNC : 0)
+    (void)win_enter_ext(wp, (undo_sync ? WEE_UNDO_SYNC : 0)
 		    | WEE_TRIGGER_ENTER_AUTOCMDS | WEE_TRIGGER_LEAVE_AUTOCMDS);
 }
 
@@ -4697,15 +4703,17 @@ win_enter(win_T *wp, int undo_sync)
  * Make window "wp" the current window.
  * Can be called with "flags" containing WEE_CURWIN_INVALID, which means that
  * curwin has just been closed and isn't valid.
+ * Returns TRUE when dont_parse_messages was decremented.
  */
-    static void
+    static int
 win_enter_ext(win_T *wp, int flags)
 {
     int		other_buffer = FALSE;
     int		curwin_invalid = (flags & WEE_CURWIN_INVALID);
+    int		did_decrement = FALSE;
 
     if (wp == curwin && !curwin_invalid)	// nothing to do
-	return;
+	return FALSE;
 
 #ifdef FEAT_JOB_CHANNEL
     if (!curwin_invalid)
@@ -4722,15 +4730,15 @@ win_enter_ext(win_T *wp, int flags)
 	    apply_autocmds(EVENT_BUFLEAVE, NULL, NULL, FALSE, curbuf);
 	    other_buffer = TRUE;
 	    if (!win_valid(wp))
-		return;
+		return FALSE;
 	}
 	apply_autocmds(EVENT_WINLEAVE, NULL, NULL, FALSE, curbuf);
 	if (!win_valid(wp))
-	    return;
+	    return FALSE;
 #ifdef FEAT_EVAL
 	// autocmds may abort script processing
 	if (aborting())
-	    return;
+	    return FALSE;
 #endif
     }
 
@@ -4757,6 +4765,16 @@ win_enter_ext(win_T *wp, int flags)
 	curwin->w_cursor.coladd = 0;
     changed_line_abv_curs();	// assume cursor position needs updating
 
+    // Now it is OK to parse messages again, which may be needed in
+    // autocommands.
+#ifdef MESSAGE_QUEUE
+    if (flags & WEE_ALLOW_PARSE_MESSAGES)
+    {
+	--dont_parse_messages;
+	did_decrement = TRUE;
+    }
+#endif
+
     if (curwin->w_localdir != NULL || curtab->tp_localdir != NULL)
     {
 	char_u	*dirname;
@@ -4832,6 +4850,8 @@ win_enter_ext(win_T *wp, int flags)
 
     // Change directories when the 'acd' option is set.
     DO_AUTOCHDIR;
+
+    return did_decrement;
 }