注意:我将以下内容包装在此处restart-emacs
提供的包中。
这是使用纯elisp达到您想要的目的的另一种方法(因为您依赖于shell,所以并非如此)。诀窍是在杀死当前emacs之前产生另一个emacs进程。
(defun launch-separate-emacs-in-terminal ()
(suspend-emacs "fg ; emacs -nw"))
(defun launch-separate-emacs-under-x ()
(call-process "sh" nil nil nil "-c" "emacs &"))
(defun restart-emacs ()
(interactive)
;; We need the new emacs to be spawned after all kill-emacs-hooks
;; have been processed and there is nothing interesting left
(let ((kill-emacs-hook (append kill-emacs-hook (list (if (display-graphic-p)
#'launch-separate-emacs-under-x
#'launch-separate-emacs-in-terminal)))))
(save-buffers-kill-emacs)))
启动emacs的GUI版本的代码很简单。在终端中启动emacs的代码有些棘手。它使用以下事实:您可以传递一个字符串,suspend-emacs
该字符串将作为终端输入传递给父进程(shell)。从文档
(暂停-emacs和可选的填充)
停止Emacs并返回上级流程。您可以稍后再继续。如果cannot-suspend不为nil,或者系统不支持作业控制,则运行subshell。
如果可选的arg STUFFSTRING为非nil,则暂停后,其字符将被Emacs的父级填充为终端输入读取。
因此,我们基本上在将emacs杀死之前将其挂起,告诉父shell恢复当前已暂停的emacs(这将很快退出),然后启动另一个emacs进程。请注意,这在终端emacs可以/实际上不能挂起但启动子Shell的平台上不起作用,例如在Windows上。