13

假设我将键绑定到某个函数,如下所示:

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

现在,我希望键绑定的工作方式为:第一次
按下后C-c =,如果我想重复功能-foo,我不需要C-c再次按下,只需重复按下=。然后,在我调用函数 foo 足够多次之后,我可以只按=(或明确按C-g)以外的键退出。

这个怎么做?

4

5 回答 5

15

这可能是您正在寻找的东西:

(defun function-foo ()
  (interactive)
  (do-your-thing)
  (set-temporary-overlay-map
    (let ((map (make-sparse-keymap)))
      (define-key map (kbd "=") 'function-foo)
      map)))
于 2013-06-20T07:09:27.940 回答
8

有一个smartrep.el包可以满足您的需要。文档有点稀缺,但您可以通过查看 github 上的大量 emacs 配置来了解它应该如何使用。例如(取自这里):

(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))))
于 2013-06-20T09:07:23.593 回答
6

这就是我使用的。我喜欢它,因为您不必指定重复键。

(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")))
于 2013-06-26T02:47:55.163 回答
2

你希望你function-foo使用set-temporary-overlay-map.

于 2013-06-20T01:08:32.457 回答
1

除了@juanleon 建议的使用set-temporary-overlay-map,这里还有一个我经常使用的替代方案。它使用标准库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)))

使用它来定义不同的可重复命令。例如,

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

然后将这样的命令绑定到具有可重复后缀的键上,例如C-c =(for C-c = = = =...)

有关更多信息,请参阅此 SO 帖子

于 2014-01-25T16:58:18.327 回答