Problem: make a mapping that handles counts
Suppose that we wanted to create a mapping so that pressing
n.. We could start off with a simple mapping:
nnoremap Q n.
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
Solution 1: execute a macro using the expression register
Let’s revise our mapping to this:
nnoremap Q @='n.'<CR>
2Q is equivalent to
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
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.