Some Vim tips and tricks

This started out as an internal training at Adfinis SyGroup to show off some Vim features and how to work best with it. I’m assuming that you know the absolute basics, like Vim’s primary modes like insert, normal, ex, and what each one does.

Preparations

It’s essential that you get some text somewhere to play around. How about some Samuel L. Jackston Lorem Ipsum text? Go and grab some paragraphs of that.

Getting around

Characters, words, sentences, paragraphs. Functions, code blocks, etc. Learn them! There’s a lot more than what I’m showing here. To see more, just type :help motion.txt

Basic editing

Try to use Vim’s editing features and commands, instead of hanging around in insert mode and editing by backspace, delete and typing text. We’ll get into more advanced usage later, but here’s some basic commands. All of those can be used with either a visual selection, a movement or a text object:

Keys Explanation
c Change text. Basically a “delete” followed by an “insert”, but will only be one step in undo etc.
gU Make text uppercase
gu Make text lowercase

Movements

Movement Keys Explanation
Characters h, j, k, l J goes down, K goes up. H goes left, L goes right.. Use those instead of arrow keys, it’s faster!
fX Go to the next occurrence of the character X
tX Go to the left of the next occurrence of the character X
Fx Go to the previous occurrence of the character x
Tx Go to the left of the previous occurrence of the character x
Words w Go to the beginning of next word
b Go to the beginning of the previous word
e Go to the end of the next word
Lines _ Go to the beginning of the (possibly indented) text
$ Go to the end of the line
0 Go to the beginning of the line (first column)
gg Go to the first line in your file
G Go to the last line in your file
Text { Go to the beginning of the paragraph (Separated by an empty line)
} Go to the end of the paragraph
( Go to the beginning of the sentence
) Go to the end of the sentence
Code % When on a bracket / brace etc, go to the matching bracket

Almost any movements and other actions can be repeated. Need to move four lines up? Type “4k” (in normal mode, of course). Repetitions work in almost all situations in Vim.

Text Objects

Text objects are extremely useful in managing your … text! We’ve learned about lines, words and paragraphs already, but Vim knows a lot more shortcuts to get around text (or code, of course). Text objects are one major feature to do this.

Text objects can be used in two variants: “Inner” and “outer” mode. For example, the content of a pair of braces would be the “inner” variant, and if you want to include the braces pair, you would use the “outer” variant.

Before we get to some examples, you should note that this stuff only gets really powerful when combining directly with other editing commands. Most of this stuff works together as expected. So, when editing, try to directly use editing commands, instead of resorting to the simple basics (like deleting and then rewriting text). Here are some examples to combine the things we’ve learned above. Almost all editing commands support movements or visual selections as well. So here we go:

