Autocmd for creating a new window?

40 views
Skip to first unread message

Benjamin Fritz

unread,
Jun 23, 2008, 3:32:23 PM6/23/08
to vim_use
Is there an autocmd event that will fire when creating a new window?

I currently have a BufWinEnter event setting some window-local options
and calling matchadd(), but I discovered today that BufWinEnter
doesn't fire at all when the window is created using :split without an
argument. Also, BufWinEnter fires whenever a new buffer is loaded in
an existing window, but the window-specific options and the matchlist
are not reset, so my matchadd() call ends up adding the same (or
similar) match over and over.

Benjamin Fritz

unread,
Jun 23, 2008, 4:03:07 PM6/23/08
to vim_use

I can hack it together using WinEnter, VimEnter, and a variable like
w:did_match, but is there a better way?

Ben Schmidt

unread,
Jun 23, 2008, 4:26:39 PM6/23/08
to vim...@googlegroups.com
Benjamin Fritz wrote:
> On 6/23/08, Benjamin Fritz <fritzo...@gmail.com> wrote:
>> Is there an autocmd event that will fire when creating a new window?

:help BufNew

is likely what you want.

Ben.

Benjamin Fritz

unread,
Jun 23, 2008, 5:03:12 PM6/23/08
to vim...@googlegroups.com

No, sadly it isn't.

What I am trying to do is set up some additional error matching using
matchadd(). One of the matches I add needs to be added to every
window. Using BufNew means that it won't be added when, for example, I
display an already-loaded buffer in a new window. I was using
BufWinEnter, which states that it will fire whenever a buffer is
displayed in a window. It is supposed to also fire when a buffer
already visible in a window is displayed in another window, but this
does not happen with :split with no arguments. This might be a bug.
Regardless, I can get around this one using WinEnter and a
window-local variable, so it isn't too big of a deal.

The other match I add needs to be added to every window containing a
buffer of a given file type. A FileType autocmd by itself won't do it,
because if the buffer is already loaded, FileType never gets called.
BufWinEnter would be perfect for this as well; I can just check the
&ft variable in the mapping. But...the same limitation applies.
Unfortunately, WinEnter fires _before_ FileType is applied, so my
dirty little hack fails for this application.

Anyone else have an idea?

Is the behavior of BufWinEnter with :split a bug?

BufWinEnter _does_ fire when you give :split an argument.

Ben Schmidt

unread,
Jun 24, 2008, 12:28:44 AM6/24/08
to vim...@googlegroups.com
Benjamin Fritz wrote:
> On 6/23/08, Ben Schmidt <mail_ben...@yahoo.com.au> wrote:
>> Benjamin Fritz wrote:
>> > On 6/23/08, Benjamin Fritz <fritzo...@gmail.com> wrote:
>> >> Is there an autocmd event that will fire when creating a new window?
>>
>>
>> :help BufNew
>>
>> is likely what you want.
>>
>> Ben.
>>
>
> No, sadly it isn't.
>
> What I am trying to do is set up some additional error matching using
> matchadd(). One of the matches I add needs to be added to every
> window. Using BufNew means that it won't be added when, for example, I
> display an already-loaded buffer in a new window. I was using
> BufWinEnter, which states that it will fire whenever a buffer is
> displayed in a window. It is supposed to also fire when a buffer
> already visible in a window is displayed in another window, but this
> does not happen with :split with no arguments. This might be a bug.

Well, it's definitely a bug, as the documented and implemented
behaviours differ. But whether it's an implementation or a documentation
bug, I'm not sure.

BufWinEnter and BufWinLeave don't seem to be 'symmetrical' at all:
According to the docs, BufWinLeave only fires if a buffer *isn't*
visible elsewhere, but BufWinEnter fires in all cases. Except using
:split, it seems.

It's all a bit strange. What do others think? Bram? Documentation or
implementation bug?

