# HG changeset patch # User Bram Moolenaar # Date 1628103605 -7200 # Node ID a1ed55c02e8029495fe394e869749a11843aa6be # Parent 4b868f9f92e61b0f6dc10635896559a26e2d7806 patch 8.2.3287: channel events not handled in BufEnter autocommand Commit: https://github.com/vim/vim/commit/57942237c1d54d8a236b43c56dc2b002339eb394 Author: Bram Moolenaar 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) diff --git a/src/testdir/test_channel.vim b/src/testdir/test_channel.vim --- 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 diff --git a/src/version.c b/src/version.c --- 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, diff --git a/src/window.c b/src/window.c --- 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; }