22

I would like to go to the file I just edited last and next kind of like MRU plugins do.

:bnext and :bprev works sometimes, but more often than not I just end up in some obscure file I don't remember editing and forced to fall back to MRU plugin.

Is there a way to fix it?

Ctrl-^ swaps between two last files. What is the best way to navigate between more?

I understand it might be tricky but I would agree to anything that can improve current :bn :bp behavior. The buffers I often see are totally out of place. Maybe there is a plugin that can keep track of the recent files and provide hooks so I can create mappings?

Replying to comments cleared up my thoughts a bit. I believe what I want is to be able to move through files in order of latest saves. That way if I go back in history the order won't change until I save the file which then becomes last and make one step "back" to the file saved right before that, i.e. the one I've started from.

Something like Ctrl-O Ctrl-I pair that switches files immediately without jumping around the current buffer. Sort of like u and U in netrw:

u   Change to recently-visited directory                 |netrw-u|
U   Change to subsequently-visited directory             |netrw-U|
8
  • By "the file I just edited last" do you literally mean "the file I most recently made edits to"? Or do you just mean the last one that you had visible in Vim?
    – Rich
    Jun 25, 2015 at 13:14
  • 2
    If the latter, I personally just mash Ctrl-O (or sometimes Ctrl-T) till I get there.
    – Rich
    Jun 25, 2015 at 13:16
  • Yes that's what I do too Ctrl-O and Ctrl-I. But it jumps between edit points and that breaks the flow. All I want to go back and forth between buffers in order of access. How plugins display a list of most recent files? Do they keep track of them internally?
    – firedev
    Jun 25, 2015 at 13:57
  • Ctrl-^ swaps between two last files. But what is the best way to navigate between more?
    – firedev
    Jun 25, 2015 at 14:00
  • By access, it's still not clear if you mean the order they were opened, written to, in a focused window, or changed. Ctrl-O/I are window-specific fwiw, while MRU is usually global. If you do want order by most recently accessed, as soon as you jump back once, the order of the list changes, further complicating things.
    – Matt Boehm
    Jun 25, 2015 at 17:17

4 Answers 4

9

I wrote a little function to repeatedly hit CTRL-O for me, until the buffer changes.

You can find it here. I mapped it to CTRL-U but you could override CTRL-O if you wanted to.

function! GoBackToRecentBuffer()
  let startName = bufname('%')
  while 1
    exe "normal! \<c-o>"
    let nowName = bufname('%')
    if nowName != startName
      break
    endif
  endwhile
endfunction

nnoremap <silent> <C-U> :call GoBackToRecentBuffer()<Enter>

You could probably write something similar for <C-I>.

Issues:

  • If there is no previous buffer, it will continue silently looping until you hit CTRL-C!

Related:

  • :jumps lists the historical locations that CTRL-O will step back through.
  • Vim's default CTRL-T is a good alternative to mashing CTRL-O, because it is coarser grained: it moves back through tag jumps only.
2
  • 1
    Vim seems to only offer one level of MRU file history, exposed on CTRL-^. However I have noticed when using :kwbd to close a few buffers, that Vim does step back to the previous buffers in the expected reverse-historical order. Perhaps Vim has a MRU list which it isn't sharing with us, or perhaps it chooses which buffer to fall back to based on the CTRL-O location history (:jumps). Jul 29, 2015 at 23:27
  • 1
    Alternatively, autocmd InsertLeave * normal mZ will remember the last edited file in the global mark Z. You can get back to it with g'Z. // I have nmap <C-y> g'Z but I still tend to use Ctrl-U more often. Aug 22, 2015 at 17:18
7

You can use :ls to show all buffers. For example:

:ls
  1      "vim.markdown"                 line 160
  2      "ext.markdown"                 line 0
  3 #    "~/to"                         line 1
  4 %a   "~/TODO"                       line 68

To go back to buffer ext.markdown, use :e +Nbuf, where N is the buffer number from the first column. For example: :e +2buf.

You can create a simple function for a more interactive experience:

fun! ChooseBuf()
    redir => buffers
        silent ls
    redir end

    echo l:buffers
    let l:choice = input('Which one: ')
    execute ':edit +' . l:choice . 'buf'
endfun
command! ChooseBuf call ChooseBuf()
nnoremap <Leader>b :call ChooseBuf()<CR>

After using :ChooseBuf or <Leader>b you can just type the number of the buffer you want to edit.

This is not quite "most recently used", since the order is "most recently opened" (this is probably also why :bnext/:bprev don't work as you expect).

5

<C-6> is what you need, that takes you back to the previous buffer you had open before the current one. There are also :bprev& :bnext which you could use for the same.

5
  • <C-6> isn't bad but I can't use that to jump back two buffers. bprev and bnext are not in order of jumps. Feb 6, 2015 at 9:40
  • Yea I don't think there's any good native way to go deeper into the history. You'd have to use some MRU plugin, even CtrlP has one, there must be others Feb 6, 2015 at 9:54
  • 2
    Note: it's not <C-6>, it's <C-^>. While on many terminal emulators there is no distinction, on some (including the one that ships with OS X), there is. For the latter case, the use of the Shift key is required (assuming Qwerty layout).
    – tommcdo
    Feb 9, 2015 at 11:55
  • @tommcdo interesting, I am on osx, but use iterm instead of the terminal.app, it works the same for me. Requiring Shift key on it would be a bummer. Feb 9, 2015 at 12:18
  • Come to think of it, it might just be that my OS is grabbing that key binding and not propagating it to Vim. My OS must be stopped!
    – tommcdo
    Feb 9, 2015 at 13:45
2

You can also use :oldfiles to get a list of files you edited.

The list will have numbers associated with filenames. Pick a file, note the number (say 14) and open it with :edit #<14

You can also run other commands on that file or pass multiple files to a command at once. More about this HERE

1
  • 1
    The other answer in the link taught me :bro[wse] ol[dfiles][!]
    – Steve
    Feb 5, 2016 at 14:03

Your Answer

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

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