78

One way to select a buffer in Vim could be to browse the buffers list, using standard commands as :ls, or with some external plugin / vimscript code to browse a list in a window.

Let's say I want to jump to a buffer directly, as fast as possible.

To traverse the buffer list in sequential mode, I now use <C-J> <C-K> shortcuts, having set in my .vimrc:

" move among buffers with CTRL
map <C-J> :bnext<CR>
map <C-K> :bprev<CR>

Another way (direct access) could be switching by number: knowing the buffer number, it is possible to switch directly by entering the buffer number followed by <C-^>. So if I want to switch to buffer number 5, I would press 5<C-^>.

But this seem not working for me (I use vim 7.4 on ubuntu box, from a Windows guest, with Italian keyboard). I suspect that's because the ^ character is in the upper case key in the Italian keyboard, so in fact to got ^ I need to press SHIFT-^

Any ideas?

7
  • 4
    Can you press <c-6> instead of <c-^>? Feb 23, 2015 at 15:34
  • do you mean Ctrl-1 to go to buffer number 1 ? Unfortunately doesn't work. nothing happen Feb 23, 2015 at 18:52
  • 1
    No. Some terminals can understand Ctrl-6 which is the same as Ctrl-^ on the US keyboard. Feb 23, 2015 at 19:54
  • 2
    +1 Great, It work! I use an Italian keyboard layout (using putty terminal emulator). So: 1<C-6> switchs to buffer number 1. Thanks! Feb 24, 2015 at 7:12
  • 1
    You can also open any alternative buffer in a new window by typing: Ctrl-w 5 Ctrl-6 where 5 is the alternative buffer you want to open and also Ctrl-w Ctrl-6. Sep 22, 2017 at 17:31

8 Answers 8

87

The :b command can also take a substring of the name of the file of the buffer which you want to travel to, which is very convenient.

For example, if you have three buffers foo, bar, and baz, then

  • :b bar will switch to the bar file.

  • :b o will switch to the foo file.

  • :b a will give you an error because it could mean either bar or baz, but you can fix the name to be more specific with, for example, : r Enter.

This can be very useful, because it means instead of

:buffer very/very/long/path/to/a/veryVeryLongFileName.txt

you can do something like

:b LongFileName

which is much shorter and easier.

This command can also take a number, if you want to use that:

:b 5
3
  • 8
    A caveat about using partial buffer names: if the partial buffer name appears at the beginning of a word boundary in some buffer's path, no buffer with the partial name in the middle of a word will be accessible by the :b command. For example, if you have two buffers path/to/foo and path/to/tofu, the command :b f<Tab> will never match path/to/tofu, since it matches at the beginning of a word in path/to/foo.
    – tommcdo
    Feb 23, 2015 at 13:36
  • 3
    :5b is slightly shorter then :b 5 ;-) Feb 24, 2015 at 22:00
  • 4
    @joeytwiddle or :b5 if one prefers:)
    – bloody
    Apr 7, 2020 at 21:54
37

This is what I use:

nnoremap <Leader>b :ls<CR>:b<Space>

Now pressing \b will list the available buffers and prepare :b for you.

Then you can just type the buffer number, and hit Enter.

Or you can type part of the filename, and hit Enter. (However I usually hit Tab before hitting Enter, to check I got the right buffer. If not, I continue cycling with Tab until I get the one I wanted.)


In fact, I use a slightly tweaked version of the above:

nnoremap <C-e> :set nomore <Bar> :ls <Bar> :set more <CR>:b<Space>

This will prevent the -- More -- prompt from appearing when you have more buffers than available lines to display them.

But if you usually have the 'more' option disabled anyway, this mapping will really annoy you, because it re-enables the 'more' option after doing ls!

8
  • 3
    Truth be told, I don't actually use either of those, I use my own little plugin, but the functionality is very similar. With the plugin, I can also perform Tab-complete on the filenames of un-opened buffers. Feb 24, 2015 at 22:24
  • 1
    Although this technique isn't as fast as using [count]<C-^> when you know the buffer number, it is pretty useful when you don't know. Feb 24, 2015 at 22:28
  • 2
    thanks joeytwiddle for your notes. I'll check your plugin asap. In my case (see keyboard issue above) [count]<C-6> appear to me the fastest way to switch to known buffer Feb 25, 2015 at 9:25
  • Yeah I am also using [count]<C-^> these days. But that means I need to run MiniBufExplorer or something similar, to know what the buffer numbers are! Sep 25, 2017 at 4:16
  • why do you need the <CR> and the <SPACE>? At first it appears to me, as if it works fine without them... Aug 30, 2018 at 19:59
