自动创建可重复的命令

时间:2014-02-19 13:25:14

标签: emacs elisp

关于可重复的emacs命令的主题已经some questions(即C-x z [repeat-command]的行为,其中每个后续z重复上一个命令),但是,自动解决方案都不能处理非前缀键绑定(我的术语:C-c p是前缀keybinding,前缀为{{ 1}},另一方面,键击C-c是非前缀键绑定。)

在我的设置中,我将M-s-+绑定到M-s-+,将text-scale-increase绑定到M-s--。在初始命令之后,只需按text-scale-decrease+进行重复缩放即可。这可以通过以下elisp实现:

-

但是,每次我想要创建可重复的键绑定时重复此代码都是麻烦且不必要的。我想要一种自动完成任务的方法。想象这段代码

(defvar text-scale-temp-keymap (make-sparse-keymap))
(define-key text-scale-temp-keymap (kbd "+") 'text-scale-increase)
(define-key text-scale-temp-keymap (kbd "-") 'text-scale-decrease)

(defun text-scale-increase-rep (inc)
  (interactive "p")
  (text-scale-increase inc)
  (set-temporary-overlay-map text-scale-temp-keymap t))

(defun text-scale-decrease-rep (inc)
  (interactive "p")
  (text-scale-decrease inc)
  (set-temporary-overlay-map text-scale-temp-keymap t))

(global-set-key (kbd "M-s-+") 'text-scale-increase-rep)
(global-set-key (kbd "M-s--") 'text-scale-decrease-rep)

将使用相应的键创建名为(make-repeatable-command 'text-scale-increase '(("+" . text-scale-increase) ("-" . text-scale-decrease))) 的命令和名为text-scale-increase-rep的覆盖键映射。

我认为这是可能的,但是如何?

2 个答案:

答案 0 :(得分:2)

试试这个:

(defun defrepeatable (alist)
  (lexical-let ((keymap (make-sparse-keymap))
                (func (cdar alist)))
    (mapcar (lambda(x) (define-key keymap (car x) (cdr x))) alist)
    (lambda (arg)
      (interactive "p")
      (funcall func arg)
      (set-temporary-overlay-map keymap t))))

(global-set-key (kbd "C-z")
                (defrepeatable
                    '(("+" . text-scale-increase) 
                      ("-" . text-scale-decrease)))) 

答案 1 :(得分:2)

替代方案 -

如果你想做的只是(a)定义一个可重复的命令和(b)将它绑定到一个(可重复的)键,你不需要所有这些。

我在您链接到的网页(12)中提供的解决方案也适用于此处。该解决方案的重点是 限制与前缀密钥一起使用,但您可以 用它来重复前缀键上的一个键。

以下是适用于您的示例的相同解决方案。您只需要定义repeat-command一次 - 您可以使用它来定义任意数量的可重复命令。

(defun repeat-command (command)
  "Repeat COMMAND."
 (interactive)
 (let ((repeat-previous-repeated-command  command)
       (last-repeatable-command           'repeat))
   (repeat nil)))

(defun text-scale-increase-rep (inc)
  (interactive "p")
  (repeat-command 'text-scale-increase))

(defun text-scale-decrease-rep (inc)
  (interactive "p")
  (repeat-command 'text-scale-decrease))

(global-set-key (kbd "M-s-+") 'text-scale-increase-rep)
(global-set-key (kbd "M-s--") 'text-scale-decrease-rep)