> Regardless, I can get around this one using WinEnter and a
> window-local variable, so it isn't too big of a deal.
>
> The other match I add needs to be added to every window containing a
> buffer of a given file type. A FileType autocmd by itself won't do it,
> because if the buffer is already loaded, FileType never gets called.
> BufWinEnter would be perfect for this as well; I can just check the
> &ft variable in the mapping. But...the same limitation applies.
> Unfortunately, WinEnter fires _before_ FileType is applied, so my
> dirty little hack fails for this application.

I think you could get around this, though it's not ideal, by using
WinEnter and FileType. Get them to do exactly the same thing, including
setting a window-local variable when a filetype actually is detected and
acted upon (avoid setting it if you just check and find no filetype).

Ben.


Bram Moolenaar

unread,
Jun 24, 2008, 4:45:26 AM6/24/08
to Ben Schmidt, vim...@googlegroups.com

Ben Schmidt wrote:

Documentation. If you do ":split" you keep editing the same buffer,
nothing is loaded.

> > Regardless, I can get around this one using WinEnter and a
> > window-local variable, so it isn't too big of a deal.
> >
> > The other match I add needs to be added to every window containing a
> > buffer of a given file type. A FileType autocmd by itself won't do it,
> > because if the buffer is already loaded, FileType never gets called.
> > BufWinEnter would be perfect for this as well; I can just check the
> > &ft variable in the mapping. But...the same limitation applies.
> > Unfortunately, WinEnter fires _before_ FileType is applied, so my
> > dirty little hack fails for this application.
>
> I think you could get around this, though it's not ideal, by using
> WinEnter and FileType. Get them to do exactly the same thing, including
> setting a window-local variable when a filetype actually is detected and
> acted upon (avoid setting it if you just check and find no filetype).
>
> Ben.

--
hundred-and-one symptoms of being an internet addict:
89. In addition to your e-mail address being on your business
cards you even have your own domain.

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ download, build and distribute -- http://www.A-A-P.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Ben Schmidt

unread,
Jun 24, 2008, 5:19:22 AM6/24/08
to Bram Moolenaar, vim...@googlegroups.com

There we go! Sorted out. It seems the last part of the documentation
should be omitted.

--- /Applications/MacVim.app/Contents/Resources/vim/runtime/doc/autocmd.txt
2008-06-22 21:12:56.000000000 +1000
+++ - 2008-06-24 19:18:12.000000000 +1000
@@ -400,10 +400,9 @@
*BufWinEnter*
BufWinEnter After a buffer is displayed in a window. This
can be when the buffer is loaded (after
- processing the modelines), when a hidden
+ processing the modelines) or when a hidden
buffer is displayed in a window (and is no
- longer hidden) or a buffer already visible in
- a window is also displayed in another window.
+ longer hidden).
*BufWinLeave*
BufWinLeave Before a buffer is removed from a window.
Not when it's still visible in another window.

This makes sense. BufWinEnter and BufWinLeave are then 'symmetrical' as
you would expect.

A little testing shows Vim does behave like this.

Ben.


Benjamin Fritz

unread,
Jun 24, 2008, 8:54:18 AM6/24/08
to vim...@googlegroups.com


I can accept that, but to play devil's advocate...

Assume you have two buffers loaded in split windows, file.a and file.b.

Go to the window for file.a and do :split file.b

This will trigger a BufWinEnter event (I've verified this, and relied
on it in the past).

Arguably, since the buffer already exists, you have loaded nothing.
Hence, the help text for BufWinEnter "...or a buffer already visible
in a window is also displayed in another window."

If instead of file.b you do :split file.a or even :split %, an event
is also triggered in the same way, much as one would expect given the
known behavior.

But, if you give :split no arguments, which intuitively should do the
same thing as :split %, no event is triggered.

Again, if this behavior is "correct" I can accept and work around that.

But it sure seems inconsistent and confusing to me, and the help
documents should clarify what is going on.

Ben Schmidt

