上下文:我想制作一个次要模式,按f
快速按(
会导致(
当时按下{}}}。这并不总是意味着只插入(
。例如,在启用了paredit模式或autopair模式的缓冲区中,按()
通常会导致插入a b
。在paredit模式缓冲区中,有时会导致包装所选文本:例如,如果我选择(
并按(a b)
,则应导致使用f
替换选择。
为了检测被按两次的(
,我只需要在http://www.emacswiki.org/emacs/electric-dot-and-dash.el
所以唯一缺少的部分是一个Lisp代码片段,告诉Emacs“现在触发(
!”
我想到的第一件事就是代码片段应该
(
但如果自动配对包(autopair或paredit或其他类似包)将(
绑定到具有查找用于调用命令的键的逻辑的命令,或者包简单地依赖于post-self-insert-hook或post-command-hook而不是绑定(require 'key-chord)
(key-chord-mode 1)
(defvar my-easy-open-paren-mode-map
(let ((map (make-sparse-keymap)))
(key-chord-define map ",." (kbd "("))
map))
(define-minor-mode my-easy-open-paren-mode
"In this mode, pressing . and , together is another way of pressing the open paren.")
(defvar my-easy-semicolon-mode-map
(let ((map (make-sparse-keymap)))
(key-chord-define map ";;" (kbd "C-e ;"))
map))
(define-minor-mode my-easy-semicolon-mode
"In this mode, pressing semicolon twice fast is another way of pressing C-e and semicolon.")
(add-hook 'prog-mode-hook 'my-easy-open-paren-mode)
(add-hook 'c-mode-common-hook 'my-easy-semicolon-mode)
。
更新
我查阅了Key Chord文档,结果发现我正在尝试解决这个问题的答案有一个更简单的解决方案:
{{1}}
触发按键可能在其他情况下仍然有用。
答案 0 :(得分:5)
您可能会感谢Key Chord库将绑定功能绑定到双键按下。 (我不建议使用f
,如果你要用英语写作,请注意;但是YMMV。)
post-self-insert-hook
, self-insert-command
仍会运行。 post-command-hook
会在任何情况下运行,但如果你担心它会看到错误的功能和/或输入事件,你可以操纵它们......
查找绑定后,您的函数可以将this-command
设置为您要约call-interactively
的函数,并将last-command-event
设置为所需的键。 e.g:
(defun my-fake-paren ()
(interactive)
(let ((command (key-binding "(")))
(setq last-command-event ?\()
(setq this-command command)
(call-interactively command)))
答案 1 :(得分:1)
我使用Key Chord来做这类事情,虽然您链接的页面似乎也做同样的事情。诀窍是让call-interactively
的调用正常工作。我把它包装成一个重置变量last-command-event
的let,这样call-interactively
认为它是一个“(”。这对我来说在paredit和基本模式下都适用。
(require 'key-chord)
(key-chord-mode 1)
(defun my-paren-call ()
(interactive)
(let ((last-command-event ?\())
(call-interactively (key-binding "("))))
(key-chord-define-global "ff" 'my-paren-call)