On 2022-12-14, Bram Moolenaar wrote:
> Gary Johnson wrote:
> 
> > > > I've had an autocommand in my vimrc for quite some time that
> > > > I noticed recently was causing the following error message when
> > > > activated:
> > > > 
> > > >     Error detected while processing BufEnter Autocommands for 
> > > > "<buffer=3>":
> > > >     E1312: Not allowed to change the window layout in this autocmd
> > > > 
> > > > I performed a git bisect on the Vim source and found that the bug
> > > > was introduced here:
> > > > 
> > > >     d63a85592cef0ee4f0fec5efe2f8d66b31f01f05 is the first bad commit
> > > >     commit d63a85592cef0ee4f0fec5efe2f8d66b31f01f05
> > > >     Author: Bram Moolenaar <b...@vim.org>
> > > >     Date:   Sat Nov 19 11:41:30 2022 +0000
> > > > 
> > > >         patch 9.0.0907: restoring window after WinScrolled may fail
> > > > 
> > > >         Problem:    Restoring window after WinScrolled may fail.
> > > >         Solution:   Lock the window layout when triggering WinScrolled.
> > > > 
> > > >      src/errors.h         |  2 ++
> > > >      src/ex_docmd.c       | 18 ++++++++++++-----
> > > >      src/proto/window.pro |  1 +
> > > >      src/version.c        |  2 ++
> > > >      src/window.c         | 56 
> > > > +++++++++++++++++++++++++++++++++++++++++++++++++---
> > > >      5 files changed, 71 insertions(+), 8 deletions(-)
> > > > 
> > > > This is the autocommand in my vimrc and the reason for it being
> > > > there:
> > > > 
> > > >     " If the Calendar window is open when the last non-Calendar
> > > >     " window is closed, Vim continues to run with the Calendar
> > > >     " window occupying the full Vim window.  Fix this,
> > > >     " automatically close the Calendar window if it is the only
> > > >     " window.
> > > >     "
> > > >     autocmd BufWinEnter __Calendar
> > > >         \ autocmd BufEnter <buffer> if winnr("$")==1 | quit | endif
> > > 
> > > So you have a BufEnter autocommand that closes the buffer (with some
> > > condition).  The BufEnter event can be triggered in various places, and
> > > they are most likely not prepared for the buffer disappearing.
> > 
> > The autocommand is defined only when the buffer name is "__Calendar"
> > and the "<buffer>" pattern is used so that that is the only buffer
> > in which the command is triggered.  The event can be triggered in
> > only one place and that place is prepared for it.
> 
> That is your specific situation.  Other users may have very different
> situations.  And we need to deal with all of them...
> 
> > > There already is quite a lot of code to handle side effects of what an
> > > autocmd may do, but it's getting very complicated.  In some cases it's
> > > better to just not allow certain actions.  For a BufEnter event it seems
> > > quite natural to disallow deleting that buffer.  Why would you delete a
> > > buffer you just entered?
> > 
> > In this case, I want to delete a buffer if it is the only buffer
> > displayed in the tab.  I never use that buffer alone, only alongside
> > another buffer.  When I close that other buffer, I want the
> > __Calendar buffer to be deleted, too, because I'm done with it.
> > I got tired of typing ":q<Enter>" twice, so I created the
> > autocommand to save some typing and time, i.e., to make the scenario
> > "just work" as Vim usually gives me the tools to do.
> > 
> > The BufEnter event is used because that's what happens when a window
> > is closed:  some other window is entered.  And with the test for
> > 'winnr("$")==1', it isn't closed every time it is entered, but only
> > when it is the last open window in the tab.
> 
> The idea of BufEnter is that you can set some options specifically for a
> buffer, setup mappings or insert some template text.  Deleting the
> buffer isn't really anticipated.
> 
> > > Since this stuff is so complicated we keep finding new problems.  So
> > > once in a while something that was allowed before is no longer allowed,
> > > because there are situations where it causes a crash.
> > > 
> > > The situation you describe seems quite rare, thus I think we just have
> > > to accept this no longer works.  You can probably find another way.
> > 
> > I'll buy that the code is getting very complicated and that some use
> > cases aren't worth supporting.  It's just a shame when useful tools
> > are prevented from working because they don't work in every case,
> > and frustrating when things that used to work stop working.
> 
> At some point I thought I should drop auto commands completely, because
> it's just getting too complicated and too many crashes have had to be
> fixed.  And there are probably a few more that we haven't found yet.
> 
> But users, and especialy plugin writers, depend on auto commands, and
> there is no good replacement, thus they are still here.  But let it be
> clear that supporting auto commands is almost infeasible, thus you can
> expect some limitations.  I currently tend to prevent things from going
> bad rather than deal with the problems caused by them.  E.g. disallow
> closing and splitting windows rather than dealing with a window
> disappearing "under our fingers".  Sometimes it's not at all clear what
> to do then.

Yes, autocommands are wonderful!  There are so many situations where
when "this" happens you want "that" to happen, too.  Autocommands
are pretty much the only hooks we have.  They do so much to make Vim
work just the way I want it.  And I do appreciate that they also
allow users to shoot themselves (ourselves) in the foot.  I'm sorry
they're a PITA for you.  Thanks for maintaining them.

> > I don't know what other event is triggered when a window/buffer
> > becomes the last one open in a tab.  I suppose I could try having
> > a BufDelete or WinClosed event check whether the buffer/window being
> > closed is the next-to-last one in a tab, and if the other buffer is
> > __Calendar, then also close that window somehow.  (I know my use of
> > "window" and "buffer" above is a little loose.)  I just hope those
> > commands haven't required the same protections as BufEnter.
> 
> Whatever auto command event you use, deleting the buffer will always be
> problematic.  Maybe you find one where it works now, but after some
> crashing bug it may stop working.
> 
> There is one exception: the SafeState event.  It was specifically added
> for when Vim isn't doing anythng, thus deleting the buffer then is
> probably OK.  Give it a try.

Thanks for the tip.  I made a note of that near the current code and
I'll try that if what I'm doing now has problems.

I found another solution using feedkeys(), which allows the :quit
command to be executed outside of an autocommand environment.

Regards,
Gary

-- 
-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221214215414.GB6446%40phoenix.

Raspunde prin e-mail lui