如何在Emacs Lisp中模拟特定的按键

时间:2013-09-19 21:40:51

标签: emacs elisp key-bindings

上下文:我想制作一个次要模式,按f快速按(会导致(当时按下{}}}。这并不总是意味着只插入(。例如,在启用了paredit模式或autopair模式的缓冲区中,按()通常会导致插入a b。在paredit模式缓冲区中,有时会导致包装所选文本:例如,如果我选择(并按(a b),则应导致使用f替换选择。

为了检测被按两次的(,我只需要在http://www.emacswiki.org/emacs/electric-dot-and-dash.el

中的短代码中取逻辑

所以唯一缺少的部分是一个Lisp代码片段,告诉Emacs“现在触发(!”

我想到的第一件事就是代码片段应该

  1. 找到绑定到密钥(
  2. 的命令
  3. 然后在该命令上以交互方式调用call。
  4. 但如果自动配对包(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}}

    触发按键可能在其他情况下仍然有用。

2 个答案:

答案 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)