为什么键绑定会导致 Emacs 在启动时执行我的功能?
Why does key binding cause Emacs to execute my function on startup?
我的 Emacs init.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
调用它。如果我给它分配一个键绑定,它会在启动时执行,并产生两种不同的副作用之一:对于一些键绑定,它会在 Emacs 仍然打开它时尝试覆盖 init.elc
,而对于其他键绑定,它会成功覆盖 init.elc
,但随后在重新加载时重新执行,导致无限递归。
我非常乐意坚持使用 lambda
版本,它在键绑定方面没有问题,但我想了解 lambda
正在执行什么魔法 and/or 什么它是关于导致第二个版本在启动时执行的键绑定。谁能解释一下?
无论如何,我的键绑定都处于自定义次要模式,如下所示:
(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
.[=13 返回的函数的绑定=]
您可以通过引用简单地给出与绑定关联的函数的名称:
(define-key custom-map (kbd "C-c C-i") 'tangle-init-and-reload)
我的 Emacs init.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
调用它。如果我给它分配一个键绑定,它会在启动时执行,并产生两种不同的副作用之一:对于一些键绑定,它会在 Emacs 仍然打开它时尝试覆盖 init.elc
,而对于其他键绑定,它会成功覆盖 init.elc
,但随后在重新加载时重新执行,导致无限递归。
我非常乐意坚持使用 lambda
版本,它在键绑定方面没有问题,但我想了解 lambda
正在执行什么魔法 and/or 什么它是关于导致第二个版本在启动时执行的键绑定。谁能解释一下?
无论如何,我的键绑定都处于自定义次要模式,如下所示:
(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
.[=13 返回的函数的绑定=]
您可以通过引用简单地给出与绑定关联的函数的名称:
(define-key custom-map (kbd "C-c C-i") 'tangle-init-and-reload)