cloud cloud cloud

anntoin.com

Using Vim Buffers

previous

Using Vim Buffers

When I started using Vim, the tab feature had already been implemented.
This started me off with the bad habit of using tabs as I would in other applications i.e. each open file in its own tab. It took me a while to realise that Vim’s idea of tabs was not my own and that in Vim, tabs better represented separate editing sessions. When I came to this realisation it took a little while to adapt my editing behaviour to use buffers in preference to tabs.

In Vim using buffers instead of tabs is a better approach; you can keep your window layout intact while changing the file you are editing (as with a typical IDE). However, with Vim’s implementation of tabs, each new tab has its own window layout so if you open every file in a separate tab the layout doesn’t carry across. Initially I tried to find a way around this, however after some consideration I realised that Vim already had a mechanism that provided what I needed: buffers.

There are several buffer management plugins for Vim, but all that you need to get started with buffers are the following commands:

  • :e file - Open file in a buffer.
  • :buffers - List open buffers.
  • :bn - Go to buffer n.
  • :bd - Delete or close a buffer.

To ease the migration from tabs to buffers I used the minibufexplorer1 plugin, so that buffers can appear like pseudo-tabs along the top of the screen.

Here’s what minibufexplorer looks like.

Here’s what minibufexplorer looks like.

Also, if you are using buffers be sure to use set hidden in your .vimrc. This enables you to switch away from buffers that you are still editing, and makes dealing with multiple buffers much more convenient.

Issues

One issue I found with Vim buffers is that sometimes the command :bd will close Vim entirely, which I was not expecting. This is because :bd closes the buffer’s windows as well. There are a few ways to deal with this:

  • You can move away from the buffer you wish to close and use :bd # to close it - this will work everywhere.
  • There is also a plugin that adds a :BD command which closes the buffer without closing the window called BufKill. I found this to be a good solution to the problem.

Ctrl-Tab through buffers

One feature that I liked about minibufexplorer was that I could use Ctrl-Tab to switch between buffers in the currently active window by setting let g:miniBufExplMapCTabSwitchBufs = 1. This would not work when I first set it. I also found that mapping <C-Tab> to :bn<cr> wouldn’t work either. It took a little while to figure this one out, but I normally use Vim in a terminal and the reason for this not working is that xterm (or most terminal emulators) don’t send Ctrl-Tab as a separate keycode - it justs sends Tab. To fix this weird state of affairs you can override the keycode in your .Xresources like so:

*vt100.translations: #override \n\
        Ctrl ~Shift <Key>Tab: string(0x1b) string("[27;5;9~") \n \
        Ctrl Shift <Key>Tab: string(0x1b) string("[27;6;9~") \n

I got this tip from www.staldal.nu.

Then map these keycodes in Vim:2

set <F13>=^[[27;5;9~
set <F14>=^[[27;6;9~
noremap <F13> :bn<cr>
noremap <F14> :bp<cr>

To insert the ^[ symbol press Ctrl-V followed by Esc or to insert the entire keycode do Ctrl-V followed by Ctrl-Tab and Ctrl-Shift-Tab respectively (your modified .Xresources must have been loaded). GVim on the other hand can recognise Ctrl-Tab so you can set:

noremap <C-Tab> :bn<cr>
noremap <C-S-Tab> :bp<cr>

This will give you the same behaviour in GVim and Terminal Vim and works with or without minibufexplorer.

Do I not use Vim’s tab feature at all now?

The answer to that is no. I now use tabs for separate editing that would otherwise interrupt my current workflow.3


  1. This is a fork of the original minibufexplorer that has fixed a lot of issues.

  2. A post on stack overflow pointed me in the right direction.

  3. For another possiblity to make tabs behave more like buffers check out this post on stack overflow.
    This still doesn’t preserve viewports but may suit some people.

next