I\'d like to know how to use a key as both a prefix for other keys and a command itself.
I can sorta do this with key-chord.el
, by binding the
If I understand what you want, I'd suggest that it is better to forget about timers and waiting a slight delay (i.e., to distinguish the intention of <menu>
as a command from its use as a prefix key).
The approach I recommend, and use quite a bit, is to define a prefix key (in your case, e.g., <menu>
), and then put the command that you were thinking of using for <menu>
on <menu> <menu>
. That's as quick as hitting <menu>
once and trying to rely on some tiny delay etc.
And it allows the command you think of as being on <menu>
(really it is on <menu> <menu>
) to be repeatable.
I typically make such a command repeatable, so that <menu> <menu> <menu>
repeats the command once, <menu> <menu> <menu> <menu>
repeats it twice, and so on. IOW, I tend to use this trick for commands that I really want to repeat easily, by just holding down a key.
Here's a simple example, from a suggestion I made more generally to emacs-devel@gnu.org
back in 2009, HERE. In that mailing-list message, if you scroll down to #9 you will see the proposal to use such keys, #12 shows this same example, and #15 addresses your question directly. The thread title is "have cake will eat,eat cake will have - krazy key koncept kontroversy", and its subject is exactly the question you raised.
;; This function builds a repeatable version of its argument COMMAND.
(defun repeat-command (command)
"Repeat COMMAND."
(interactive)
(let ((repeat-previous-repeated-command command)
(last-repeatable-command 'repeat))
(repeat nil)))
Here is how you could then define `C-x', which is already a prefix
key, as also a repeatable key for an action command, in this case,
`backward-char':
(defun backward-char-repeat ()
"Like `backward-char', but repeatable even on a prefix key."
(interactive)
(repeat-command 'backward-char))
(define-key ctl-x-map "\C-x" 'backward-char-repeat)
Now just holding down `C-x' invokes `backward-char' repeatedly - once
you've gotten past the first `C-x' (the prefix).
As I say, I've long used this technique to be able to (a) have "repeating prefix keys" and (b) still have other keys defined on them.
It seems that you want something like smartrep which enables specifying a key as a common prefix for several commands. The only thing you'll be missing out-of-the-box is binding a command to the common prefix key, so you'll need to get your hands dirty with smartrep
internals a bit. The function you're after is
(smartrep-read-event-loop
'((KEY1 command)
(KEY2 command)
...))
Here's a piece of code that may get you started:
(defun my-command-with-prefix ()
(interactive)
(invoke-prefix-command)
(initialize-event-loop)
;; The form
;;
;; (condition-case ERR FORM (quit QUIT-HANDLER))
;;
;; is there to catch C-g key presses and make sure that
;; finalization code is run.
(condition-case e
(smartrep-read-event-loop
'(("a" . command1)
("b" . command2)
("c" . command3)))
(quit nil))
;; finalize loop
(finalize-event-loop))
The snippet above is essentially a distilled version of code found here.