Erik Ramsgaard Wognsen

Thoughts & technology

Learn Vim the Harder Way, Part II

In a previous post I introduced learning Vim the harder way. To summarize:

  • The easy way: Use the arrow keys for cursor movement
  • The hard way: Don’t use arrow keys; use hjkl in normal mode
  • The harder way: Don’t use hjkl; learn Vim’s multitude of other motion commands

Now, there’s nothing wrong with using the arrow keys per se, but it very often leads to staying in insert mode most of the time and thus missing out on all the stuff you can do from normal mode. As someone wrote about vi/Vim:

your keyboard becomes a huge specialized text-editing gamepad with almost a hundred buttons.

There’s nothing wrong with using hjkl either, in fact they’re very good because they force you to use normal mode as your, well, normal mode. However, normal mode only really provides an advantage if you harness its power and go beyond the basics. For motions, that involves reducing your use of hjkl. In this part we see how to do that for inserting and deleting text.

Insert Without i

One of the first things Vim users learn is that you type i to go to insert mode (where you can write text). Just like hjkl, i is a basic command. And just like there are many other motions beyond hjkl, there are more commands that bring you to insert mode:

  • a appends text after the current character (like i inserts before it).
  • I and A insert text at the beginning and end of the line, respectively, no matter where on the line your cursor is.
  • o and O “open” a new blank line for writing immediately after and before the current line, respectively (no matter where on the line your cursor is). When used for programming (for example with :set autoindent), “open” also does intelligent indentation.
  • gi inserts text where you last stopped inserting text, no matter where in the buffer the cursor now is.

Try disabling i with :nmap i <nop>, or perhaps with a reminder of what to do instead: :nnoremap i :echoerr "Try a/I/A/o/O/gi instead!"<cr>. It’s really annoying, but that’s the point. Once you have a basic grasp of the other insert mode commands, you can remove the mapping again with :nunmap i.

By the way, I lied a bit earlier. The command I doesn’t insert at the beginning of the line. It inserts immediately before the first non-whitespace character of the line, which is often convenient, not least in programming. But you can still tell Vim to really insert at the beginning of the line with the command gI. Vim is thorough like that.

Delete Without Backspace

Now you know a flexible set of commands to go to insert mode. Once you’re there, there’s one thing you should not to too much (beside use the arrow keys), and that is: backspace. Like many other commands, it is a basic operation good in some cases and inefficient in others. It’s good for correcting a typo, but deleting words and anything bigger is like digging with a teaspoon. So I’d recommend removing the temptation to use the teaspoon by disallowing backspacing past the position where you started insert mode:

1
set backspace-=start

You can still correct typos while you type. In normal mode you can also delete a few chars with the x and X commands which work like delete and backspace do in insert mode.

For anything bigger, use the delete command d. It takes a motion or text object. For example, dw deletes from the cursor position until the start of the next word, dt' deletes until the next apostrophe, and dap deletes a paragraph (the one the cursor is currently in). All in one step.

Besides being more efficient, doing it as a single command has the advantage that it can be undone as a single command (u), and, perhaps more importantly, that you get the whole thing copied so you can insert it later (in Vim, delete and cut are the same thing).

Delete and Insert at the Same Time

In the previous section I suggest staying in normal mode when removing text. But what if you want to both delete and insert text? Just like Vim provides many commands than combine moving the cursor and inserting text (a, I, A, etc.), it also provides commands that combine deleting and inserting:

  • r replaces the character under the cursor with another character of your choosing
  • R drops you into replace mode where you overwrite/replace text until you return to normal mode with Esc.
  • s/S substitute the character/line under the cursor with any text (insert mode)
  • c changes text into other text: It first awaits your choice of motion or text object to delete and then drops you into insert mode. For example, c) changes from the cursor position until the end of the sentence and ci" changes the whole content of the double quote delimited string the cursor is in.
  • C changes from the cursor position to the end of the line (similarly to how D deletes from the cursor position to the EOL while d takes a motion or text object)

If you’re comfortable with x/X/d, but not the replace/substitute/change commands, I’d recommend something crazy: Disable x, X, and d:

1
2
3
nmap x <nop>
nmap X <nop>
nmap d <nop>

Instead, the stuff you want to delete, you can substitute/change into nothing until the substitute/change commands comes naturally to you.

Learn

The point of temporarily disabling commands is not to say they’re bad, because they’re not. They are strictly necessary parts of Vim. The point is to also learn the more powerful and flexible commands. I have only covered the basics of normal mode, but read :help, :help user-manual, and this to uncover all the cool stuff you can do.

Comments