Literate Vim

This post originally published on thoughtbot's Giant Robots blog.

Vim normal mode commands are made up of verbs, adverbs, and nouns. Many of them are mnemonic such as visual, change, yank and delete. Others like ` are less obviously “go to” in context of a mark.

Some Vim plugins add additional commands. In this example, we rely on functionality from vim-unimpaired and vim-surround which add the [ and ya]/vi> functionality, respectively.

Let’s break down a relatively verbose Vim normal model command:

"wya]}[ "wpa: <https://example.com><Esc>vi>
  1. "w Apply the next command to a register named “w”. “w” happened to be an unused register in my Vim setup.
  2. ya] Yank the text around the brackets.
  3. } Move the cursor to the first line after the current paragraph.
  4. [ Insert a blank line above the cursor, but don’t move the cursor and stay in normal mode. The space is “" in :help files.
  5. "w Again, do something with the “w” register.
  6. p Paste its contents.
  7. a Open insert mode to append after the character under the cursor.
  8. : <https://example.com> Insert that literal text.
  9. <Esc> Press escape, bringing us back to normal mode from insert mode.
  10. vi> Visually select inside angle brackets.

So what does this do?

With your cursor inside [brackets] as on this line

Insert the text [brackets]: <https://example.com> after the paragraph, leaving a blank line above. Visually select the link text and leave it to me to make changes if desired.

See it in action

This is great when authoring a post in Markdown when you’d like to add a link to some text. I have it mapped to <Leader>e in Markdown files with:

autocmd filetype markdown nnoremap <Leader>e :normal "wya]}[ "wpa: <https://example.com><Esc>vi>

Combine it with ysa2w] for even more fun. What does it do?

Unfortunately, it doesn’t play nicely if the current paragraph is followed by an EOF, as the } motion moves to the end of the paragraph and does not create a new line. Can you fix this? (hover for the answer.) You might need to open up the :help files and jump around a bit until you have about 2 more commands under your belt.