Oh, what a nasty bug! After having debugged eclim to find out what might trigger this it comes down to be reproducible like this:
1. Start vim: vim -u NONE -N --cmd 'call gettabvar(1, "bar") | au BufEnter * echom "TRIGGERED"' 2. Remove the initial message, e.g. ":<cr>" 3. Open the cmdline-window: q/ The BufEnter autocommand (and likely WinEnter also) gets triggered, if `gettabvar()` has been called with the current tabpagenr(). It does not happen when using "0"or a non-existing tab with gettabvar. The reason for this is that in `switch_win` in `f_gettabvar` will unblock autocommands on failure, although that is what `restore_win` is meant to do. (code reference: https://github.com/vim-jp/vim/blob/master/src/eval.c#L12087-12101) The attached patch fixes this, according to the doc comment from `switch_win`: * restore_win() MUST be called to undo. It adjusts two other places where the code was returning on switch_win-failure only. Please consider adding tests for this. This bug appears to exist since 7.3.963 probably (https://github.com/vim-jp/vim/commit/b4af40af94851dcd1327c7a65c6da8d72937053d). There is also a call to `block_autocmds` in `free_all_mem` without a corresponding call to `unblock_autocmds`, but that might be expected?! I have not checked where this is used. Patch URL: https://github.com/blueyed/vim/compare/fix-switch_win-no-unblock_autocmds.patch Regards, Daniel. Am Samstag, 13. September 2014 19:49:59 UTC+2 schrieb Daniel Hahler: > It appears that &buftype is not correctly set with the BufEnter autocommand > for a cmdline-window. > > I've noticed this with a BufEnter autocommand that checks for &buftype, and > the documentation states that it should be "nofile" for the cmdline-window, > but it's empty. > > Additionally, according to the documentation, BufEnter shouldn't get > triggered at all for a cmdline-window (from cmdline.txt): > > > Two autocommand events are used: |CmdwinEnter| and |CmdwinLeave|. Since > > this > window is of a special type, the WinEnter, WinLeave, BufEnter and BufLeave > events are not triggered. > > > I've seen a similar oddity before, where &buftype appeared to be not current > with a WinEnter autocommand, and in that case it helped to use BufEnter. > > > Regards, > Daniel. -- -- You received this message from the "vim_dev" maillist. Do not top-post! Type your reply below the text you are replying to. For more information, visit http://www.vim.org/maillist.php --- You received this message because you are subscribed to the Google Groups "vim_dev" group. To unsubscribe from this group and stop receiving emails from it, send an email to vim_dev+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.
>From e17f089f2df1d19ec2d932e284c835b2cbc6c35d Mon Sep 17 00:00:00 2001 From: Daniel Hahler <g...@thequod.de> Date: Sat, 13 Sep 2014 21:31:56 +0200 Subject: [PATCH 1/2] Do not call unblock_autocmds on failure in switch_win restore_win is meant to do this! --- src/window.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/window.c b/src/window.c index 5012427..309de67 100644 --- a/src/window.c +++ b/src/window.c @@ -6696,12 +6696,8 @@ switch_win(save_curwin, save_curtab, win, tp, no_display) goto_tabpage_tp(tp, FALSE, FALSE); } if (!win_valid(win)) - { -# ifdef FEAT_AUTOCMD - unblock_autocmds(); -# endif return FAIL; - } + curwin = win; curbuf = curwin->w_buffer; # endif >From f2193a2d88abbad48ed1c43f2a96d512c489bc51 Mon Sep 17 00:00:00 2001 From: Daniel Hahler <g...@thequod.de> Date: Sat, 13 Sep 2014 21:56:37 +0200 Subject: [PATCH 2/2] Call `restore_win` on `switch_win` failure in `setwinvar` and if_py This is required after the fix in e17f089. Also add a question/TODO/note to free_all_mem. --- src/eval.c | 4 +++- src/if_py_both.h | 1 + src/misc2.c | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/eval.c b/src/eval.c index dfcb586..321a22d 100644 --- a/src/eval.c +++ b/src/eval.c @@ -17252,8 +17252,10 @@ setwinvar(argvars, rettv, off) if (win != NULL && varname != NULL && varp != NULL) { #ifdef FEAT_WINDOWS - if (switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == FAIL) + if (switch_win(&save_curwin, &save_curtab, win, tp, TRUE) == FAIL) { + restore_win(save_curwin, save_curtab, TRUE); return; + } #endif if (*varname == '&') diff --git a/src/if_py_both.h b/src/if_py_both.h index 5044afb..45c5158 100644 --- a/src/if_py_both.h +++ b/src/if_py_both.h @@ -3172,6 +3172,7 @@ set_option_value_for( if (switch_win(&save_curwin, &save_curtab, (win_T *)from, win_find_tabpage((win_T *)from), FALSE) == FAIL) { + restore_win(save_curwin, save_curtab, FALSE); if (VimTryEnd()) return -1; PyErr_SET_VIM(N_("problem while switching windows")); diff --git a/src/misc2.c b/src/misc2.c index 1f8878f..09b1b78 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -1040,6 +1040,7 @@ free_all_mem() entered = TRUE; # ifdef FEAT_AUTOCMD + // NOTE: no call to unblock_autocmds?! block_autocmds(); /* don't want to trigger autocommands here */ # endif