From 476ba6d5934ad448cc69f0bd0822062636b6c430 Mon Sep 17 00:00:00 2001 From: Eshel Yaron Date: Sat, 12 Apr 2025 11:15:10 +0200 Subject: [PATCH] lisp/savehist.el: Save data, not code. --- lisp/savehist.el | 133 +++++++++++------------------------------------ 1 file changed, 31 insertions(+), 102 deletions(-) diff --git a/lisp/savehist.el b/lisp/savehist.el index 2a5ffb8c904..2a6b450280a 100644 --- a/lisp/savehist.el +++ b/lisp/savehist.el @@ -38,8 +38,7 @@ ;; ;; or with customize: `M-x customize-option RET savehist-mode RET'. ;; -;; You can also explicitly save history with `M-x savehist-save' and -;; load it by loading the `savehist-file' with `M-x load-file'. +;; You can also explicitly save history with `M-x savehist-save'. ;;; Code: @@ -67,8 +66,7 @@ MAX-SIZE elements (if the value is a list) before saving the value. The contents of variables should be printable with the Lisp printer. You don't need to add minibuffer history variables to -this list, all minibuffer histories will be saved automatically -as long as `savehist-save-minibuffer-history' is non-nil. +this list, all minibuffer histories will be saved automatically. User options should be saved with the Customize interface. This list is useful for saving automatically updated variables that are not @@ -149,8 +147,6 @@ unwise, unless you know what you are doing.") ;; Internal variables. -(defvar savehist-last-checksum nil) - (defvar savehist-minibuffer-history-variables nil "List of minibuffer histories. The contents of this variable is built while Emacs is running, and saved @@ -176,18 +172,13 @@ it loads the previous minibuffer histories from `savehist-file'. The variable `savehist-autosave-interval' controls the periodicity of saving minibuffer histories. -If `savehist-save-minibuffer-history' is non-nil (the default), -all recorded minibuffer histories will be saved. You can arrange +All recorded minibuffer histories will be saved. You can arrange for additional history variables to be saved and restored by customizing `savehist-additional-variables', which by default is an empty list. For example, to save the history of commands invoked via \\[execute-extended-command], add `command-history' to the list in `savehist-additional-variables'. -Alternatively, you could customize `savehist-save-minibuffer-history' -to nil, and add to `savehist-additional-variables' only those -history variables you want to save. - To ignore some history variables, add their symbols to the list in `savehist-ignored-variables'. @@ -200,13 +191,12 @@ histories, which is probably undesirable." (when (and (not savehist-loaded) (file-exists-p savehist-file)) (condition-case errvar - (progn - ;; Don't set coding-system-for-read -- we rely on the - ;; coding cookie to convey that information. That way, if - ;; the user changes the value of savehist-coding-system, - ;; we can still correctly load the old file. - (load savehist-file nil (not (called-interactively-p 'interactive))) - (setq savehist-loaded t)) + (with-temp-buffer + (insert-file-contents savehist-file) + (goto-char (point-min)) + (dolist (entry (read (current-buffer))) + (set (car entry) (cdr entry))) + (setq savehist-loaded t)) (error ;; Don't install the mode if reading failed. Doing so would ;; effectively destroy the user's data at the next save. @@ -232,17 +222,15 @@ Normally invoked by calling `savehist-mode' to unset the minor mode." (savehist--manage-timer)) (defvar savehist--has-given-file-warning nil) -(defun savehist-save (&optional auto-save) +(defun savehist-save () "Save the values of minibuffer history variables. -Unbound symbols referenced in `savehist-additional-variables' are ignored. -If AUTO-SAVE is non-nil, compare the saved contents to the one last saved, - and don't save the buffer if they are the same." +Unbound symbols referenced in `savehist-additional-variables' are ignored." (interactive) (with-temp-buffer (insert (format-message (concat - ";; -*- mode: emacs-lisp; coding: %s -*-\n" + ";; -*- mode: lisp-data; coding: %s -*-\n" ";; Minibuffer history file, automatically generated by `savehist'.\n" "\n") savehist-coding-system)) @@ -251,73 +239,17 @@ If AUTO-SAVE is non-nil, compare the saved contents to the one last saved, (print-level nil) (print-quoted t) (print-circle t)) - ;; Save the minibuffer histories, along with the value of - ;; savehist-minibuffer-history-variables itself. - (when savehist-save-minibuffer-history - (prin1 `(setq savehist-minibuffer-history-variables - ',savehist-minibuffer-history-variables) - (current-buffer)) - (insert ?\n) - (dolist (symbol savehist-minibuffer-history-variables) - (when (and (boundp symbol) - (not (memq symbol savehist-ignored-variables))) - (let ((value (symbol-value symbol)) - excess-space) - (when value ; Don't save empty histories. - (insert "(setq ") - (prin1 symbol (current-buffer)) - (insert " '(") - ;; We will print an extra space before the first element. - ;; Record where that is. - (setq excess-space (point)) - ;; Print elements of VALUE one by one, carefully. - (dolist (elt value) - (let ((start (point))) - (insert " ") - ;; Try to print and then to read an element. - (condition-case nil - (progn - (prin1 elt (current-buffer)) - (save-excursion - (goto-char start) - (read (current-buffer)))) - (error - ;; If writing or reading gave an error, comment it out. - (goto-char start) - (insert "\n") - (while (not (eobp)) - (insert ";;; ") - (forward-line 1)) - (insert "\n"))) - (goto-char (point-max)))) - ;; Delete the extra space before the first element. - (save-excursion - (goto-char excess-space) - (if (eq (following-char) ?\s) - (delete-region (point) (1+ (point))))) - (insert "))\n")))))) - ;; Save the additional variables. - (dolist (elem savehist-additional-variables) - (when (not (memq elem savehist-minibuffer-history-variables)) - (let ((symbol (if (consp elem) - (car elem) - elem))) - (when (boundp symbol) - (let ((value (symbol-value symbol))) - (when (savehist-printable value) - ;; When we have a max-size, chop off the last elements. - (when (and (consp elem) - (listp value) - (length> value (cdr elem))) - (setq value (copy-sequence value)) - (setcdr (nthcdr (cdr elem) value) nil)) - (prin1 `(setq ,symbol ',value) (current-buffer)) - (insert ?\n)))))))) - ;; If autosaving, avoid writing if nothing has changed since the - ;; last write. - (let ((checksum (md5 (current-buffer) nil nil savehist-coding-system))) - (condition-case err - (unless (and auto-save (equal checksum savehist-last-checksum)) + (prin1 + (seq-keep + (lambda (sym) + (when (and (boundp sym) (not (memq sym savehist-ignored-variables))) + (cons sym (symbol-value sym)))) + (cons 'savehist-minibuffer-history-variables + (append savehist-minibuffer-history-variables + savehist-additional-variables))) + (current-buffer))) + (condition-case err + (progn ;; 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 @@ -327,24 +259,21 @@ If AUTO-SAVE is non-nil, compare the saved contents to the one last saved, (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)) + (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))))))) + (set-file-modes savehist-file savehist-file-modes))) + (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. Does nothing if Savehist mode is off." - (when savehist-mode - (savehist-save t))) + (when savehist-mode (savehist-save))) (define-obsolete-function-alias 'savehist-trim-history #'identity "27.1") -- 2.39.5