Multi-file Editing in Vim 7.0

Vim supports editing many files at once. That's a great feature for programmers like me. I can copy and paste text between files, search for identifiers in other files, and view 2 (or more) files on one screen. Vim provides copious commands to list, add, delete, cycle through, and split buffers. And then Vim 7.0 comes along and adds tabs to the mix.

Help! I'm drowning in options.

I find myself wishing for a simpler model for multi-file editing. Maybe a tab-per-buffer model where you could glance at the tab names to know which buffers are open. But why give up splits? I use :stselect <ident> to follow tag references all the time. All I really want to do is know what files I have open, and move between them without wrecking my tab and window layout.

To help untangle these options, let me summarize vim's data model - the primary elements are buffers, windows and tabs.

Buffers

A buffer is a file that has been loaded into memory for editing. A buffer is modified during your editing session but isn't saved to disk until you do :w. New buffers are created with :e <filename>.

The :ls command lists all my buffers. I often rotate through buffers with :bn (buffer next). You can change to a specific buffer with :b<buffer number>, but I find that tedious, as you first have to use :ls to find the buffer number. Plugins like bufexplorer and minibufexpl can make switching buffers more intuitive.

Windows

A window is nothing more than a view of a buffer. Multiple windows can view one buffer so edits in one window are displayed in all windows on that buffer - try :split and make some edits. But more commonly, you use windows to view different buffers at the same time

I tend to use windows ephemerally - I'll use a split command to quickly reference another file and then close the new window. Programmers like to be able to view lots of text at once, and windows cut down on viewable lines.

I also find the stock commands to flip between windows cumbersome so I have mapped <leader>w to Ctrl-W w, which lets me toggle through the window list.

Tabs: new for Vim 7.0!

A tab is a full-screen collection of windows. Tabs let you partition your windows into any scheme you like. A 'tabline' at the top of the vim window lets you know which tab you are in. :gt moves you to the next tab. Sometimes I prefer one tab per buffer (try :tab sball), or you could have a C header file and its implementation per tab.

Frustrations and switchbuf to the Rescue

All this brings me to my problem - I have too many ways to move between buffers. The :ls command lists all the buffers and their buffer numbers; :b<number> replaces the contents of the current window with the requested buffer; :gt moves to the next tab; and I configured <leader>w to move to the next window (within a tab). That's a lot of options.

Generally, I want a way to move between 'files' without disturbing my current window and tab layout. As I finally learned, a combination of :sb and switchbuf makes this possible.

The :sb <buffer> (split buffer) command usually opens a new window with the requested buffer. You can give the command a buffer number or a filename. With the set switchbuf=usetab option, you can tell vim to first search the tab and window list for the requested buffer - if the buffer exists is in a window or tab, the focus goes right to that window. The :sbn (split buffer next), when used with switchbuf, lets me flip through the list of my open files.

Problem solved!

Technorati tags for this post:

Comments on "Multi-file Editing in Vim 7.0":

Comment by knutert@gmail.com

Posted at Aug 13th 2006.

Hey!

I've also been struggling with this, thanks for the tips!

Comment by Ash

Posted at Sep 12th 2006.

Thanks for this perfect tip!

I mapped "go buffer"

map gb :bn

map gB :bN

too (same way as "go tab" = gt/gT works) and opened either buffers or tabs (never both) during each session to prevent flustration :), but now i see :sb works perfectly with switchbuf=usetab. Thanks.

Comment by Ash

Posted at Sep 12th 2006.


Thanks for this perfect tip!

I mapped "go buffer"

map gb :bn

map gB :bN

too (same way as "go tab" = gt/gT works) and opened either buffers or tabs (never both) during each session to prevent flustration :), but now i see :sb works perfectly with switchbuf=usetab. Thanks.

Comment by Ash

Posted at Sep 12th 2006.


Thanks for this perfect tip!

I mapped "go buffer"

map gb :bn≶cr>

map gB :bN≶cr>

too (same way as "go tab" = gt/gT works) and opened either buffers or tabs (never both) during each session to prevent flustration :), but now i see :sb works perfectly with switchbuf=usetab. Thanks.

Comment by matt

Posted at Sep 19th 2006. matt's URL
Ash and knutert - you're welcome. It looks like I need to work on the escaping of my html, huh?

Comment by coelholds@gmail.com

Posted at Feb 28th 2007.

UAU

That is perfect

Thank you very much

Comment by richstyles@gmail.com

Posted at Nov 3rd 2007. richstyles@gmail.com's URL
You can also do ":vert sb" to split the buffer vertically.
Allowed html tags: br p blockquote i b em code strong u ol ul li a
(type "human" here)