tags:

views:

125

answers:

3

Is there something like a close-window-hook in vim/vimscript, so that I can call a function every time a window is closed?

I want to use it for the following scenario: I use an extra scratch window to display information about the file, and when I close the file I want the scratch window to be closed automatically so that vim exits.

If you have any ideas how to achieve that without a hook that will be just as fine.

edit: I know about :qa[ll], but I am lazy and only want to type :q or ZZ.

edit2.71828183: I accepted the autocommand answer as it was closest to the original question, but found another solution in using a preview window instead of a split window. A preview window is automatically closed when the last "normal" window is closed..

A: 

You can use

:quitall

or

:qall

to close all windows at once.

add a ! if you want to ignore unsaved changes.

:qall!
Peter
Sorry, that is not what I want. I want the second window to automatically close, no matter how the first window is closed. That includes ZZ, :q, whatever. Especially I don't want to type :qa all the time, :q is hard-wired into my fingers..
0x89
A: 

Add a mapping.

:nnoremap :q :qa

then, if you only want to use :q one day, you can just

:qa<backspace>

and normally, you can just

:q<enter>

and get

:qa<enter>

for free.

Peter
+1  A: 

autocommands are amazing! I'm pretty sure that in this case, BufLeave will do the job, but you might want BufWinLeave? Have a look at :help autocmd-events for a full list of events.

The other bit you'll care about is: you can have buffer-local autocommands! (:help autocmd-buflocal)

You can define one for the current buffer using au BufLeave <buffer> .... My best guess is that you could run this in whatever command creates the scratch window. You should be able to cache the scratch window's buffer number in a global variable when you open the scratch window, then your autocommand could just delete that buffer (:help :bdelete).

au BufLeave <buffer> bdelete g:scratch_buffer
call CreateScratchWindow()

function CreateScratchWindow() {
    ...
    let g:scratch_buffer = bufnr("")
}

There's also a function winbufnr, for getting buffer numbers by window. You can use either one - just make sure that the scratch window/buffer is current when you use it! (The "" means current window/buffer).

Jefromi
Autocommands are what I was looking for when asking for a hook, thanks for the tip.But I can't make this autocommand work to solve my original problem. It closes the scratch buffer, but then the original file does not close!
0x89
I think you want `BufUnload` instead.
rampion
@rampion: I believe that when a window is closed, the buffer it contained becomes hidden, which should not trigger `BufUnload`. Have you actually tried it?@0x89: That's very strange. The autocommand shouldn't be able to affect execution outside of itself. A kludge to get it to work might be to have the autocommand close the original file too. (use | to concatenate commands, or write a function for the autocommand to call)
Jefromi
If the buffer is hidden or unloaded depends on the `hidden` setting, as well as on the `bufhidden` option. Maybe that is the solution: I have "set hidden" in my `.vimrc`, so when I close the first buffer, it becomes _hidden_, then the autocommand closes the other one, which makes the first window visible again - tricky! So I could close the window in the au. But I found another solution: I use a preview window instead of a split window (see :help preview). That is automatically closed when there are no other windows left..
0x89
Oh! I'm sorry, I meant to suggest that in the first place, but got totally distracted by buffer-local autocommands.
Jefromi