]> git.eshelyaron.com Git - emacs.git/commitdiff
(save-place-abbreviate-file-names): Don't eagerly load alist (bug#75730)
authorStefan Monnier <monnier@iro.umontreal.ca>
Mon, 3 Feb 2025 21:33:39 +0000 (16:33 -0500)
committerEshel Yaron <me@eshelyaron.com>
Sun, 9 Feb 2025 08:02:25 +0000 (09:02 +0100)
Change the way we handle `save-place-abbreviate-file-names` such that
this preference is applied lazily when we load the alist, rather than
eagerly when we define it (which forced the alist to be loaded before we
needed it).

* lisp/saveplace.el (save-place-load-alist-from-file): Use `unless`,
`when`, and `with-temp-buffer` to hopefully help readability.
Call `save-place--normalize-alist`.
(save-place--normalize-alist): New function extracted from the setter
of `save-place-abbreviate-file-names`.
(save-place-abbreviate-file-names): Use it.
(save-place-alist-to-file): Use `with-temp-buffer`.

(cherry picked from commit f3ac16b3cc5778041332bb46f819a51e8b697099)

lisp/saveplace.el

index d6b3696f6c7087f1c95c0a575647ac888e7b3dd5..d188de29144599f0255aa2e012bd0fe3f1535f87 100644 (file)
@@ -101,47 +101,44 @@ this happens automatically before saving `save-place-alist' to
   :type 'boolean)
 
 (defun save-place-load-alist-from-file ()
-  (if (not save-place-loaded)
-      (progn
-        (setq save-place-loaded t)
-        (let ((file (expand-file-name save-place-file)))
-          ;; make sure that the alist does not get overwritten, and then
-          ;; load it if it exists:
-          (if (file-readable-p file)
-              ;; don't want to use find-file because we have been
-              ;; adding hooks to it.
-              (with-current-buffer (get-buffer-create " *Saved Places*")
-                (delete-region (point-min) (point-max))
-                ;; Make sure our 'coding:' cookie in the save-place
-                ;; file will take effect, in case the caller binds
-                ;; coding-system-for-read.
-                (let (coding-system-for-read)
-                  (insert-file-contents file))
-                (goto-char (point-min))
-                (setq save-place-alist
-                      (with-demoted-errors "Error reading save-place-file: %S"
-                        (car (read-from-string
-                              (buffer-substring (point-min) (point-max))))))
-
-                ;; If there is a limit, and we're over it, then we'll
-                ;; have to truncate the end of the list:
-                (if save-place-limit
-                    (if (<= save-place-limit 0)
-                        ;; Zero gets special cased.  I'm not thrilled
-                        ;; with this, but the loop for >= 1 is tight.
-                        (setq save-place-alist nil)
-                      ;; Else the limit is >= 1, so enforce it by
-                      ;; counting and then `setcdr'ing.
-                      (let ((s save-place-alist)
-                            (count 1))
-                        (while s
-                          (if (>= count save-place-limit)
-                              (setcdr s nil)
-                            (setq count (1+ count)))
-                          (setq s (cdr s))))))
-
-                (kill-buffer (current-buffer))))
-          nil))))
+  (unless save-place-loaded
+    (setq save-place-loaded t)
+    ;; FIXME: Obey `save-place-abbreviate-file-names'?
+    (let ((file (expand-file-name save-place-file)))
+      ;; make sure that the alist does not get overwritten, and then
+      ;; load it if it exists:
+      (when (file-readable-p file)
+        ;; don't want to use find-file because we have been
+        ;; adding hooks to it.
+        (with-temp-buffer
+          ;; Make sure our 'coding:' cookie in the save-place
+          ;; file will take effect, in case the caller binds
+          ;; coding-system-for-read.
+          (let (coding-system-for-read)
+            (insert-file-contents file))
+          (goto-char (point-min))
+          (setq save-place-alist
+                (with-demoted-errors "Error reading save-place-file: %S"
+                  (car (read-from-string
+                        (buffer-substring (point-min) (point-max))))))
+
+          ;; If there is a limit, and we're over it, then we'll
+          ;; have to truncate the end of the list:
+          (if save-place-limit
+              (if (<= save-place-limit 0)
+                  ;; Zero gets special cased.  I'm not thrilled
+                  ;; with this, but the loop for >= 1 is tight.
+                  (setq save-place-alist nil)
+                ;; Else the limit is >= 1, so enforce it by
+                ;; counting and then `setcdr'ing.
+                (let ((s save-place-alist)
+                      (count 1))
+                  (while s
+                    (if (>= count save-place-limit)
+                        (setcdr s nil)
+                      (setq count (1+ count)))
+                    (setq s (cdr s))))))))
+      (save-place--normalize-alist))))
 
 (defcustom save-place-abbreviate-file-names nil
   "If non-nil, abbreviate file names before saving them.
@@ -154,27 +151,32 @@ just using `setq' may cause out-of-sync problems.  You should use
 either `setopt' or \\[customize-variable] to set this option."
   :type 'boolean
   :set (lambda (sym val)
-         (set-default sym val)
-         (or save-place-loaded (save-place-load-alist-from-file))
-         (let ((fun (if val #'abbreviate-file-name #'expand-file-name))
-               ;; Don't expand file names for non-existing remote connections.
-               (non-essential t))
-           (setq save-place-alist
-                 (cl-delete-duplicates
-                  (cl-loop for (k . v) in save-place-alist
-                           collect
-                           (cons (funcall fun k)
-                                 (if (listp v)
-                                     (cl-loop for (k1 . v1) in v
-                                              collect
-                                              (cons k1 (funcall fun v1)))
-                                   v)))
-                  :key #'car
-                  :from-end t
-                  :test #'equal)))
-         val)
+         (let ((old (if (default-boundp sym) (default-value sym))))
+           (set-default sym val)
+           (if (or (equal old val) (not save-place-loaded))
+               nil                      ;Nothing to do.
+             (save-place--normalize-alist))))
   :version "28.1")
 
+(defun save-place--normalize-alist ()
+  (let ((fun (if save-place-abbreviate-file-names
+                 #'abbreviate-file-name #'expand-file-name))
+        ;; Don't expand file names for non-existing remote connections.
+        (non-essential t))
+    (setq save-place-alist
+          (cl-delete-duplicates
+           (cl-loop for (k . v) in save-place-alist
+                    collect
+                    (cons (funcall fun k)
+                          (if (listp v)
+                              (cl-loop for (k1 . v1) in v
+                                       collect
+                                       (cons k1 (funcall fun v1)))
+                            v)))
+           :key #'car
+           :from-end t
+           :test #'equal))))
+
 (defcustom save-place-save-skipped t
   "If non-nil, remember files matching `save-place-skip-check-regexp'.
 
@@ -273,7 +275,6 @@ Use `setopt' or Customize commands to set this option."
 This means when you visit a file, point goes to the last place
 where it was when you previously visited the same file."
   :global t
-  :group 'save-place
   (save-place--setup-hooks save-place-mode)
   (save-place--manage-timer))
 
@@ -383,8 +384,7 @@ may have changed) back to `save-place-alist'."
 (defun save-place-alist-to-file ()
   (let ((file (expand-file-name save-place-file))
         (coding-system-for-write 'utf-8))
-    (with-current-buffer (get-buffer-create " *Saved Places*")
-      (delete-region (point-min) (point-max))
+    (with-temp-buffer
       (when save-place-forget-unreadable-files
        (save-place-forget-unreadable-files))
       (insert (format ";;; -*- coding: %s; mode: lisp-data -*-\n"
@@ -402,8 +402,7 @@ may have changed) back to `save-place-alist'."
        (condition-case nil
            ;; Don't use write-file; we don't want this buffer to visit it.
             (write-region (point-min) (point-max) file)
-         (file-error (message "Saving places: can't write %s" file)))
-        (kill-buffer (current-buffer))))))
+         (file-error (message "Saving places: can't write %s" file)))))))
 
 (defun save-places-to-alist ()
   ;; go through buffer-list, saving places to alist if save-place-mode