Vim anti-patterns

The benefits of getting to grips with Vim are immense in terms of editing speed and maintaining your “flow” when you’re on a roll, whether writing code, poetry, or prose, but because the learning curve is so steep for a text editor, it’s very easy to retain habits from your time learning the editor that stick with you well into mastery. Because Vim makes you so fast and fluent, it’s especially hard to root these out because you might not even notice them, but it’s worth it. Here I’ll list some of the more common ones.

Moving one line at a time

If you have to move more than a couple of lines, moving one line at a time by holding down j or k is inefficient. There are many more ways to move vertically in Vim. I find that the two most useful are moving by paragraph and by screenful, but this depends on how far and how precisely you have to move.

  • { — Move to start of previous paragraph or code block.
  • } — Move to end of next paragraph or code block.
  • Ctrl+F — Move forward one screenful.
  • Ctrl+B — Move backward one screenful.

If you happen to know precisely where you want to go, navigating by searching is the way to go, searching forward with / and backward with ?.

It’s always useful to jump back to where you were, as well, which is easily enough done with two backticks, or gi to go to the last place you inserted text. If you like, you can even go back and forth through your entire change list of positions with g; and g,.

Moving one character at a time

Similarly, moving one character at a time with h and l is often a waste when you have t and f:

  • t<char> — Move forward until the next occurrence of the character.
  • f<char> — Move forward over the next occurrence of the character.
  • T<char> — Move backward until the previous occurrence of the character.
  • F<char> — Move backward over the previous occurrence of the character.

Moving wordwise with w, W, b, B, e, and E is better, too. Again, searching to navigate is good here, and don’t forget you can yankdelete or change forward or backward to a search result:

y/search<Enter>
y?search<Enter>
d/search<Enter>
d?search<Enter>
c/search<Enter>
c?search<Enter>

Searching for the word under the cursor

Don’t bother typing it, or yanking/pasting it; just use * or #. It’s dizzying how much faster this feels when you use it enough for it to become automatic.

Deleting, then inserting

Deleting text with intent to replace it by entering insert mode immediately afterward isn’t necessary:

d2wi

It’s quicker and tidier to use c for change:

c2w

This has the added benefit of making the entire operation repeatable with the . command.

Using the arrow keys

Vim lets you use the arrow keys to move around in both insert and normal mode, but once you’re used to using hjkl to navigate, moving to the arrow keys to move around in text feels clumsy; you should be able to spend the vast majority of a Vim session with your hands firmly centered around home row. Similarly, while the Home and End keys work the same way they do in most editors, there’s no particular reason to use them when functional equivalents are closer to home in ^ and $.

So wean yourself off the arrow keys, by the simple expedient of disabling them entirely, at least temporarily:

noremap <Up> <nop>
noremap <Down> <nop>
noremap <Left> <nop>
noremap <Right> <nop>

The benefits of sticking to home row aren’t simply in speed; it feels nicer to be able to rest your wrists in front of the keyboard and not have to move them too far, and for some people it has even helped prevent repetitive strain injury.

Moving in insert mode

There’s an additional benefit to the above in that it will ease you into thinking less about insert mode as a mode in which you move around; that’s what normal mode is for. You should, in general, spend as little time in insert mode as possible. When you want to move, you’ll get in the habit of leaving insert mode, and moving around far more efficiently in normal mode instead. This distinction also helps to keep your insert operations more atomic, and hence more useful to repeat.

Moving to Escape

The Escape key on modern keyboards is a lot further from home row than it was on Bill Joy’s keyboard back when he designed vi. Hitting Escape is usually unnecessary; Ctrl+[ is a lot closer, and more comfortable. It doesn’t take long using this combination instead to make reaching for Escape as you did when you were a newbie feel very awkward. You might also consider mapping the otherwise pretty useless Caps Lock key to be another Escape key in your operating system, or even mapping uncommon key combinations like jj to Escape. I feel this is a bit drastic, but it works well for a lot of people:

inoremap jj <Esc>

Moving to the start or end of the line, then inserting

Just use I and A. Again, these make the action repeatable for other lines which might need the same operation.

Entering insert mode, then opening a new line

Just use o and O to open a new line below and above respectively, and enter insert mode on it at the same time.

Entering insert mode to delete text

This is a pretty obvious contradiction. Instead, delete the text by moving to it and using d with an appropriate motion or text object. Again, this is repeatable, and means you’re not holding down Backspace. In general, if you’re holding down a key in Vim, there’s probably a faster way.

Repeating commands or searches

Just type @: for commands or n/N for searches; Vim doesn’t forget what your last search was as soon as you stop flicking through results. If it wasn’t your most recent command or search but it’s definitely in your history, just type q: or q/, find it in the list, and hit Enter.

Repeating substitutions

Just type & to repeat the last substitution on the current line. You can repeat it on all lines by typing g&.

Repeating macro calls

Just type @@.

These are really only just a few of the common traps to avoid to increase your speed and general efficiency with the editor without requiring plugins or substantial remappings. Check out the Vim Tips wiki for some other really helpful examples.