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.
I can hack it together using WinEnter, VimEnter, and a variable like
w:did_match, but is there a better way?
: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.
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.
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.
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 ///
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.
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.
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.
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
":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.
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.