【问题标题】:Automatic creation of repeatable command自动创建可重复的命令
【发布时间】:2014-02-19 13:25:14
【问题描述】:

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

在我的设置中,我将M-s-+ 绑定到text-scale-increaseM-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 的命令和名为 text-scale-increase-temporary-map 的覆盖键映射以及相应的键。

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

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

    试试这个:

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

    【讨论】:

    • 据我所知,这与链接解决方案的作用相同:它只能用于 前缀样式 击键 a la C-z + + + 和不能用于所需的M-s-+ + + 情况。
    • C-M-+ + -M-+ + -M-s-+ + - 一起使用,虽然后者同时按4 个键有点荒谬。
    • 如果我将C-z(您的代码)替换为M-s 并输入M-s-+,我会收到错误消息M-s-+ is undefined(在emacs -Q 中尝试过,只添加了(require 'cl))。跨度>
    • 你应该输入M-s-+,而不是M-s
    • 之前 alist 在 lambda 但不在 lexical-let 中,所以 lambda 没有看到它。它在我的 Emacs 实例中工作,因为我在调试期间将 alist 绑定为全局变量。总之:如果你想让 lambda 看到任何不是它的 arg 或全局的东西,请使用 lexical-let
    【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 2012-11-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-23
      • 2021-11-23
      • 2012-10-28
      • 2013-05-17
      • 2012-05-30
      相关资源
      最近更新 更多