Check out my new project: Peer to Peer - watch how experts solve tech problems.

Learn more

Check out my new project: Peer to Peer - watch how experts solve tech problems.

Creating repeatable mappings with repeat.vim

#61

Run time:

The dot command is my all-time favorite Vim trick: it tells Vim to repeat the last change. But the dot command tends not to work well with user-defined mappings. In this episode, we’ll use repeat.vim to set up a simple mapping so that it can be repeated using the dot command.

Shownotes

The README for repeat.vim begins:

If you’ve ever tried using the . command after a plugin map, you were likely disappointed to discover it only repeated the last native command inside that map, rather than the map as a whole. That disappointment ends today. Repeat.vim remaps . in a way that plugins can tap into it.

I’ve often felt this sense of disappointment when using Vim’s xp commands to transpose two characters. I’d like to be able to use the dot command to repeat xp, but it only repeats the p command, which is the last native command. Let’s create a custom cp mapping that transposes two characters in a way that can be repeated using the . command.

Constructing a repeatable mapping

Usually, Vim’s mappings follow this general format:

:map LHS RHS

This instructs Vim to execute the keys on the right-hand side (RHS) of the expression whenever the user presses the keys on the left-hand side (LHS). Alternatively, we can create a named mapping by using the <Plug> key on the LHS of the expression. Named mappings can’t be executed directly by the user, but they can be referenced by other mappings (see :help using-<Plug>). For example, this pair of mappings:

nmap <Plug>TransposeCharacters xp
nmap cp <Plug>TransposeCharacters

Has the same effect as this single mapping:

nmap cp xp

That is, when the user presses cp, Vim executes the x command followed by the p command. We can use the repeat#set() function (supplied by repeat.vim) to tell Vim to invoke our named mapping when the dot command is used. Here’s the complete mapping:

nnoremap <silent> <Plug>TransposeCharacters xp
\:call repeat#set("\<Plug>TransposeCharacters")<CR>
nmap cp <Plug>TransposeCharacters

Note that the line beginning with \ is a continuation of the previous line. When the user presses cp, Vim executes the <Plug>TransposeCharacters named mapping. That mapping executes the Normal commands x then p, then runs :call repeat#set("\<Plug>TransposeCharacters"), which instructs the dot command to execute the named mapping.

Further reading

Comments

Level-up your Vim

Training

Boost your productivity with a Vim training class. Join a public class, or book a private session for your team.

Drew hosted a private Vim session for the shopify team that was one of the best workshops I have ever attended.

John Duff, Director of Engineering at Shopify

Publications

Make yourself a faster and more efficient developer with the help of these publications, including Practical Vim (Pragmatic Bookshelf 2012), which has over 50 five-star reviews on Amazon.

After reading it, I've switched to vim as my default editor on a daily basis with no regrets. ★★★★★

Javier Collado

Learn to use Vim efficiently in your Ruby projects

In association with Thoughtbot, one of the most well respected Rails consultancies in the world, I've produced a series of screencasts on how to make navigating your Ruby projects with Vim ultra-efficient. Along the way, you’ll also learn how to make Ruby blocks a first-class text object in Vim. This lets you edit Ruby code at a higher level of abstraction. Available to buy from Thoughtbot..