From d780864fd38768801c88778ee694a1a535e41810 Mon Sep 17 00:00:00 2001 From: Stefan Kangas Date: Tue, 18 Aug 2020 19:29:19 +0200 Subject: [PATCH] Fix exiting Emacs when savehist-file not writable * lisp/savehist.el (savehist-save): Show warning when 'savehist-file' is not writable. (Bug#34093) (savehist--has-given-file-warning): New variable. --- lisp/savehist.el | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/lisp/savehist.el b/lisp/savehist.el index 4e52efe7f1..5a64b9327a 100644 --- a/lisp/savehist.el +++ b/lisp/savehist.el @@ -215,6 +215,7 @@ savehist-uninstall (cancel-timer savehist-timer) (setq savehist-timer nil))) +(defvar savehist--has-given-file-warning nil) (defun savehist-save (&optional auto-save) "Save the values of minibuffer history variables. Unbound symbols referenced in `savehist-additional-variables' are ignored. @@ -288,23 +289,29 @@ savehist-save ;; If autosaving, avoid writing if nothing has changed since the ;; last write. (let ((checksum (md5 (current-buffer) nil nil savehist-coding-system))) - (unless (and auto-save (equal checksum savehist-last-checksum)) - ;; Set file-precious-flag when saving the buffer because we - ;; don't want a half-finished write ruining the entire - ;; history. Remember that this is run from a timer and from - ;; kill-emacs-hook, and also that multiple Emacs instances - ;; could write to this file at once. - (let ((file-precious-flag t) - (coding-system-for-write savehist-coding-system) - (dir (file-name-directory savehist-file))) - ;; Ensure that the directory exists before saving. - (unless (file-exists-p dir) - (make-directory dir t)) - (write-region (point-min) (point-max) savehist-file nil - (unless (called-interactively-p 'interactive) 'quiet))) - (when savehist-file-modes - (set-file-modes savehist-file savehist-file-modes)) - (setq savehist-last-checksum checksum))))) + (condition-case err + (unless (and auto-save (equal checksum savehist-last-checksum)) + ;; Set file-precious-flag when saving the buffer because we + ;; don't want a half-finished write ruining the entire + ;; history. Remember that this is run from a timer and from + ;; kill-emacs-hook, and also that multiple Emacs instances + ;; could write to this file at once. + (let ((file-precious-flag t) + (coding-system-for-write savehist-coding-system) + (dir (file-name-directory savehist-file))) + ;; Ensure that the directory exists before saving. + (unless (file-exists-p dir) + (make-directory dir t)) + (write-region (point-min) (point-max) savehist-file nil + (unless (called-interactively-p 'interactive) 'quiet))) + (when savehist-file-modes + (set-file-modes savehist-file savehist-file-modes)) + (setq savehist-last-checksum checksum)) + (file-error + (unless savehist--has-given-file-warning + (lwarn '(savehist-file) :warning "Error writing `%s': %s" + savehist-file (caddr err)) + (setq savehist--has-given-file-warning t))))))) (defun savehist-autosave () "Save the minibuffer history if it has been modified since the last save. -- 2.28.0