I played around with this a bit and the following seems to work for the cases I tested, including closing a window split and a tab with one window using :q
.
augroup bufclosetrack
au!
autocmd WinLeave * let g:lastWinName = @%
augroup END
function! LastWindow()
exe "split " . g:lastWinName
endfunction
command -nargs=0 LastWindow call LastWindow()
This creates an autocommand in a new augroup (only need to put it in a group if you risk loading the script file multiple times) to run just before the cursor leaves a window (see :help WinLeave
), which includes closing a window, be it just a split or the last window in a tab, closing the tab. We set this to occur on any buffer name by using th *
. Then we set the action save the file name of that window into a global variable, we'll call g:lastWinName
, but you could use any variable name you want.
Then we create a function that will split the current window, giving the split command the value of the variable we saved to. This is done by concatenating the string "split "
with the variable g:lastWinName
using the .
operator. The exe
command executes the resulting string.
When you accidentally close a window or tab, then, you can call the LastWindow command as :LastWindow
, which calls a function which will open a new split on that last file name.
Caveats:
- if you accidentally change window (just moving cursor to another window for example) after you close a window, this won't recover the closed window
- If you have vim change its working directory based on the path of the file for the active buffer, this will probably fail (likewise if you change directory manually after the window is closed)
- Using this after closing a tabfull of windows (e.g. using
:tabc
) results in the save called multiple times. Running LastWindow only restores one of them (whichever Vim actually closed last)
- This only restores the buffer by name; none of the other window information is restored (e.g. window size, position in buffer, window local settings, etc)
Possible future improvements:
- It might be possible to track the buffer number of the window before it closes and track that; that should solve the problem with changing directory
- Some window settings could be copied to other variables and restored on function call
- Other commands/functions in a similar vein could allow other methods of restoration, e.g. to open in a new tab instead of a new split
:e #
? See:h cmdline-special
for details.#
, this is a neat suggestion. But unfortunately it looks like that register is per-window (stackoverflow.com/a/5182973/3235236), so this won't work if:wq
also closes the corresponding window. The documentation foralternate-file
is a little bit hazy so I could be missing something.vim -p file1 file2
, then run:wq
, and then:tabnew #
. That said, yes,#
does get lost pretty soon, if you don't re-open the file immediately.:e #
will work some of the time, and it's what I do, but it isn't reliable. When that doesn't work I do:b part-of-filename<tab>
.