I restart my emacs a lot. All I want to do is create a function that kills the current emacs, only to spawn a new one in it's stead. Ideally, this would also work in a TTY.
Note: I have wrapped the following in a package
restart-emacs available here.
Here is an alternate way to achieve what you want using pure elisp (not really since you rely on a shell). The trick is to spawn off another emacs process just before current emacs is killed.
(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)))
The code to start a GUI version of emacs is straightforward. The code to start emacs in a terminal is a bit tricky. It uses the fact that you can pass a string to
suspend-emacs which would be passed as terminal input to the parent process (the shell). From the documentation
(suspend-emacs &optional STUFFSTRING)
Stop Emacs and return to superior process. You can resume later. If `cannot-suspend' is non-nil, or if the system doesn't support job control, run a subshell instead.
If optional arg STUFFSTRING is non-nil, its characters are stuffed to be read as terminal input by Emacs's parent, after suspension.
So we basically suspend emacs just before it is killed tell the parent shell to resume currently suspended emacs (which is going to exit soon) and then launch another emacs process. Note that this does not work on platforms on which terminal emacs can/does not actually suspend but starts a subshell, for example on windows.
As far as I know you cannot tell Emacs to re-start after terminating, but you can set the exit code so that the process that started Emacs in the first place can detect that you want to re-start.
For example, this shell script re-starts Emacs if it exited with the code 123.
#!/bin/sh while emacs -nw "$@"; [ $? = 123 ]; do :; done
Next, we define
kill-emacs-and-restart that makes Emacs terminate with the exit code equal to the magic number recognized by the script:
(defun kill-emacs-and-restart () (interactive) (kill-emacs 123))
Now if you run Emacs via this script you can re-start by
M-x kill-emacs-and-restart (or bind it to a key sequence).
Assuming I've got the syntax right for embedding " in a string, this should do it.
(defun restart-emacs () (call-process "sh" nil nil nil "-c" "gdb -p $(ps h -o ppid -p $$) -ex 'call execl(\"/bin/sh\", \"/bin/sh\", \"-c\", \"exec emacs\")'"))
As of emacs version
29.1 emacs now has the
restart-emacs command built in.
** New command 'restart-emacs'.
This is like 'save-buffers-kill-emacs', but instead of just killing the current Emacs process at the end, it starts a new Emacs process (using the same command line arguments as the running Emacs process). 'kill-emacs' and 'save-buffers-kill-emacs' have also gained new optional arguments to restart instead of just killing the current process.
From the release notes