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

余生颓废 提交于 2019-12-17 18:57:30

问题


Let's say I bind the key to a certain function as follows:

(global-set-key (kbd "C-c =") 'function-foo)

Now, I want the key binding to work as:
After I press C-c = for the first time, if I want to repeat the function-foo, I don't need to press C-c again, but simply repeat pressing =. Then, after I call the function-foo for enough times, I can just press keys other than = (or explicitly press C-g) to quit.

How to do this?


回答1:


This may be the thing you are looking for:

(defun function-foo ()
  (interactive)
  (do-your-thing)
  (set-temporary-overlay-map
    (let ((map (make-sparse-keymap)))
      (define-key map (kbd "=") 'function-foo)
      map)))



回答2:


There's a smartrep.el package that does exactly what you need. The documentation is a bit scarce but you can get a grip of how it's supposed to be used by looking into numerous emacs configs found on github. For example (taken from here):

(require 'smartrep)
(smartrep-define-key
    global-map "C-q" '(("n" . (scroll-other-window 1))
                       ("p" . (scroll-other-window -1))
                       ("N" . 'scroll-other-window)
                       ("P" . (scroll-other-window '-))
                       ("a" . (beginning-of-buffer-other-window 0))
                       ("e" . (end-of-buffer-other-window 0))))



回答3:


This is what I use. I like it because you don't have to specify the repeating key.

(require 'repeat)
(defun make-repeatable-command (cmd)
  "Returns a new command that is a repeatable version of CMD.
The new command is named CMD-repeat.  CMD should be a quoted
command.

This allows you to bind the command to a compound keystroke and
repeat it with just the final key.  For example:

  (global-set-key (kbd \"C-c a\") (make-repeatable-command 'foo))

will create a new command called foo-repeat.  Typing C-c a will
just invoke foo.  Typing C-c a a a will invoke foo three times,
and so on."
  (fset (intern (concat (symbol-name cmd) "-repeat"))
        `(lambda ,(help-function-arglist cmd) ;; arg list
           ,(format "A repeatable version of `%s'." (symbol-name cmd)) ;; doc string
           ,(interactive-form cmd) ;; interactive form
           ;; see also repeat-message-function
           (setq last-repeatable-command ',cmd)
           (repeat nil)))
  (intern (concat (symbol-name cmd) "-repeat")))



回答4:


You want your function-foo to use set-temporary-overlay-map.




回答5:


In addition to what @juanleon suggested, which uses set-temporary-overlay-map, here is an alternative that I use quite a bit. It uses standard library repeat.el.

;; 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)))

Use that to define different repeatable commands. E.g.,

(defun backward-char-repeat ()
  "Like `backward-char', but repeatable even on a prefix key."
  (interactive)
  (repeat-command 'backward-char))

Then bind such a command to a key with a repeatable suffix, e.g., C-c = (for C-c = = = =...)

See this SO post for more information.



来源:https://stackoverflow.com/questions/17201738/how-to-write-a-key-bindings-in-emacs-for-easy-repeat

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!