September 2016
Sometimes you want to repeat an Emacs function, even when calling it originally took a few keystrokes. Here's how to make it easily repeatable. Say we have a simple function that inserts "here":
(defun insert-here ()
(interactive)
(insert "here"))
And bind it to C-c h h
:
(global-set-key (kbd "C-c h h") #'insert-here)
This works; every time we type C-c h h
, we insert "here" into the buffer. But often we want to repeat the command. Although we could use C-x z
to repeat the last command, that's still two keypresses, and isn't the easiest thing to press once you've typed C-c h h
. So instead, we can make a sparse keymap and in it, set "h" to this command.
(setq insert-here-keymap
(let ((map (make-sparse-keymap)))
(define-key map (kbd "h") #'insert-here)
map))
Now we just need to use this keymap inside #'insert-here
. We can't use #'use-local-map
, because that will mean we can never insert h
again: we'd always call #'insert-here
. Instead, we can use #'set-transient-map
, which still uses the local keymap, but deactivates the keymap after a single key is pressed.
(defun insert-here ()
(interactive)
(insert "here")
(set-transient-map
insert-here-keymap))
Now, after activating #'insert-here
, we can repeat it by pressing h
. But if anything else is pressed, the keymap disables. Further presses of h
will insert the letter; the keymap is no longer used. So we've accomplished our goal of easily repeating this command with a single keypress.