]> git.eshelyaron.com Git - emacs.git/commitdiff
lisp/savehist.el: Save data, not code.
authorEshel Yaron <me@eshelyaron.com>
Sat, 12 Apr 2025 09:15:10 +0000 (11:15 +0200)
committerEshel Yaron <me@eshelyaron.com>
Sat, 12 Apr 2025 09:15:10 +0000 (11:15 +0200)
lisp/savehist.el

index 2a5ffb8c904bc19afc733ef8b8be1e4d64f8d65e..2a6b450280ab535d9e95abe10e936934830cac72 100644 (file)
@@ -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")