Use key as both prefix and command

后端 未结 2 711
时光说笑
时光说笑 2020-12-11 11:31

I\'d like to know how to use a key as both a prefix for other keys and a command itself.

  1. I can sorta do this with key-chord.el, by binding the

相关标签:
2条回答
  • 2020-12-11 12:02

    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.

    0 讨论(0)
  • 2020-12-11 12:05

    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.

    0 讨论(0)
提交回复
热议问题