4

When writing to a file, I often accidentally type :wq instead of :w since the two keys are right next to each other. But since I almost always have more than one buffer open, Vim stays up and whatever file I just closed stays in the list of buffers (:ls).

It is sometimes a lot of work to reopen the file manually. And worse, sometimes I don't even remember the file name of what I just edited! So I have to pore over :ls and try to remember.

Is there a way to "reopen" the most recently closed window?

  • 2
    Did you try :e #? See :h cmdline-special for details. – Sato Katsura Aug 5 '16 at 4:06
  • I never knew about #, 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 for alternate-file is a little bit hazy so I could be missing something. – Lombard Aug 5 '16 at 11:38
  • You shouldn't believe everything you read on the internet. Try this: 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. – Sato Katsura Aug 5 '16 at 12:58
  • The alternate file is remembered for each window. :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>. – Antony Aug 5 '16 at 13:50
4

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
  • It is sad that out of 3 solutions which were plugins that I have checked (bufexplorer,mru,undoquit) only yours worked for closing a help file. – eyal karni Nov 15 at 15:13
2

You can try CTRL-O, this will go to last cursor posision in jump list, even for closed buffers. This will even work from fresh vim instance, so you can open last file with that.

  • This isn't working for me... :h jumplist states that "there is a separate jump list for each window". So unless the window is still open and displaying another buffer, this doesn't do what I need it to do. In my typical workflow, I have one thing to edit per window i.e. no hidden buffers. – Lombard Aug 5 '16 at 9:17
  • Ah... wrongly read about restoring a window, sorry. So I don't about restoring a window, but this will create a window: nmap <Leader>restore :new<CR><C-O><C-O>. This creates new window and goes back to last file using jumplist. Note that this should be done just after :wq. New window may be not in the same position as closed one, though. <Leader>restore may be any mapping that will suite your needs. And <Leader> is by default assigned to ``. Hope whis will work better for you. – grodzik Aug 5 '16 at 9:39
  • It seems that traversing the jumplist does not take me to the closed buffer if :wq also closed the corresponding window, which is usually the case for me. – Lombard Aug 5 '16 at 11:32
0

Not the exact solution but a rather popular one is the MRU plugin by yegappan. It provides you with a temporary window (just like a quickfix window) that contains the name and path of the current files and recently closed files.

After you close the a file with :wq and swear that you should not have done it, you can do :MRC and a temporary window opens. It allows for opening/reopening the files present in this temporary window in different ways:

  • <CR> opens the file in the current window (or different window if there are non-written changes in the current window).
  • o opens the file in a new window always
  • t opens the file in a new tab
  • no :MRC command! – eyal karni Nov 15 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.