From: Stefan Monnier Date: Mon, 3 Feb 2025 21:33:39 +0000 (-0500) Subject: (save-place-abbreviate-file-names): Don't eagerly load alist (bug#75730) X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=4d4ab5a0af9cdbe733be9883162e23a30d7bea76;p=emacs.git (save-place-abbreviate-file-names): Don't eagerly load alist (bug#75730) 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) --- diff --git a/lisp/saveplace.el b/lisp/saveplace.el index d6b3696f6c7..d188de29144 100644 --- a/lisp/saveplace.el +++ b/lisp/saveplace.el @@ -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