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: vim programming
Comment by knutert@gmail.com
Hey!
I've also been struggling with this, thanks for the tips!
Comment by Ash
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
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
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
Comment by coelholds@gmail.com
UAU
That is perfect
Thank you very much
Comment by richstyles@gmail.com