Problem: make a mapping that handles counts
Suppose that we wanted to create a mapping so that pressing Q
executed n.
. We could start off with a simple mapping:
nnoremap Q n.
Pressing Q
now executes n.
, giving us two keystrokes for the price of one. Nice! But if we try prefixing our new mapping with a count, something odd happens. For example, pressing 2Q
behaves as though we had pressed 2n.
. It would be more useful if 2Q
was equivalent to n.n.
.
Solution 1: execute a macro using the expression register
Let’s revise our mapping to this:
nnoremap Q @='n.'<CR>
Now, pressing 2Q
is equivalent to n.n.
, 3Q
is equivalent to n.n.n.
, and so on.
So how does it work? The @
key tells Vim to execute a macro. Rather than using a named register we use the expression register, which lets us specify the contents in place. The characters inside of the quotes are interpreted as keystrokes, and the carriage return enters the string into the expression register.
You can find a short section about this technique in Vim’s documentation by looking up :help map-examples
.
There’s also an article on the VimWiki explaining it.
For more on the expression register, check out episodes 56 and 57.
Solution 2: use the :normal Ex command
This mapping also properly handles a count:
nnoremap Q :normal n.<CR>
This uses the :normal
Ex command. I would prefer to see this mapping in a vimrc than the previous example. To my eye it looks less cryptic.