emacs multi-keystroke binding [duplicate]

2019-07-04 04:39发布

问题:

This question already has an answer here:

  • How to write a key bindings in emacs for easy repeat? 5 answers

I'm still very new to EMACS, but are getting familiar when i'm going through the emacs and elisp manual. But right now i'm stuck on this:

Is there a simple way to bind input sequences in regexp style?

eg: the default binding for function enlarge-window-horizontally is "C-x {", is it possible to rebind it to something like "C-x ({)+" so that enlarge-window-horizontally can be called repeatedly by repeating "{" character, instead of release Ctrl key multiple times?

回答1:

There is another way to archive what you desire:

The first time you want to repeat the last command, press C-x z, afterwards you may repeat your command as often as desired by just pressing z.

The advantage of this approach is that it works with every command you use and not just for a specific one.

For additional reference here is the output of C-h f

8.11 Repeating a Command

Many simple commands, such as those invoked with a single key or with M-x COMMAND-NAME , can be repeated by invoking them with a numeric argument that serves as a repeat count (*note Arguments::). However, if the command you want to repeat prompts for input, or uses a numeric argument in another way, that method won't work.

The command C-x z (`repeat') provides another way to repeat an Emacs command many times. This command repeats the previous Emacs command, whatever that was. Repeating a command uses the same arguments that were used before; it does not read new arguments each time.

To repeat the command more than once, type additional z's: each z repeats the command one more time. Repetition ends when you type a character other than z, or press a mouse button.

For example, suppose you type C-u 2 0 C-d to delete 20 characters. You can repeat that command (including its argument) three additional times, to delete a total of 80 characters, by typing C-x z z z. The first C-x z repeats the command once, and each subsequent z repeats it once again.



回答2:

The "Emacs way" is to use C-u as a prefix key. E.g. C-u20C-x{.

Having said that, it's possible to do what you ask for. However, it would require you to bind C-x { and { separately. The former would be defined like it is today, but the latter would have to look something like:

(defun my-open-brace ()
  (interactive)
  (if (eq last-command 'shrink-window-horizontally)
      (progn
        (setq this-command 'shrink-window-horizontally)
        (call-interactively 'shrink-window-horizontally))
    (call-interactively 'self-insert-command)))

Unfortunately, if you have many sequences ending in {, you would have to write one function to handle them all.



回答3:

You can also define your own repeatable command and bind it to C-x {. You can then use it exactly as you requested: C-x { { { {..., instead of having to use C-x { C-x z z z z...

Here is what you do:

 (defun your-repeat-command (command)
   "Repeat COMMAND."
   (let ((repeat-message-function  'ignore))
     (setq last-repeatable-command  command)
     (repeat nil)))


 (defun your-shrink-window-horizontally ()
   "Shrink window horizontally.
 You can repeat this by hitting the last key again..."
   (interactive)
   (require 'repeat nil t)
   (my-repeat-command 'shrink-window-horizontally))


 (define-key ctl-x-map "{" 'your-shrink-window-horizontally)

You can do this with any command you like --- use my-repeat-command to make a repeatable version of it. I do this all the time, in several of my libraries.



回答4:

Write a multi repeat command for emacs by using minor mode. I name it smart-repeat-mode

https://github.com/zhsfei/emacs-ext



标签: emacs elisp