From b218c8b6b587d4f0629cbe81bf2dba95d07844d0 Mon Sep 17 00:00:00 2001 From: Lars Ingebrigtsen Date: Mon, 7 Dec 2020 15:40:23 +0100 Subject: [PATCH] Allow shutting down Emacs even if there are errors in kill-emacs-hook * lisp/subr.el (run-hook-query-error-with-timeout): New function (bug#28542). * src/emacs.c (Fkill_emacs): Use it to allow exiting Emacs even if there are errors in kill-emacs-hook. (syms_of_emacs): Define the symbol. --- etc/NEWS | 7 +++++++ lisp/subr.el | 18 ++++++++++++++++++ src/emacs.c | 4 +++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/etc/NEWS b/etc/NEWS index 34f7d30c845..49d66cc449e 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -1365,6 +1365,13 @@ This new command (bound to 'C-c C-l') regenerates the current hunk. ** Miscellaneous +--- +*** Errors in 'kill-emacs-hook' no longer prevents Emacs from shutting down. +If a function in that hook signals an error in an interactive Emacs, +the user will be prompted whether to continue or not. If the user +doesn't answer within five seconds, Emacs will continue shutting down +anyway. + --- *** iso-transl is now preloaded. This means that keystrokes like 'Alt-[' are defined by default, diff --git a/lisp/subr.el b/lisp/subr.el index 2236e934841..c28807f694b 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -5909,4 +5909,22 @@ returned list are in the same order as in TREE. (defconst regexp-unmatchable "\\`a\\`" "Standard regexp guaranteed not to match any string at all.") +(defun run-hook-query-error-with-timeout (hook) + "Run HOOK, catching errors, and querying the user about whether to continue. +If a function in HOOK signals an error, the user will be prompted +whether to continue or not. If the user doesn't respond, +evaluation will continue if the user doesn't respond within five +seconds." + (run-hook-wrapped + hook + (lambda (fun) + (condition-case err + (funcall fun) + (error + (unless (y-or-n-p-with-timeout (format "Error %s; continue?" err) + 5 t) + (error err)))) + ;; Continue running. + nil))) + ;;; subr.el ends here diff --git a/src/emacs.c b/src/emacs.c index d1b010ec7fe..fe09c446c38 100644 --- a/src/emacs.c +++ b/src/emacs.c @@ -2368,7 +2368,7 @@ all of which are called before Emacs is actually killed. */ if (noninteractive) safe_run_hooks (Qkill_emacs_hook); else - run_hook (Qkill_emacs_hook); + call1 (Qrun_hook_query_error_with_timeout, Qkill_emacs_hook); #ifdef HAVE_X_WINDOWS /* Transfer any clipboards we own to the clipboard manager. */ @@ -2890,6 +2890,8 @@ syms_of_emacs (void) DEFSYM (Qrisky_local_variable, "risky-local-variable"); DEFSYM (Qkill_emacs, "kill-emacs"); DEFSYM (Qkill_emacs_hook, "kill-emacs-hook"); + DEFSYM (Qrun_hook_query_error_with_timeout, + "run-hook-query-error-with-timeout"); #ifdef HAVE_UNEXEC defsubr (&Sdump_emacs); -- 2.39.5