10

I just started using buffers in Vim and I couldn't figure out how to list recent closed buffers. Is there a simple way (like :ls) to list those? Are they actually stored by Vim?

Maybe I'm misusing buffers, but what I want to do is to glance at recent closed buffers and then reopen (:e) one of those (of which at that moment I don't remember the (file)name).

I searched windows.txt (from :help buffers) for terms like history, closed buffer, buffer closed, but none of them got me closer to doing what I want.


Edit: I tried :oldfiles (as D. Ben Knoble suggested) but that doesn't seem to work as I'd expect. When I'm viewing one file (buffer) A.file and open another one B.file (using NERDTree) and just after that I close B.file, then :oldfiles doesn't show B.file on the list.

5
  • You could try :oldfiles—depends on what you mean by “closed”
    – D. Ben Knoble
    Dec 5, 2019 at 1:23
  • Read the docs :h :oldfiles...it explains exactly how it works. You can force it to behave a bit closer to expectations by jumping through some hacks...cough...hoops.
    – B Layer
    Dec 5, 2019 at 2:22
  • @BLayer I don't follow. I understood that what :oldfiles does is based on the viminfo file, but I'm not sure how would I accomplish what I asked. Are you suggesting putting each new buffer filename inside viminfo automatically with some script? I guess it's possible to use some hook whenever a new buffer is created, but I have no idea how to do any of that.
    – José
    Dec 5, 2019 at 5:32
  • Yeah, you're pretty much in the ballpark. I wasn't necessarily recommending such a route but figured I'd mention it regardless. I'll be away the rest of (my) evening. If no better solutions are in the offing by tomorrow perhaps I'll dig that hole a little deeper and see what can be found.
    – B Layer
    Dec 5, 2019 at 5:39
  • 1
    Did you try buffers? As you open new files they get added to the bottom of the list (most recent). You can see buffers no longer "visible" aka hidden" :help buffers has a legend. This was the answer for me when I was looking to reopen the last file I had open after I had accidentally opened another file over my active window.
    – Brenden
    Jan 1, 2020 at 21:19

3 Answers 3

5

As of patch 8.1.2225, you can use :ls t to list buffers in order of most recently used.

This includes "closed" buffers where closed means not in any window currently. It does not include buffers from prior closed instances of vim.

1

Use _u to open last buffer,_U to view last buffers.

It can be improved.

let g:lastWindows= []
let g:lastWinName = ""

function! SaveLastWindow()
  if &bt == '' || &bt == 'help' || &ft == 'netranger' "|| &bt == 'nofile'
    let cur= expand( '<afile>' )

    if cur == g:lastWinName || cur ==""
      return
    endif 

    call add(g:lastWindows,cur) 

    let g:lastWinName=cur
  endif
endfunction 

augroup bufclosetrack
  au!
  autocmd BufWinLeave * call SaveLastWindow()
augroup END

function! LastWindow()
  exe "split " . g:lastWinName
endfunction

command -nargs=0 LastWindow call LastWindow()

nmap _u :LastWindow<CR>
nmap _U :call fzf#vim#cust_history(g:lastWindows)<CR>

in autoload/fzf/vim.vim add

function! fzf#vim#cust_history(src,...)
  return s:fzf('history-files', {
  \ 'source':  a:src,
  \ 'options': ['-m', '--header-lines', !empty(expand('%')), '--prompt', 'Hist> ']
  \}, a:000)
endfunction
5
  • My answer is based on vi.stackexchange.com/questions/9081/… @John O'M answer , that is also relevant. The question is a similar question.
    – eyal karni
    Jan 4, 2020 at 15:12
  • 3
    After patch 8.1.2225 this could be simplified using the lastused field of getbufinfo()
    – Mass
    Jan 4, 2020 at 15:24
  • Can you elaborate?
    – eyal karni
    Jan 4, 2020 at 15:27
  • 3
    e.g., getting a list of buffers sorted by recency, getbufinfo()->sort({x,y -> y.lastused - x.lastused})->map({_,x -> x.name})->filter('len(v:val)')
    – Mass
    Jan 4, 2020 at 15:44
  • If a buffer is deleted, it is deleted from the buffer list as well. I agree it doesn't happen often. Also, I am on nvim. no lastused for me.
    – eyal karni
    Jan 4, 2020 at 16:10
0

You can try to improve my naive attempt:

"" if you want real list
" let g:mru_buffers = []
"" or just a string with newlines
let g:mru_buffers = ""
func! RecordMRU(file)
    if a:file != '' " here you can add another check if buffer/file is in mru and either do nothing or move it in the list/string to top
        " call insert(g:mru_buffers, a:file)
        let g:mru_buffers .= a:file . "\n"
    endif
endfunc
augroup mru_list | au!
    au BufDelete * call RecordMRU(expand('<afile>'))
augroup end

Having this you can list recently closed buffers with echo g:mru_buffers, or make a command :command MRU :echo g:mru_buffers.

It doesn't have persistence but one can easily add it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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