Linux Tools - vimdiff

An image of a cup of coffee at keyboard

Welcome to episode one of the Linux Tools series. This article is about vimdiff - which I consider one of the essential and important tools that should be in every Linux admin's toolbox. I frequently find myself connected to some webserver via ssh to make some minor change(s) to a file, and vim and vimdiff are what I reach for.

First a little discussion about the difference between vi (pronounced vee-eye by the way) and vim (which stands for Vi IMproved). There are some purists who claim that vim is bloated and slow. That may be true, but on most modern Linux distributions vi is simply a sym link or wrapper pointing to vim anyway, so even if you just type vi as opposed to vim - you still get vim. So this discussion is about the tool available to most of us using Linux. I know there are a lot of people using things like NeoVIM and such, but this article isn't about that either - just the basic tool vim, and specifically vimdiff which technically is just a subset of the more expansive vim command set.

Your mileage may vary, but in my experience the vimdiff command wasn't installed with the minimal server install, so when provisioning a new box that I will be managing, it's one of the items that gets included in the first round of installs. On Redhat flavors (CentOS, Fedora, Rocky) that's "dnf install vim" , and on Debian flavors it would be "apt install vim". On all the distros that I've used lately, vi was there out of the box, but vim was not (even though as stated above vi was still really vim) and thus neither was vimdiff. As mentioned in the preceding paragraph, you can start in vim and open multiple files and then turn on diff mode...but vimdiff is just a shortcut to getting there, and I like shortcuts.

To compare two or more files, side-by-side, just type:

vimdiff file1 file2 [file3 [file4] ...]

You will be presented a diff view with the diffs being highlighted with red for something that's different in a line, blue and green for entire lines that exist in one but not in other(s). The problem is that sometimes those highlight colors make it impossible to read the text being highlighted (depending on your default color scheme)...so you may need to change the colorscheme on the fly to make it more readable. To do that first check what colorschemes are installed and available, then choose one. The following two commands for example choose the elflord scheme:

:colorscheme Ctrl-d
blue       default    desert     evening    koehler    murphy     peachpuff  shine      torte
darkblue   delek      elflord    industry   morning    pablo      ron        slate      zellner

:colorscheme elflord

To be clear, that first command is :colorscheme and then a space and then holding down the Ctrl key while pressing d, and of course if you already know the name of the colorscheme to which you want to switch you can skip that step and simply issue the second command.

OK, now that we can read our files, let's look at how to navigate around them.

Cursor navigation:

]c move cursor to next diff occurrence
[c move cursor to previous diff occurrence
Ctrl-w l move cursor to the buffer to the right
Ctrl-w h move cursor to the buffer to the left
Ctrl-w w move cursor to the next buffer *
:ls or :buffers list all open buffers (or files)

* the difference between Ctrl-w l and Ctrl-w w is that if you are in the far right pane, Ctrl-w w goes back to pane 1.

Diff commands:

If you are only working with two files, do and dp work just fine as shortcuts, but if you are working with more than 2 files you will need to use the full commands because you have to tell vim which file you are getting from or putting to, by using the number of the buffer (which you got from the :ls command). Say you have 3 files test1.txt, test2.txt, and test3.txt open in buffers 1, 2, and 3 respectively. If your cursor is in buffer 1 sitting on top of a diff and you want to put that diff to buffer 3 you would use the command 

:diffput 3

do or :diffget obtains (gets) the diff from other file
dp or :diffput puts the diff to the other file
:diffupdate rescan the files for diffs *

* I haven't experienced it, but apparently sometimes vimdiff gets confused after you make some puts or gets and :diffupdate refreshes the view.

Fold manipulation:

zo open the fold under the cursor
zc close the fold under the cursor
zr open all folds
zm close all folds

By default, vimdiff will close any folds where there aren't any diffs, and it will do that as soon as you perform one of the modifications that eliminates a diff. If you're like me, before saving changes, you want to view the entire file to make sure you didn't wreck it, so that zr command comes in really handy.

That brings us to the commands for closing and/or writing file(s).

Exiting:

The standard vim commands work here - one thing to pay attention to though is where your cursor is located, because the : commands apply to that file.

:q close the file
:w write the changes to the file
:wq write the changes and then close the file
:qa close all files ( you already wrote them, right? )

 

There are more commands, but these are the ones you will use most often.

One of the most exhaustive vim cheat sheets can be found here: https://vim.rtorr.com/