2010-03-22 117 views
9

我有一个小模式。如果该模式处于活动状态并且用户点击了DEL,我想 需要执行一些操作,但只有在某些条件成立的情况下才会执行。如果 条件成立并且执行操作,那么在此之后我不想做任何其他更多 。但是,如果条件失败,我不想做任何事情 并让默认的DEL操作执行。Emacs键绑定回退

不知道我该如何解决这个问题。但我想我能做到这一点有两种方式:

1) 我可以重新绑定DEL键功能在小模式,然后 检查,如果条件成立OT没有。但是,我怎么知道DEL的默认命令是 ?

2) 我可以添加一个像这样的预命令钩子。执行命令然后打破链。但是,我如何打破这个链条?

(add-hook 'pre-command-hook 
      (lambda() 
      (when (equal last-input-event 'backspace) 
       ;; Do something and then stop (do not execute the 
       ;; command that backspace is bound to) 
      ))) 

你会以何种方式解决它?谢谢!

+0

del和backspace是否一样? – Amos 2010-03-22 16:53:14

回答

12

要做到这一点的方法是暂时禁用您的次要模式,然后查找键绑定。

假装已绑定'do-thingy删除。那么这会做的伎俩(假设要触发关闭条件是(equal last-input-event 'backspace)

(defun do-thingy() 
    "Do something, unless last event was backspace." 
    (interactive) 
    (if (equal last-input-event 'backspace) 
     (let* ((my-minor-mode nil) 
      (original-func (key-binding (kbd "DEL")))) 
     ;; original-func is whatever DEL would be if 
     ;; my-minor-mode were disabled 
     (call-interactively original-func)) 
    (message "Here's my minor mode behavior!"))) 

注:此行为假定您已经设置了key bindingsstandard way a minor-mode would具体地说,应该将你的键盘映射添加到变量minor-mode-map-alist。通过添加元素(my-minor-mode . my-minor-mode-keymap),这是上面的let声明是如何工作的,它查找你想要你的模式暂时禁用绑定。

如果使用define-minor-mode来定义你的未成年人模式下,键盘映射被建立“正道“自动。”

+0

完美,谢谢! – rejeep 2010-03-22 19:17:34

+2

如果你事先不知道关键是你想要回退到哪个关键位置,那么对于任意回退怎么样?如何以编程方式查找绑定以用于original-func的值? (从不介意:它看起来像使用这个命令键向量)。 – 2011-08-09 19:28:54

-3

似乎没有办法可靠地做你想做的事情。如果你的新命令绑定到DEL,那么在当前键盘映射中绑定到DEL之前的东西不再存在。您提出的另一种方法将不起作用,因为预命令挂钩不会阻止发生以下操作。你也许会想用^ G(Keyboard-Quit)中断进一步的执行,但这是一个不受控制的中断,可能会阻止比你想要的更多的事情。

即使您设置新绑定的过程比刚刚重新绑定更复杂一点,并且记住之前绑定的内容,所以您可以事后调用它,但您并没有真正拥有自己的外观对于。如果有人想重新绑定“默认”动作,他们必须通过修改您的功能来完成,而不是替换键绑定。

你想做什么并不符合Emacs的键绑定工作模式。

2

这就是我用于我的smart-tab包,正是这样做。

(defun smart-tab-default() 
    "Indents region if mark is active, or current line otherwise." 
    (interactive) 
    (if mark-active 
     (indent-region (region-beginning) 
        (region-end)) 

    (call-interactively 
    (or 
     ;; Minor mode maps for tab (without smart-tab-mode) 
     (cdar (assq-delete-all 'smart-tab-mode (minor-mode-key-binding "\t"))) 
     (cdar (assq-delete-all 'smart-tab-mode (minor-mode-key-binding [(tab)]))) 
     (local-key-binding "\t") 
     (local-key-binding [(tab)]) 
     (global-key-binding "\t") 
     (global-key-binding [(tab)]))))) 

,并在命令smart-tab(这是一个在小 模式绑定到选项卡),它具有以下:

(if (smart-tab-must-expand prefix) 
    ;; use smart tab 
    (smart-tab-default)) 

它首先检查是否有任何次要模式绑定标签(不包括 smart-tab-mode),然后是本地,最后是全局键绑定。