23

:CtrlPBuffer from plugin CtrlP (5k ★)

Main feature of this plugin is to provide a fuzzy matching to conveniently open a different buffer with visual feedback.

Open the fuzzy buffer listing with :CtrlPBuffer or press <C-p> followed by <C-b> to change the mode to buffer.

Enter a sufficient number of characters to specify the buffer you want to open.
You can also use <C-j> and <C-k> to cycle through the list and select manually the buffer.

enter image description here

Customization

If you wish to open the buffer list immediately with <C-p>, add following line to your vimrc:

let g:ctrlp_cmd = 'CtrlPBuffer'

You can use <C-f/b> to switch the mode of the ctrlp window.

I personally use let g:ctrlp_cmd = 'CtrlPMRU'. The most recently used (mru) list also contains the opened buffers. If you use different ctrlp modes and want to stick to your last mode, you can set let g:ctrlp_cmd = 'CtrlPLastMode [--dir]'.

Similar plugins

There are many more plugins which provide a buffer list with an interactive prompt with fuzzy matching, e.g.

The dark side vs. the light side

(i.e. plugin-heavy vim setup vs. the vim way)

Before you decide to use these more complex plugins, study the answers by @Doorknob and @joeytwiddle. In particular, check the one-liner if one of them already fulfills your needs.

  1. nnoremap <Leader>b :b <C-d>
  2. nnoremap <Leader>b :ls<Cr>:b<Space>

Installing the plugins just for buffer switching might be an overkill. See also the remarks on https://www.vi-improved.org/recommendations and the article by Drew Neil ‘On sharpening the saw’.

5
  • yes Hotschke, I confess i often use :CtrlPBuffer Jan 11, 2017 at 10:36
  • I am using map <leader>a <ESC>:CtrlPBuffer<CR><CR> to jump to the previously opened buffer with <leader>a (while <leader>b just opens the buffer list for me)
    – Rolf
    Sep 13, 2018 at 7:59
  • @Rolf: do you know <C-^> (= <C-6>)? see :h CTRL-^. Afaik, this just does what your mapping <leader>a seems to do. Therefore I think you just brought an example why people say using plugins might lead to vim user who do not know what vim already can do on its own.
    – Hotschke
    Sep 13, 2018 at 8:25
  • @Hotschke: No, I didn't know that. Learned something knew, thanks! I'm gonna remap <C-^> though.
    – Rolf
    Sep 14, 2018 at 6:44
  • 1
    Excellent reference to <C-d> with vanilla vim. I haven't seen that reference anywhere else.
    – radke
    Jul 31, 2019 at 16:01
13

[b and ]b from plugin vim-unimpaired (> 3k ★)

If you happen to have installed vim-unimpaired, you can use

  • [b (:bp[revious]) and
  • ]b (:bn[ext])

for cycling through open buffers. No need to define more precious mappings for the same commands. Furthermore, jumping to the first and last buffer can be done by

  • [B (:bf[irst]) and
  • ]B (:bl[ast]).

There are plenty more bracket-mappings contained in vim-unimpaired which you might find useful. They all follow the same scheme which makes it easy to memorize them.

The dark side vs. the light side

This plugin can be considered lightweight and 'vimish'. It is denoted by the #vim community as a "does not harm" plugin.

