(Buffer-menu-make-sort-button) Make sorting by mouse-2 work from a different window.
[bpt/emacs.git] / lisp / saveplace.el
index d3ad772..249bdfe 100644 (file)
@@ -1,8 +1,8 @@
-;;; saveplace.el --- automatically save place in files.
+;;; saveplace.el --- automatically save place in files
 
-;; Copyright (C) 1993, 1994 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994, 2001 Free Software Foundation, Inc.
 
-;; Author: Karl Fogel <kfogel@cs.oberlin.edu>
+;; Author: Karl Fogel <kfogel@red-bean.com>
 ;; Maintainer: FSF
 ;; Created: July, 1993
 ;; Keywords: bookmarks, placeholders
@@ -63,6 +63,7 @@ simply put this in your `~/.emacs' file:
 
 \(setq-default save-place t\)"
   :type 'boolean
+  :require 'saveplace
   :group 'save-place)
 
 (make-variable-buffer-local 'save-place)
@@ -72,7 +73,7 @@ simply put this in your `~/.emacs' file:
   :type 'file
   :group 'save-place)
 
-(defcustom save-place-version-control 'nospecial
+(defcustom save-place-version-control nil
   "*Controls whether to make numbered backups of master save-place file.
 It can have four values: t, nil, `never', and `nospecial'.  The first
 three have the same meaning that they do for the variable
@@ -81,7 +82,7 @@ value of `version-control'."
   :type '(radio (const :tag "Unconditionally" t)
                (const :tag "For VC Files" nil)
                (const never)
-               (const :tag "Use value of version-control" nospecial))
+               (const :tag "Use value of `version-control'" nospecial))
   :group 'save-place)
 
 (defvar save-place-loaded nil
@@ -93,6 +94,40 @@ value of `version-control'."
                 (const :tag "No Limit" nil))
   :group 'save-place)
 
+(defcustom save-place-forget-unreadable-files t
+  "Non-nil means forget place in unreadable files.
+
+The filenames in `save-place-alist' that do not match
+`save-place-skip-check-regexp' are filtered through
+`file-readable-p'. if nil, their alist entries are removed.
+
+You may do this anytime by calling the complementary function,
+`save-place-forget-unreadable-files'.  When this option is turned on,
+this happens automatically before saving `save-place-alist' to
+`save-place-file'."
+  :type 'boolean :group 'save-place)
+
+(defcustom save-place-save-skipped t
+  "If non-nil, remember files matching `save-place-skip-check-regexp'.
+
+When filtering `save-place-alist' for unreadable files, some will not
+be checked, based on said regexp, and instead saved or forgotten based
+on this flag."
+  :type 'boolean :group 'save-place)
+
+(defcustom save-place-skip-check-regexp
+  ;; thanks to ange-ftp-name-format
+  "\\`/\\(?:cdrom\\|floppy\\|mnt\\|\\(?:[^@/:]*@\\)?[^@/:]*[^@/:.]:\\)"
+  "Regexp whose file names shall not be checked for readability.
+
+When forgetting unreadable files, file names matching this regular
+expression shall not be checked for readability, but instead be
+subject to `save-place-save-skipped'.
+
+Files for which such a check may be inconvenient include those on
+removable and network volumes."
+  :type 'regexp :group 'save-place)
+
 (defun toggle-save-place (&optional parg)
   "Toggle whether to save your place in this file between sessions.
 If this mode is enabled, point is recorded when you kill the buffer
@@ -125,16 +160,44 @@ To save places automatically in all files, put this in your `.emacs' file:
   (or save-place-loaded (load-save-place-alist-from-file))
   (if buffer-file-name
       (progn
-        (let ((cell (assoc buffer-file-name save-place-alist)))
+        (let ((cell (assoc buffer-file-name save-place-alist))
+             (position (if (not (eq major-mode 'hexl-mode))
+                           (point)
+                         (1+ (hexl-current-address)))))
           (if cell
-              (setq save-place-alist (delq cell save-place-alist))))
-        (if save-place
-            (setq save-place-alist
-                 (cons (cons buffer-file-name
-                             (if (not (eq major-mode 'hexl-mode))
-                                 (point)
-                               (1+ (hexl-current-address))))
-                        save-place-alist))))))
+              (setq save-place-alist (delq cell save-place-alist)))
+         (if (and save-place
+                  (not (= position 1)))  ;; Optimize out the degenerate case.
+             (setq save-place-alist
+                   (cons (cons buffer-file-name position)
+                         save-place-alist)))))))
+
+(defun save-place-forget-unreadable-files ()
+  "Remove unreadable files from `save-place-alist'.
+For each entry in the alist, if `file-readable-p' returns nil for the
+filename, remove the entry.  Save the new alist \(as the first pair
+may have changed\) back to `save-place-alist'."
+  (interactive)
+  ;; the following was adapted from an in-place filtering function,
+  ;; `filter-mod', used in the original.
+  (unless (null save-place-alist)      ;says it better than `when'
+    ;; first, check all except first
+    (let ((fmprev save-place-alist) (fmcur (cdr save-place-alist)))
+      (while fmcur                     ;not null
+       ;; a value is only saved when it becomes FMPREV.
+       (if (if (string-match save-place-skip-check-regexp (caar fmcur))
+               save-place-save-skipped
+             (file-readable-p (caar fmcur)))
+           (setq fmprev fmcur)
+         (setcdr fmprev (cdr fmcur)))
+       (setq fmcur (cdr fmcur))))
+    ;; test first pair, keep it if OK, otherwise 2nd element, which
+    ;; may be '()
+    (unless (if (string-match save-place-skip-check-regexp
+                             (caar save-place-alist))
+               save-place-save-skipped
+             (file-readable-p (caar save-place-alist)))
+      (setq save-place-alist (cdr save-place-alist)))))
 
 (defun save-place-alist-to-file ()
   (let ((file (expand-file-name save-place-file)))
@@ -142,11 +205,11 @@ To save places automatically in all files, put this in your `.emacs' file:
       (message "Saving places to %s..." file)
       (set-buffer (get-buffer-create " *Saved Places*"))
       (delete-region (point-min) (point-max))
-      (if (file-readable-p file)
-          (insert-file-contents file))
-      (delete-region (point-min) (point-max))
-      (goto-char (point-min))
-      (print save-place-alist (current-buffer))
+      (when save-place-forget-unreadable-files
+       (save-place-forget-unreadable-files))
+      (let ((print-length nil)
+            (print-level nil))
+        (print save-place-alist (current-buffer)))
       (let ((version-control
              (cond
               ((null save-place-version-control) nil)
@@ -174,7 +237,7 @@ To save places automatically in all files, put this in your `.emacs' file:
                 (delete-region (point-min) (point-max))
                 (insert-file-contents file)
                 (goto-char (point-min))
-                (setq save-place-alist 
+                (setq save-place-alist
                       (car (read-from-string
                             (buffer-substring (point-min) (point-max)))))
 
@@ -194,7 +257,7 @@ To save places automatically in all files, put this in your `.emacs' file:
                               (setcdr s nil)
                             (setq count (1+ count)))
                           (setq s (cdr s))))))
-                  
+
                 (kill-buffer (current-buffer))
                 (message "Loading places from %s...done" file)))
           nil))))
@@ -232,7 +295,7 @@ To save places automatically in all files, put this in your `.emacs' file:
   (if save-place-loaded
       (save-place-alist-to-file)))
 
-(add-hook 'find-file-hooks 'save-place-find-file-hook t)
+(add-hook 'find-file-hook 'save-place-find-file-hook t)
 
 (add-hook 'kill-emacs-hook 'save-place-kill-emacs-hook)
 
@@ -240,5 +303,5 @@ To save places automatically in all files, put this in your `.emacs' file:
 
 (provide 'saveplace) ; why not...
 
+;;; arch-tag: 3c2ef47b-0a22-4558-b116-118c9ef454a0
 ;;; saveplace.el ends here
-