shell

Vim. Editing multiple files

In previous issues, we have edited one file at a time. We did this because there were other points of interest at that time. However, Vim can handle more than one file at a time using several different techniques including buffers, viewports and tabs last one, since Vim 7. In this issue we take a look at these handy mechanisms that will speed up your work.

Buffers
We can think of a buffer as a place inside Vim where a file is loaded. In the following example, I will use a couple of files:

$ cat file1 file2
This is file 1
This is file 2
$ vim file1

This is file 1
~
~
~
~
~
~
~
~
~

To see file2, we use the :e command to load and edit the new file:


~
~
~
~
:e file2 [ENTER]

Hint: you can use TAB to autocomplete file names and commands


This is file 2
~
~
~
~
~
~
~
~
~

Vim is now showing file2, but what happened with file1? It is still there, loaded into the first buffer. We can return to it using the buffer previous command, :bp


This is file 1
~
~
~

What if we want to move to file2? buffer next, :bn. In fact, if you do it twice, you will get file1 again.
This is because buffers are circularly linked. Like this:

    

 ---------------------------- bn ---------------------------->
file 1 <--bp/bn---> file 2 <---bp/bn---> file 3 <--bp/bn---> ...<---> file N
<------------------------ bp ----------------------------

It is useful to know each buffer’s contents. You can do this with the :buffers command.


~
~
~
~
:buffers
  1 %a   "file1"                    line 1
  2      "file2"                        line 0
  3      "file3"                        line 0
  4      "file4"                        line 0
  5      "file5"                        line 0
  6      "file6"                        line 0

Imagine you are in the third buffer and you want to edit the 45th of a total of 100 files. In this case, you do not really want to use the :bn or :bp approach but the :buffer number command:



~
~
~
~
:buffer 45 [ENTER]

This command sends you to the exact buffer. One restriction to take into account when moving from one buffer to another is that you should save your work before leaving the current buffer. If you do not do it, you will see a message like the one below:

E37: No write since last change (add ! to override)

as when trying to quit Vim without saving.
To override this restriction (if you really want to do it), use a bang: :bn!. The content of the modified buffer will not be lost, it is a just a warning. However, it is a good habit to always save before leaving a buffer.
Every time you edit a file, it is loaded into a buffer even if you do it invoking Vim with several file names. For instance, if you start Vim like this:

vim file1 file2 file3

Vim will load the files into three different buffers (check it out with the :buffers command.

Viewports
A viewport can be imagined as a window inside Vim. Basically Vim splits the visual area into several parts either vertically or horizontally. We can use the :sp (split) or the :vsp (vertical split) with or without a file name. This is what appears after invoking Vim and executing the :sp command:


~
~
~
~
~
~
~
[No Name]                                                     0,0-1          All

~
~
~
~
~
~
[No Name]                                                     0,0-1          All

Pretty cool, isn’t it? You can jump from one viewport to another using Ctrl-w-w (this is, Control-w and then w again). When Vim is showing several viewports, all the actions take place at the specific viewport in which you are working. For instance, if you search a term, the search is limited to that viewport.
You can start Vim with several viewports using the -o and -O flags. The former splits the window horizontally, the latter does it vertically (forgive my use of screenshots but for once I guess they are illustrative :-) ):

$ vim -o make.conf sysctl.list

horizontal

A viewport can be split again into more viewports. That is nice, but you can end up with something similar to the screenshot below, so do not be too enthusiastic creating viewports ;) :

mess

Of course, in each viewport, the complete buffer list is available. This is a global list for each Vim session. The default layout of the viewports may well not satisfy your needs. In that case you can use the movement commands using uppercase letters preceded by Ctrl-w. These commands move the viewport in which they are applied. For example, if we have two vertical viewports and we are positioned at the left one, typing Ctrl-w L moves the viewport to the right and the right one to the left.

Tabs
Since Vim 7, there is a new way to edit multiple files. Tabs work like in many other applications (e.g. web browsers). To create a new tab, use “:tabnew“. You can use Ctrl-Up and Ctrl-Down to move through the tabs.

I know what you are asking yourself and the answer is yes: every tab has access to the global buffer list and it can be split into several viewports. Thousands of possibilities at hand!

tab1

tab2

There are a lot of commands to help you dealing with tabs. Some of them are :tabNext, :tabprevious, :tabfirst and :tablast to move through the tabs. :tabclose to close the current tab and :tabs to obtain a list of tabs.

Being efficient
Editing multiple files using buffers, viewports and tabs is OK. Having several files open at the same time, it is easy to move through them, etc. But what if you want to do something for all files at the same time? The family of commands [buf/win/tab]do do the magic. They apply an action to all the files in the list of buffers, viewports or tabs. For example:

~
~
~
~
~
~
~
:bufdo :%s/file/archive/g | w!

The command above replaces all the occurrences of file by archive (do not worry if you do not understand the command, we will visit the search and replace topic in another issue).
Other interesting command:

:bufdo !tar rvf package.tar %


Creates a tar file named package.tar containing all the files loaded into the buffers

Conclusion
Although this has not been an in depth tutorial about buffers, viewports and tabs, it should be sufficient to help you manage your files under Vim efficiently. As a programmer, I find these features extremely useful. I usually have my .h and .c/.cpp files open in two viewports so I can see both the declaration and the definition of the classes at the same time, for example.
Use these features for a while and you will realize how easy and efficient your daily work can become.

Enjoy!

Vim Sheet (IV)

  • :e Edit a new file (and load it into a new buffer)
  • :bp, :bn Move to the previous/next buffer
  • :buffer number Move to the specified buffer
  • :buffers, :tabs Show the list of buffers/tabs
  • :sp, :vsp Split the current viewport horizontally/vertically
  • Ctrl-w w Move to the next window
  • Ctrl-w H/J/K/L Move the current viewport in the specified direction
  • :tabnew Create a new tab
  • Ctrl-Up, Ctrl-Down Move to the next/previous tab
  • :tabNext, :tabprevious, :tabfirst, :tablast Movements through the tab list
  • :bufdo, :windo, :tabdo action Apply action on all the specified objects

1 Comment

  • On 10.14.10 enos76 said:

    Finally I can copy and paste on multiple files from within VIm! Thanks.

speak up

Add your comment below, or trackback from your own site.

Subscribe to these comments.

Be nice. Keep it clean. Stay on topic. No spam.

You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*Required Fields