1
  • 1
    +1 Also worth noting that you can provide a count. 3[b to jump three buffers back. Apr 29, 2019 at 3:28
9

In addition to really useful answers by joeytwiddle and Doorknob don't forget about :b#, which switches to most recently used buffer. It can also be done with just <C-^>. When you have a lot of buffers and you constantly switch between them, the most recent buffer is usually the most common destination.

Personally I use combination of many methods. When I'm working with mainly two buffers and the rest is opened just for occasional reference, I tend to switch between them with :b# or <C-^>. When I have to work with more of them and switch more often, I use either numbers (as in joeytwiddle tip), or part of names (as in Doorknob tip) with TAB to complete them. When the names are confusing, and there are many buffers opened (usually over 10), I use Ctrl-P plugin more often (https://github.com/kien/ctrlp.vim) With two fast keystrokes I got the list of them all and I'm able to use powerful fuzzy search over them to find quickly what I want.

1
  • 2
    <C-^> alone (<C-6> in my case, as Peter Rincker suggested) is a good trick in case of just 2 buffers :-) Feb 26, 2015 at 16:50
4

Currently I'm using <Leader>+number key to switch. The leader key is my <space> key. I also use vim-airline to show the buffer nr on top of the window.

" airline settings
let g:airline#extensions#tabline#buffer_nr_show = 1
let g:airline#extensions#tabline#enabled = 1

While the bufnr often exceeds 10, so I tweak my own mapping, if the number is the only match, switch buffer immediately, otherwise wait for more number input or <space> key for confirm:

nnoremap <expr> <Leader>1 tweak#wtb_switch#key_leader_bufnum(1)
nnoremap <expr> <Leader>2 tweak#wtb_switch#key_leader_bufnum(2)
nnoremap <expr> <Leader>3 tweak#wtb_switch#key_leader_bufnum(3)
nnoremap <expr> <Leader>4 tweak#wtb_switch#key_leader_bufnum(4)
nnoremap <expr> <Leader>5 tweak#wtb_switch#key_leader_bufnum(5)
nnoremap <expr> <Leader>6 tweak#wtb_switch#key_leader_bufnum(6)
nnoremap <expr> <Leader>7 tweak#wtb_switch#key_leader_bufnum(7)
nnoremap <expr> <Leader>8 tweak#wtb_switch#key_leader_bufnum(8)
nnoremap <expr> <Leader>9 tweak#wtb_switch#key_leader_bufnum(9)




func! tweak#wtb_switch#key_leader_bufnum(num)
    let l:buffers = tweak#wtb_switch#buflisted()
    let l:input = a:num . ""

    while 1

        let l:cnt = 0
        let l:i=0
        " count matches
        while l:i<len(l:buffers)
            let l:bn = l:buffers[l:i] . ""
            if l:input==l:bn[0:len(l:input)-1]
                let l:cnt+=1
            endif
            let l:i+=1
        endwhile

        " no matches
        if l:cnt==0 && len(l:input)>0
            echo "no buffer [" . l:input . "]"
            return ''
        elseif l:cnt==1
            return ":b " . l:input . "\<CR>"
        endif

        echo ":b " . l:input

        let l:n = getchar()

        if l:n==char2nr("\<BS>") ||  l:n==char2nr("\<C-h>")
            " delete one word
            if len(l:input)>=2
                let l:input = l:input[0:len(l:input)-2]
            else
                let l:input = ""
            endif
        elseif l:n==char2nr("\<CR>") || (l:n<char2nr('0') || l:n>char2nr('9'))
            return ":b " . l:input . "\<CR>"
        else
            let l:input = l:input . nr2char(l:n)
        endif

        let g:n = l:n

    endwhile
endfunc

func! tweak#wtb_switch#buflisted()
  return filter(range(1, bufnr('$')), 'buflisted(v:val)')
endfunc

The code is pasted from here

By the way, I also use <S-h> and <S-l> for :bp and :bn, or :tabp and :tabn if more than one tabpage is opened currently. It's quite intuitive for me.

1
  • yesssssss. glad i scrolled down on this thread. thank you. Jul 28, 2020 at 23:10
2

These days I am using [buffer_number]<Ctrl-^> to switch buffers because it is very fast.

But how to know the buffer number? I use MiniBufExplorer so I can always see the buffer numbers at the top of Vim.

I also use the following mapping, because <C-^> is a bit hard to reach with one hand.

:nmap <C-E> <C-^>

On a fresh machine with no config, I fall back to :b [part_of_filename]<Tab><Enter>

1

junegunn/fzf.vim provides :Buffers for fuzzy search.

nnoremap <Leader>b :Buffers

enter image description here

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.