How do you prefer to switch between buffers in Vim?

I've tried MiniBufExplorer, but I usually end up with several windows showing it or close it altogether. What I'd like is something like LustyJuggler with incremental search, the way I switch between buffers in Emacs. Surely there is a script like this?


Solution 1:

I used to use a combination of tabs and multiple gvim instances, keeping groups of related files as tabs in each instance. So long as I didn't end up with too many tabs in one instance, the tab bar shows you the name of each file you're editing at a glance.

Then I read a post by Jamis Buck on how he switched from TextMate back to vim, and learned some great tricks:

  • Ctrl+w s and Ctrl+w v to split the current window
  • Ctrl+6 to switch back and forth between two buffers in the same window.
  • the awesome fuzzyfinder.vim which gives you auto-completing search of files in your current directory or of buffers you currently have open
  • Jamis' own fuzzy_file_finder and fuzzyfinder_textmate, which slightly modify how fuzzyfinder works to behave more like a similar feature in TextMate (as far as I can tell, the difference is that it matches anywhere in the filename instead of only from the start). Watch this video to see it in action.

Now I just have one gvim instance, maximised, and split it into multiple windows so I can see several files at once. I bound Ctrl+F to fuzzyfinder\_textmate, so now if I type (say) Ctrl+F mod/usob it opens up app/models/user\_observer.rb. I almost never bother with tabs any more.

Update 2010/08/07

While fuzzyfinder\_textmate remains awesome, as Casey points out in the comments, it's no longer maintained. Also, it (and/or fuzzyfinder.vim) gets a bit slow and unstable when working with large projects (lots of directories or files), so I've been looking for an alternative.

Fortunately, there seems to be a very nice alternative in the form of Wincent Colaiuta's Command-T plugin. This has very similar (if not slightly better) behaviour to fuzzyfinder\_textmate, but is noticeably faster; it also has nice features like being able to open the found file in a split or vertical split. Thanks (and upvotes!) to David Rivers for pointing to it.

Solution 2:

I use the basics - ':ls' + ':bn'/':bp' + ':b <part-of-name>'

Solution 3:

I like "ctrl-w s" and "ctlr-w v" to split the window. Then I map the movement keys (h, j, k, l) with ctrl held down to move between the split windows:

" Map ctrl-movement keys to window switching
map <C-k> <C-w><Up>
map <C-j> <C-w><Down>
map <C-l> <C-w><Right>
map <C-h> <C-w><Left>

Having to move my hand over to the arrow keys is annoying.

Next, I set up ctlr-tab to switch between buffers in the current window (like a lot of other environments):

" Switch to alternate file
map <C-Tab> :bnext<cr>
map <C-S-Tab> :bprevious<cr>

These have worked pretty well for me over the last several years although vim always has more secrets than you can know.

Solution 4:

I have been using Wincent Colaiuta's Command-T vim plugin for a couple months now. Wincent wrote the parts of it that need to be fast in C, and I must say that it is! And, I think its file pattern matching logic is even better than Textmate's Command-T. Check out the screencast.

The Command-T plug-in for VIM provides an extremely fast, intuitive mechanism for opening files with a minimal number of keystrokes. It's named "Command-T" because it is inspired by the "Go to File" window bound to Command-T in TextMate.

Files are selected by typing characters that appear in their paths, and are ordered by an algorithm which knows that characters that appear in certain locations (for example, immediately after a path separator) should be given more weight.

Easier buffer switching contains many useful tips. I have adapted the following to my .vimrc, which does buffer-name auto-completion, maps the most useful buffer-switching commands to my <Leader> and left-side home row keys, and shows the current buffer number in the status line:

"" Tab triggers buffer-name auto-completion
set wildchar=<Tab> wildmenu wildmode=full

let mapleader = ","

map <Leader>t :CommandT<Return>
map <Leader>a :bprev<Return>
map <Leader>s :bnext<Return>
map <Leader>d :bd<Return>
map <Leader>f :b 

"" Show the buffer number in the status line.
set laststatus=2 statusline=%02n:%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P

I also use MiniBufExplorer, which provides a compact listing of each listed buffer in its own horizontal split up top.

Solution 5:

nmap <Leader>bb :ls<CR>:buffer<Space>

and nobody mentioned nice plugin ctrlp.vim. Using this plugin you can search buffer by name.