Keys Explanation
dap Deletes a paragraph (In text objects, “a” is outer, “i” is inner)
ci( Change contents of a braces pair
ca[ Replace an array subscript with something else
d3) Not a text object, but a movement: Delete three sentences
3ds Delete three sentences, this time using text objects
cit Assuming you’re in HTML between some tags: Change text between opening and closing tags

There are plugins available to add even more text objects. Python developers would probably love to hear that there is a plugin that turns indentation into text objects - thus you can manage indentation blocks just as well..

Again, there’s a huge number of shortcuts managing text objects. Type :help text-objects to find out more.

Registers

Vim has a ton of registers that you can use. There are 26 general-purpose registers (one for each character). You can yank text into the "a register by typing "ay, for example. To paste from the "a register again, type "ap.

A lot of people don’t know this, but you also have access to the registers in the ex-mode command line. If you want to search for some text that you currently have in the register "f, you can type / (to get into search mode), followed by Ctrl+R, followed by the character f.

If you want to see what’s currently in your registers, use :reg.

There are a lot of special-purpose registers as well. For example, the register "/ contains the last thing that you searched for, and "+ represents the X11 text selection. "* can be used to interact with the clipboard. If you yank something into that register, you can paste it in another application. If you you copied something in another application, you can read it using that register.

The numerical registers contain things that you’ve yanked the last few times. So go look there if you’ve just overwritten something.

There should be a special mention for the ". register, as well. It contains the last thing that you’ve inserted!

Macros

Vim also provides you with a simple way to automate things between learning command patterns and writing full-blown scripts, called macros. Macros are basically a set of commands, executed after one another. If you plan ahead a bit, you can get through a lot of text with quite little effort.

You can get into macro-recording mode by typing q, followed by a character denoting the register into which to store the macro. I’m usually just typing qq, therefore putting the macro into the "q register.

Macros work across multiple files as well, so be careful! A very common use case where I’m using macros is if I’m changing something similar in a bunch of files. Let’s make up a story here: I’m refactoring some python code, and moved a function from one module to another. On the way there, the function was also renamed. To simplify the whole affair a bit, assume that the function did indeed have a unique name.

To update all references, I need to add a new import line, and replace all calls to the old function to the new one. Here’s what I’d do:

  1. Open a new vim on the commandline, passing all python files as a parameter: vim $(find . -name "*.py")
  2. Start recording a macro by typing qq (as noted above, this puts the macro into the "q register)
  3. Find the first import line, and add my new import above it: /^import <Enter> O import newmodule <Esc>
  4. Replace all references to the old name: :%s/oldmodule.oldname/newmodule.newname/g <Enter>
  5. Open the next file from the command line: :next <Enter>
  6. End the macro recording mode by typing q again.

Now that I have the macro recorded, I can execute it using the @ command. This one also uses a register name as a parameter. And we want to do it for all python files on the command line, which I’m just assuming to be about 20 files, in total. So we repeat the command 20 times. To put it all together, type 20@q <Enter>. If there’s only 19 files, no problem. Macro execution stops on the first error (such as no more files on the list).

Using external tools

You can filter some lines or the whole file through external commands. This is extremely useful for formatting, sorting, or whatever else you want to do with your file.

Simply calling an external program will print it’s output to your screen, and when you press any key, the output will disappear. Try :!ls for example.

More useful is the ability to read the output from an external program. This can be very handy for downloading something right into your editor, for example: :r!curl http://store.nike.com/robots.txt

You can also filter some lines or the whole file. I’m using this mostly for code formatting and sorting. But you could also pipe out a formula to bc for calculation, for example… Try some of those: Write 123+999 on a new line, mark it in visual mode, then type :!bc followed by <Enter>. Don’t worry about the prefix in the command line - this is vim telling itself to work on the current visual selection.

Vim also has a very limited terminal emulator, reachable by calling :sh. However, this breaks for anything more complex than very simple commands. During `:sh execution, vim hides itself, and only comes back once you exit the shell. If you’re using Neovim (and you should!), then you get a full-blown terminal emulator that runs within a Vim window. It’s also way more feature-complete, so you can even do an Xzibit and run vim in your vim, so you can hack while you hack! Just type :terminal in an empty window, and enjoy :)

Plugins

These days, you should use a plugin manager to handle this - no more copying stuff all over your .vim directory! I’m using Vundle, which does a pretty decent job. Also, I suggest some minor hackery so you can autoinstall it on a new machine. I’ve written about this before: http://winged.ch/vundle_autoinstall/

Here’s a bunch of plugins that I’m currently using. I’m grouping them together by theme to make sure that I’m not installing two plugins that do essentially the same.

"""""""""""""""""""""""""""""""""""""""""""""""""""""
" Misc helpers                                      "
"""""""""""""""""""""""""""""""""""""""""""""""""""""
Plugin 'The-NERD-tree'                    " File manager etc
Plugin 'ctrlp.vim'                        " Open files by fuzzy matching filenames

"""""""""""""""""""""""""""""""""""""""""""""""""""""
" Motion / Text objects / Formatting helpers        "
"""""""""""""""""""""""""""""""""""""""""""""""""""""
Plugin 'vim-indent-object'                " Indentation text objects, useful for python development

"""""""""""""""""""""""""""""""""""""""""""""""""""""
" Completion / Compilers / syntax checkers          "
"""""""""""""""""""""""""""""""""""""""""""""""""""""
Plugin 'scrooloose/syntastic'             " Syntax checkers for almost everything
Plugin 'Valloric/YouCompleteMe'           " Code completion, supports many languages

Please note that I’m omitting a ton of plugins here, since this article would get way too long if I’d include and explain all of them.

Some of the plugins above should be looked at in more detail.

Vundle

Vundle works by introducing additional commands that can be used in ex mode, or listed in your .vimrc file. The Plugin command above tells it to use a given plugin (which it automatically installs by checking certain github repositories). There is also a PluginSearch and PluginInstall command. The latter doesn’t automatically update your .vimrc, however. So don’t forget to do that after installing a plugin, otherwise it won’t be working anymore when you restart Vim.

CtrlP

This plugin allows to quickly open a file. Once installed, type Ctrl+P to open the plugin’s menu. Then just type away until the file you want is selected. Then press <Enter> and it will open right away. If you want to keep the current file open, use <Ctrl+T> instead, so the new file gets put into a new tab.

Vim-Indent-Object

As commented, this introduces a new category of text objects, called indents. Those behave exactly the same as the other text objects. So you can use yii to copy the contents of a python function, for example. of yai to copy the function including it’s definition.

Syntastic

Syntastic introduces support for a ton of external syntax checkers, and is usually triggered just after saving a file. It will display all errors and warnings in a separate window. Please note that for this to work, the external syntax checkers must be installed, of course.

YouCompleteMe

As with Syntastic, YouCompleteMe relies on external tools, depending on the language you’re editing. Read it’s documentation to find out more.

Completion

Completion is another huge topic that could span multiple training sessions in it’s own right. So instead of explaining all of it, I’m just giving an overview here.

Vim knows a lot of different completion modes that can be triggered by Ctrl+X followed by some more keys. For example, Ctrl+X, Ctrl-O will activate Omni-Completion, which uses a vim function (usually from a plugin) for completion. This is mostly useful when programming.

Keys Explanation
Ctrl-X, Ctrl-N Local keyword completion
Ctrl-X, Ctrl-O (Programmable) Omnicompletion
Ctrl-X, Ctrl-F Filename completion
Ctrl-X, Ctrl-S Spelling / dictionary completion

Please note that plugins such as YouCompleteMe will change the behaviour of completion. Some map completion onto Tab for example. Please read the documentation of your plugins!

Training yourself

There are a few things you can do to force yourself to use Vim “the right way”. For example, here’s how you can disable the arrow keys, so you must use HJKL instead (which will make you a lot faster, because you won’t need to move your hand off the home row anymore..):

inoremap  <Up>     <NOP>
inoremap  <Down>   <NOP>
inoremap  <Left>   <NOP>
inoremap  <Right>  <NOP>
noremap   <Up>     <NOP>
noremap   <Down>   <NOP>
noremap   <Left>   <NOP>
noremap   <Right>  <NOP>

There are also people who think that Caps Lock is quite useless, and Escape is far away for your left pinky. Those people sometimes have the glorious idea to map Caps Lock to Escape. Unfortunately, you’d need to do this in your operating system’s settings.

Some more not-so-well known shortcuts

Keys Mode Explanation
Ctrl+A Normal Increment the number under the cursor (Works with hex, decimal, octal, …)
Ctrl+X Normal Decrement the number under the cursor (Works with hex, decimal, octal, …)
Ctrl+Z Normal Suspend vim, returns to your shell. Use fg to resume vim.
Ctrl+O Normal Go to previous position (for example when jumping, searching around etc)
Ctrl+I Normal Opposite direction of Ctrl+O
g; Normal Go to previous change. Can be prefixed by a number for repetition :)
g, Normal Go to next change (opposite of g;)

Final words

There is a lot more to Vim than what we’ve just touched here. And I mean A LOT MORE! Vim is probably one of those tools that nobody ever knows everything about. Maybe not even it’s author…

To learn more, it’s often quite useful to just browse around it’s awesome documentation a bit and try to improve your editing skills once in a while. Sometimes you will need to force yourself into a new habit, and thus slowing you down before it’s benefits will show up.

Also, there are quite a few awesome vim tutorials online. Here are some I really liked:

:wq