unread,
Jun 24, 2008, 9:16:42 AM6/24/08
to vim...@googlegroups.com
> I can accept that, but to play devil's advocate...
>
> Assume you have two buffers loaded in split windows, file.a and file.b.
>
> Go to the window for file.a and do :split file.b
>
> This will trigger a BufWinEnter event (I've verified this, and relied
> on it in the past).

It doesn't for me. I tested it just prior to my last post. And I just
tested it again now. Can you describe a foolproof set of steps that can
reproduce this? I did

:let g:a=1
:au BufWinEnter * let g:a += 1 | echo "LOADED " g:a
:e ~/c.vim
:split ~/cc.c
:split ~/c.vim

I saw LOADED 2 for the first :e, LOADED 3 for the first :split, and
nothing for the second :split.

> If instead of file.b you do :split file.a or even :split %, an event
> is also triggered in the same way, much as one would expect given the
> known behavior.

Ah! Now *this* happens for me. It is quite strange. If I have the same
autocommand as before and do

:e ~/c.vim
:split ~/c.vim

or

:e ~/c.vim
:split %

I see a LOADED message for both. If I do

:e ~/c.vim
:split

Then I only see a LOADED message for the :e, and not the :split.

> But, if you give :split no arguments, which intuitively should do the
> same thing as :split %, no event is triggered.
>
> Again, if this behavior is "correct" I can accept and work around that.
>
> But it sure seems inconsistent and confusing to me, and the help
> documents should clarify what is going on.

Yeah, I think something strange is going on here... Surely there
shouldn't be a distinction between splitting with a different file and
splitting with the same file, except possibly no arguments vs. giving an
argument. But that doesn't appear to actually be the distinction here.
Weird.

Ben.


John Beckett

unread,
Jun 24, 2008, 10:31:45 PM6/24/08
to vim...@googlegroups.com
Ben Schmidt wrote:
> It doesn't for me. I tested it just prior to my last post. And
> I just tested it again now. Can you describe a foolproof set
> of steps that can reproduce this? I did
>
> :let g:a=1
> :au BufWinEnter * let g:a += 1 | echo "LOADED " g:a
> :e ~/c.vim
> :split ~/cc.c
> :split ~/c.vim
>
> I saw LOADED 2 for the first :e, LOADED 3 for the first
> :split, and nothing for the second :split.

I also *see* nothing, but in fact g:a was incremented, so the event was called. I
confirmed that by modifying your BufWinEnter to append g:a to the buffer (LOADED 4
does occur).

While mucking around I notice another discrepancy that is probably related:

vim -N -u NONE -U NONE -i NONE
:e filea " an existing file
x " make any change to the buffer
:split % " error E37 'no write since last change'
:split filea " same error
:split " works

So :split with no arguments does not invoke events, which is somewhat
understandable.

John

Tony Mechelynck

unread,
Jun 24, 2008, 11:08:34 PM6/24/08
to vim...@googlegroups.com

":split fileb" also gives no error. The error (IIUC) comes from trying
to read a file which exists 'modified' in another buffer. ":split" with
no arguments does not create a new buffer, which I think is the
criterion used.


Best regards,
Tony.
--
Do not believe in miracles -- rely on them.

Benjamin Fritz

unread,
Jun 25, 2008, 8:44:55 AM6/25/08
to vim...@googlegroups.com

Yet, try this:

vim -N -u NONE -U NONE -i NONE
:e filea " an existing file
x " make any change to the buffer

:split fileb " no error
:split filea " no error, and correctly loads existing (modified) buffer

IMO, very inconsistent and should probably be fixed. It is obviously
possible to split a window to load a modified buffer. Splitting a
window does not cause any changes to a file, this should be a totally
safe operation.

My guess (without looking at the code) is that :split with arguments
is implemented by calling the same code as :split without an arugment,
and then calling the code for :edit. This would explain the lack of a
BufWinEnter event for :split as well as the error for :split % when
the current buffer is modified. I'm not sure what would be required to
make it work consistently with and without argument; if it is too
complex it can probably wait a while, but I do think it should be
done.

Reply all
Reply to author
Forward
0 new messages