problem
Lately I run GNU Emacs mostly as GUI on X/tty7 (which I'll call "the desktop" as opposed to emacs-desktop) on one of my Debian laptops. Occasionally the desktop hangs, in which case I usually can goto tty1 and sudo shutdown -[whatever] now
. Unfortunately this does not cause Emacs to shut down as cleanly as I'd like: I'd like Emacs to (e.g.) save any unsaved buffers and desktop-save
, but that doesn't seem to get done.
So I'm thinking that, in this usecase, I should utter something from tty1 (before shutdown
) to tell Emacs to shutdown cleanly ... but I don't know what to say. How to do this?
solution
thanks
TIA and for past help to the many fine folks @ help-gnu-emacs, esp Yuri Khan for the initial suggestion and Jorge A. Alfaro-Murillo for the more important details of this solution. Special thanks to Faried Nawaz for 2 important advances that pretty-much solve the problem.
server and client
One way that WFM (not entirely without problems--see notes
below) is
- Preparation:
1.1. Whenever you start Emacs, make it start a server instance. I did this by adding the following line to my ~/.emacs.d/init.el
:
(server-start)
1.2. Also in ~/.emacs.d/init.el
, define a callable function to tell emacs to shutdown cleanly, with as few prompts as possible. Faried Nawaz recommended
(defun my-kill-emacs ()
"Set kill-emacs-query-functions , confirm-kill-emacs , and
kill-emacs-hook to nil to quit emacs without any pesky prompts
(except to save buffers)"
(let (kill-emacs-query-functions confirm-kill-emacs kill-emacs-hook)
(save-buffers-kill-emacs)))
1.3. Restart your emacs to be sure to incorporate your new init.el
code.
- When you encounter tty7/desktop hang: Goto tty1, and login if not already. Then do either of the following:
2.1. manually: from bash commandline, run
emacsclient -c -a '' -e '(my-kill-emacs)'
2.2. scripted: save the above line into an executable file à la ~/bin/shutdown_Emacs_cleanly.sh
and run it. E.g.:
#!/bin/sh
emacsclient -c -a '' -e '(my-kill-emacs)'
notes
If your (graphical) Emacs has no unsaved buffers when you kill it (as described above), Emacs will exit with no prompts. If your Emacs has unsaved buffers when you kill it, you will get prompts (from your character-mode Emacs in tty1) to save the buffers. (Writing a function that saves all unsaved buffers without any prompts is left as an exercise for the reader :-)
Whether or not you have unsaved buffers, when your tty1 commandline exits, its terminal handling may be "polluted": e.g. (and in roughly decreasing order of importance),
You will no longer see what you type at the bash prompt.
History browsing (via up/down-arrow key) also fails--at least, I cannot see anything on the commandline.
Hitting RET at the bash prompt no longer does a line feed, though it still produces a new prompt. This results in a display like
me@it:~$ me@it:~$ me@it:~$ me@it:~$ me@it:~$ me@it:~$ me@it:~$ me@it:~$ me@it:~$
My tty1 is always polluted by running the above; YMMV. Fortunately, as Nawaz points out, one can unpollute by calling
reset
from the tty1 commandline (after installing package=ncurses-bin
).