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 <[email protected]>
> >     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.

> 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.

> 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.

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.

Thanks for taking the time to explain the situation.

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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20221214174231.GA6446%40phoenix.

Raspunde prin e-mail lui