在 Emacs 中用另一个 Emacs 执行表达式

我用的是开发版 Emacs,自己从 Git 仓库编译,版本号已经到了 27。开发新插件的时候,有时候想知道某些功能 Emacs 25 支不支持,本来我得专门切换到命令行,比如:

~ $ emacs-25.3.1 --batch --eval "(princ (fboundp 'read-multiple-choice))"
nil

这挺麻烦,借助 async.el 能很优雅地解决:

(eval-in-other-emacs "emacs" 'emacs-version)
     => "27.0.50"

(eval-in-other-emacs "emacs-25.3.1" 'emacs-version)
     => "25.3.1"

(eval-in-other-emacs "emacs" '(fboundp 'read-multiple-choice))
     => t

(eval-in-other-emacs "emacs-25.3.1" '(fboundp 'read-multiple-choice))
     => nil

其中 eval-in-other-emacs 是我自己定义的:

(require 'async)
(require 'pp)

(defun eval-in-other-emacs (emacs form)
  (interactive
   (list (read-shell-command "Emacs: ")
         (read--expression "Eval: ")))
  (let* ((fullpath (executable-find emacs))
         (invocation-directory (file-name-directory fullpath))
         (invocation-name (file-name-nondirectory fullpath))
         (result (async-get (async-start (lambda () (eval form))))))
    (when (called-interactively-p 'any)
      (pp-display-expression result "*Pp Eval Output*"))
    result))
3 个赞