我有一个小模式。如果该模式处于活动状态且用户点击DEL,我 想做一些动作,但只有在某些条件成立的情况下。如果 条件成立并执行操作我想不再做任何事情 之后。但如果条件失败,我不想做任何事情 并让默认的DEL动作执行。
不知道我怎么解决这个问题。但我想我可以用两种方式做到这一点:
1) 我可以在次模式下将DEL键重新绑定到一个函数然后 检查条件是否成立。但那我怎么知道什么 DEL的默认命令是?
2) 我可以像这样添加一个pre命令钩子。然后执行命令 打破链条。但是我该如何打破链条?
(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 :(得分:12)
执行此操作的方法是暂时禁用次要模式,然后查找键绑定。
假装您已将'do-thingy
绑定到 DEL 。然后这就行了(假设你要触发的条件是(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 bindings standard way a minor-mode would。具体来说,您应该通过添加元素(my-minor-mode . my-minor-mode-keymap)
将键映射添加到变量minor-mode-map-alist
。这就是上述let
语句的工作原理,它会在暂时禁用您的模式时查找所需的绑定。
如果您使用define-minor-mode
来定义次要模式,则会自动将“键盘映射”设置为“正确方式”。
答案 1 :(得分: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
),然后是本地,最后是全局键绑定。
答案 2 :(得分:-3)
似乎没有办法可靠地做你想做的事。如果您的新命令绑定到DEL,那么在当前键映射之前绑定到DEL的任何内容都不再存在。您提出的另一种方法不起作用,因为预命令挂钩不会阻止发生以下操作。您可能还会考虑使用^ G(键盘退出)中断进一步的执行,但这是一个不受控制的中断,可能会停止比您想要的更多的事情。
即使您设置新绑定的过程比仅重新绑定更复杂,并记住之前绑定的内容,所以您可以在之后调用它,您实际上没有找到您想要的内容。如果有人想要重新绑定“默认”操作,他们必须通过修改您的功能而不是替换键绑定来执行此操作。
您想要做的事情不符合Emacs关键绑定工作原理的模型。