Vim Goodies

Given the vastness of Vim, I thought it would be helpful to point out some of the features that I think are most useful when programming. (It’s all in the manual, but you might not know where to look…) Note that some of this depends on configuration and plugins that I’ve already set up in the virtual machine. I’ll try to let you know when something I mention isn’t part of the default setup, and in those cases you can look through ~/.vimrc and the contents of ~/.vim/ to see what I’ve added.

Background

Before learning the fancy stuff in this document, you will want to get familiar with the basics. For this, you can run the command vimtutor in your terminal. The following links might also be helpful:

TL;DR

If you just want to read some interesting parts of the manual, here are the relevant sections, with no context. Some explanations / summaries are given in the sections that follow.1

Text objects

You can read all about it if you type :h text-objects from vim. A few notes on useful ones for programming:

Motion commands

In a traditional text editor, you move around with the arrow keys. In vim, you have lots of ways to move the cursor. In addition to the usual hjkl, you can move by sentences using (), paragraphs with {}, and if you use the linux kernel style guidelines (opening function brace on its own line), then [[ goes to the start of the current/previous function, and ]] to the start of the next one. For complete details read :h object-motions and :h motion.txt.

One other useful thing to point out is the g; command. This moves you backwards through the most recent places you’ve edited. The scenario is as follows: you’re editing something, and then you scroll around to look at something else for a moment, and maybe even make a little change. Rather than scroll your way back to what you were working on, just use g; once or twice and you’ll be right there. You can also explicitly set bookmarks in a file (see :h m), but I use g; far more often (probably because it requires no planning).

Code snippets

There is a nice plugin called snipmate for vim. It is already installed on the virtual machine. To try it out, open a C++ file, and then start typing a for loop. Just type for and then hit tab. It should expand into a skeletal for loop. To see the others and maybe add your own, look in the files

You can guess the format, or read the docs.

Formatting code

You can use the = command to properly indent / format your code. You can highlight something in visual mode and use it, but it also takes motion commands. So to auto-indent your whole file, you could do this: gg=G. See :h = for full details. By the way, I highly recommend you format your code the way = would! It’s true that the compiler doesn’t care, but proper indentation makes things a lot easier to read and understand.

Compiling with makefiles

This is covered in the workflow recommendations I gave you. I set it up so that if there is a makefile, you can compile your code by hitting \c, and if there are errors, move through them with ]q and [q (these are non-standard keybindings). More details can be found via :h :make and :h quickfix.

Supertab

I’ve set up supertab so you can tab-complete variable names, among other things. If you’ve already typed an annoying variable name in your program, you can start typing it, and while in insert mode, hit the tab key. It will try to fill the rest out for you. It can also complete file names! Try typing “~/csc” in insert mode, and then hit tab.

Spelling (not so useful for programming)

If you find yourself using vim for things other than code (I use it for just about every text editing task), I wrote something to make spelling correction easier. If you want to try it, open a new text file via $ vim /tmp/testfile.txt (this will ensure that spell checking is enabled) and then type a sentence like this: “This is a sentence withh spelling mistakez.” If you hit alt-s while in insert mode, it will go back, try to fix your mistake, and then jump back to where you were editing. This way you can fix mistakes as you type instead of after. If it guessed wrong, you can use alt-a to try the next guess, but sometimes it’s better to just go fix it manually. This also works in normal mode, but without the jump at the end. To see the vim script, look in ~/.vimrc around line 700, or just search for the word “spelling”. It is a wrapper for the features described in :h spell. (Note: if you have alt set as the $mod key for the window manager, then the above keybindings won’t get a chance to work. Perhaps consider changing $mod to the “win” key (Mod4 in your i3 config).)

Detective work

It is often useful to compare two files and highlight the differences (for example, if one of your tests for a project fails). Vim has a few built-in utilities for this. The first is the command vimdiff. If you want to see how files fileA and fileB differ, just run this command:

$ vimdiff fileA fileB

The above will show you the files side by side, “collapsing” sections that are identical so that you can focus on what is different.2

One other command worth mentioning (which is a part of the vim project) is xxd. This can help you track down more subtle differences in files, that might not be obvious from looking at a normal diff. It will show you what’s in a file, byte-for-byte, in a completely unambiguous way. This can be useful to detect differences due to characters with similar glyphs (like ‘O’ vs ‘0’), or differences in white space, like the presence of a trailing newline. Here’s an example:

$ echo 'hello world' | xxd
00000000: 6865 6c6c 6f20 776f 726c 640a            hello world.

The output is (by default) given in two “columns”: the left shows you each byte in hexadecimal (and the offset into the file at which those bytes appear), while the right side attempts to give a textual representation for the bytes corresponding to printable ascii characters. Pro-tip: you can combine xxd and vimdiff using process substitution and make quick work of what could have been a frustrating debugging session:

$ vimdiff <(xxd fileA) <(xxd fileB)


Back to the class homepage


  1. For this to make any sense, I’m assuming you’ve got basic vim usage figured out by now (you know the different modes and a few basic editing and movement commands, like dd deletes a line, and hjkl move around).↩︎

  2. You can achieve something similar using diff -y, but using vimdiff grants you additional benefits, like ease of navigation, the ability to expand collapsed matching sections, as well as syntax highlighting to show differences / similarities within a single line.↩︎