10

If I run C-x C-c in emacs, it will close immediately. If I set confirm-kill-emacs to y-or-n-p it will ask for confirmation before closing.

Instead of y-or-n-p, I want to set some temporary timer for 3 seconds before closing emacs. So, if I press C-x C-c it should show something like

Emacs will be shutdown in 3 seconds. Press C-g to stop

If I don't do anything, it should shutdown emacs, but if I press C-g, it should prevent shutting down. How can I achieve this?

Glorfindel
  • 234
  • 1
  • 5
  • 13
Chillar Anand
  • 4,042
  • 1
  • 23
  • 52

2 Answers2

13

You can roll your own predicate function that waits for 3 seconds and invariably returns non-nil (unless it is interrupted with C-g):

(setq confirm-kill-emacs
      (lambda (&rest args)
        (interactive)
        (message "Quitting in 3 seconds. Press `C-g' to stop.")
        (sleep-for 3)
        t))

or a variant which will read any key:

(setq confirm-kill-emacs
      (lambda (&rest args)
        (interactive)
        (null (read-event "Quitting in 3 seconds. Hit any key to stop."
                          nil 3))))
François Févotte
  • 5,917
  • 1
  • 24
  • 37
7

You can use sit-for instead of using sleep-for plus t. And the function need not be a command (interactive).

sit-for returns t if it waited and nil if the user interrupted the wait.

(setq confirm-kill-emacs
      (lambda (&rest _)
        (message "Quit in 3 sec (`C-g' or other action cancels)")
        (sit-for 3)))
Drew
  • 75,699
  • 9
  • 109
  • 225