30

Is there a way to prevent Emacs from exiting once I initiate the exit process?

I occasionally fat finger C-xC-s as C-xC-c. It isn't an awful process to get back up and running but I am curious if there is a way I can stop the exit process so that I can continue uninterrupted with all my files open.

Using GNU Emacs 24.3.1. Running on Cygwin under Window 7.

Drew
  • 29,895
  • 7
  • 74
  • 104
N Klosterman
  • 1,231
  • 14
  • 23

5 Answers5

43

There is a built-in variable you can set to a function like so:

(setq confirm-kill-emacs 'y-or-n-p)
scottfrazer
  • 17,079
  • 4
  • 51
  • 49
  • By default, Emacs uses `'yes-or-no-p` when you try to exit Emacs and there are unsaved buffers. For consistency, if you'd like the prompt when closing Emacs to be the same as this default, use `(setq confirm-kill-emacs 'yes-or-n-p)` instead. – WalterGR Jun 25 '18 at 15:52
  • You can set this with customize – Anthony Williams Sep 14 '18 at 17:28
  • @WalterGR wouldn't `(setq confirm-kill-emacs 'yes-or-no-p)` be more consistent, rather than `(setq confirm-kill-emacs 'yes-or-n-p)`? – mark Jan 14 '19 at 21:53
3

scottfrazer's answer's the more appropriate, to me, than what follows.

Enable Emacs Lock minor mode (emacs-lock-mode) on any of the buffers, to prevent Emacs from exiting in case you accidentally hit C-xC-c.

From the Emacs Wiki page:

Emacs cannot exit until the buffer is killed or unlocked

Add (emacs-lock-mode) to your .emacs/init.el file so that this lock is enabled in every Emacs session. Adding this will lock the *scratch* buffer which will have to be unlocked in case you really want to exit Emacs.

Another way/hack of doing this is to start a process in Emacs e.g. M-xshell or have an unsaved file associated to a buffer, doing this will prompt you for confirmations when Emacs is exiting.

Yes one more, unset C-xC-c using global-unset-key. And then if you want to exit Emacs M-xkill-emacs.

Bleeding Fingers
  • 6,993
  • 7
  • 46
  • 74
2
  • Using confirm-kill-emacs, as @scottfrazer suggested, is one approach.

  • More generally, you can use kill-emacs-query-functions to do whatever you want in this regard. (There was no real need for them to add confirm-kill-emacs, but they did.)

  • You probably do not want to use kill-emacs-hook in this regard (that's what kill-emacs-query-functions is for), but be aware of it, in case you come across it using apropos etc.

One advantage of kill-emacs-query-functions over justconfirm-kill-emacs is that you can require a better confirmation: yes instead of just hitting key y. For example:

(add-hook 'kill-emacs-query-functions
          (lambda () (y-or-n-p "Do you really want to exit Emacs? "))
          'append)

That is what I do. It is too easy to be hitting keys and accidentally hit C-x C-c y, especially since I have similar keys bound (e.g., C-x c, C-x C-x, C-x C-y).

Drew
  • 29,895
  • 7
  • 74
  • 104
2

I've added the following to my emacs configuration to prevent accidental closes. I didn't like having to confirm close emacs for something like a one off commit, but I hate losing my emacs session accidentally while deep in a problem.

This adds a global state flag to emacs describing whether or not it's locked. This flag is set either automatically after emacs is open for 5 minutes, or manually using the lock-emacs command. The lock can later be removed manually by using the unlock-emacs command.

If emacs is locked, and you attempt to close it (presumably accidentally), emacs will instead give you a message saying that emacs has been locked, and cannot be closed. If it's unlocked, close behaves exactly as it does by default.

;; don't close emacs on accident
(setq emacs-locked nil)
(setq confirm-kill-emacs
      (lambda (&rest args)
        (if emacs-locked
            (progn
              (message "%s" "Emacs is locked, and cannot be closed.")
              nil)
            t)
         ))
(defun lock-emacs-silently ()
  (progn
    (setq emacs-locked t))
  )

(defun lock-emacs ()
  "Prevent emacs from being closed."
  (interactive)
  (progn
    (lock-emacs-silently)
    (message "%s" "Emacs is now locked."))
  )
(defun unlock-emacs ()
  "Allow emacs to be closed."
  (interactive)
  (progn
    (setq emacs-locked 'nil)
    (message "%s" "Emacs can now be closed."))
  )
(run-at-time "5 minutes" nil 'lock-emacs-silently)

(Open to suggestions on how to make the confirm-kill-emacs portion nicer, I'm a lisp novice :) ).


After using this for a couple of years, I ended up going to something much simpler:

;; Unbind the normal close
(global-unset-key (kbd "C-x C-c"))
;; Require C-c 3 times before closing
(global-set-key (kbd "C-x C-c C-c C-c") 'save-buffers-kill-terminal)
1

If you're looking for a shorter answer, I've had this line at the bottom of all my .emacs files since the last century:

(shell)
Eric
  • 2,115
  • 2
  • 20
  • 29
  • Can you explain what adding (shell) does? I'm searching through the emacs wiki and just searching "shell" is a bit ambiguous to find out what this does. – N Klosterman Jan 17 '14 at 17:59
  • I have mentioned it in my answer. `(shell)` actually starts a process which Emacs will prompt you for being active and if you really want to exit. [Shell Mode](http://www.emacswiki.org/emacs/ShellMode). – Bleeding Fingers Jan 17 '14 at 20:15