为什么键绑定会导致 Emacs 在启动时执行我的函数?



我的Emacsinit.el文件中有一个函数,可以让我从一个有文字的源文件重建和字节编译它。它由一个由defun包装的lambda函数组成,并且完全按照我的预期工作。目前为止,一切都好。

(defun tangle-init-and-reload ()
"Tangle the code blocks in init.org, byte-compile, and reload."
(lambda ()
(interactive)
;; Don't run hooks when tangling.
(let ((prog-mode-hook nil))
(org-babel-tangle-file (concat user-emacs-directory "init.org"))
(byte-compile-file (concat user-emacs-directory "init.el"))
(load-file user-init-file))))

当我在 Elisp 中阅读函数时,在我看来,我应该能够简单地使用defun来定义一个命名函数并跳过lambda,所以我删除了lambda,否则保持函数不变,如下所示:

(defun tangle-init-and-reload ()
"Tangle the code blocks in init.org, byte-compile, and reload."
(interactive)
;; Don't run hooks when tangling.
(let ((prog-mode-hook nil))
(org-babel-tangle-file (concat user-emacs-directory "init.org"))
(byte-compile-file (concat user-emacs-directory "init.el"))
(load-file user-init-file)))

以这种方式编写,该函数也可以按预期工作 - 只要我用M-x tangle-init-and-reload RET调用它。如果我给它分配一个键绑定,它会在启动时执行,并带有以下两种不同的副作用之一:对于某些键绑定,它会尝试覆盖init.elc而 Emacs 仍然打开它,而对于其他键绑定,它成功地覆盖了init.elc,但随后在重新加载时重新执行,导致无限递归。

我非常乐意坚持使用lambda版本,它对键绑定没有问题,但我想了解lambda正在执行什么魔术和/或导致第二个版本在启动时执行的键绑定是什么。谁能解释一下?

无论它的价值如何,我的键绑定都处于自定义次要模式,如下所示:

(defvar custom-map (make-keymap)
"Custom key bindings.")
(define-key custom-map (kbd "C-c C-i") (tangle-init-and-reload))
(define-minor-mode custom-bindings-mode
"Activates custom key bindings."
t nil custom-map)

定义键绑定时,将键关联到值,在本例中为:

(tangle-init-and-reload)

这是一个正常计算的表达式,即在关联绑定时调用该函数。

在以前的版本中,计算相同的函数返回一个闭包,您有一个间接级别,因此您建立了从键到调用tangle-init-and-reload返回的函数的绑定。

只需通过引用来提供与绑定关联的函数的名称:

(define-key custom-map (kbd "C-c C-i") 'tangle-init-and-reload)

最新更新