diff lisp/packages/saveplace.el @ 2:ac2d302a0011 r19-15b2

Import from CVS: tag r19-15b2
author cvs
date Mon, 13 Aug 2007 08:46:35 +0200
parents 376386a54a3c
children 34a5b81f86ba
line wrap: on
line diff
--- a/lisp/packages/saveplace.el	Mon Aug 13 08:45:53 2007 +0200
+++ b/lisp/packages/saveplace.el	Mon Aug 13 08:46:35 2007 +0200
@@ -1,11 +1,11 @@
 ;;; saveplace.el --- automatically save place in files.
 
-;; Copyright (C) 1993 Free Software Foundation, Inc.
+;; Copyright (C) 1993, 1994 Free Software Foundation, Inc.
 
 ;; Author: Karl Fogel <kfogel@cs.oberlin.edu>
 ;; Maintainer: FSF
 ;; Created: July, 1993
-;; Version: 1.0
+;; Version: >1.0 (RMS doesn't keep version numbers :-( )
 ;; Keywords: bookmarks, placeholders
 
 ;; This file is part of XEmacs.
@@ -22,9 +22,12 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with XEmacs; see the file COPYING.  If not, write to the Free
-;; Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+;; 02111-1307, USA.
 
-;;; Synched up with: Not synched with FSF but close to 19.30.
+;;; Synched up with: FSF 19.34.
+
+;;; Commentary:
 
 ;; Automatically save place in files, so that visiting them later
 ;; (even during a different Emacs session) automatically moves point
@@ -32,8 +35,10 @@
 ;; value of buffer-local variable save-place to determine whether to
 ;; save position or not.
 ;;
-;; Don't autoload this, rather, load it, since it modifies
-;; find-file-hooks and other hooks.
+;; Thanks to Stefan Schoef, who sent a patch with the
+;; `save-place-version-control' stuff in it.
+
+;;; Code:
 
 ;; this is what I was using during testing:
 ;; (define-key ctl-x-map "p" 'toggle-save-place)
@@ -58,12 +63,22 @@
 
 (make-variable-buffer-local 'save-place)
 
-(defvar save-place-file "~/.emacs-places"
+(defvar save-place-file (convert-standard-filename "~/.emacs-places")
   "*Name of the file that records `save-place-alist' value.")
 
+(defvar save-place-version-control 'nospecial
+  "*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
+`version-control', and the final value `nospecial' means just use the
+value of `version-control'.")
+
 (defvar save-place-loaded nil
   "Non-nil means that the `save-place-file' has been loaded.")
 
+(defvar save-place-limit nil
+  "Maximum number of entries to retain in the list; nil means no limit.")
+
 (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
@@ -78,13 +93,12 @@
 \(setq-default save-place t\)"
   (interactive "P")
   (if (not buffer-file-name)
-      (message 
-       (format "Buffer \"%s\" not visiting a file." (buffer-name)))
+      (message "Buffer `%s' not visiting a file" (buffer-name))
     (if (and save-place (or (not parg) (<= parg 0)))
 	(progn
-	  (message "No place will be saved in this file.")
+	  (message "No place will be saved in this file")
 	  (setq save-place nil))
-      (message "Place will be saved.")
+      (message "Place will be saved")
       (setq save-place t))))
 
 (defun save-place-to-alist ()
@@ -102,13 +116,16 @@
               (setq save-place-alist (delq cell save-place-alist))))
         (if save-place
             (setq save-place-alist
-                  (cons (cons buffer-file-name (point))
+		  (cons (cons buffer-file-name
+			      (if (not (eq major-mode 'hexl-mode))
+				  (point)
+				(1+ (hexl-current-address))))
                         save-place-alist))))))
 
 (defun save-place-alist-to-file ()
   (let ((file (expand-file-name save-place-file)))
     (save-excursion
-      (message (format "Saving places to %s..." 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)
@@ -116,9 +133,16 @@
       (delete-region (point-min) (point-max))
       (goto-char (point-min))
       (print save-place-alist (current-buffer))
-      (write-file file)
-      (kill-buffer (current-buffer))
-      (message (format "Saving places to %s... done." file)))))
+      (let ((version-control
+	     (cond
+	      ((null save-place-version-control) nil)
+	      ((eq 'never save-place-version-control) 'never)
+	      ((eq 'nospecial save-place-version-control) version-control)
+	      (t
+	       t))))
+	(write-file file)
+	(kill-buffer (current-buffer))
+	(message "Saving places to %s...done" file)))))
 
 (defun load-save-place-alist-from-file ()
   (if (not save-place-loaded)
@@ -129,8 +153,7 @@
           ;; load it if it exists:
           (if (file-readable-p file)
               (save-excursion
-                (message (format "Loading places from %s..."
-                                 save-place-file))
+                (message "Loading places from %s..." save-place-file)
                 ;; don't want to use find-file because we have been
                 ;; adding hooks to it.
                 (set-buffer (get-buffer-create " *Saved Places*"))
@@ -140,8 +163,25 @@
                 (setq save-place-alist 
                       (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))
-                (message (format "Loading places from %s... done." file))
+                (message "Loading places from %s...done" file)
                 t)
             t)
           nil))))
@@ -160,25 +200,28 @@
 	;; overhead of function call by checking here too.
 	(and buffer-file-name (save-place-to-alist))
 	(setq buf-list (cdr buf-list))))))
-    
-(add-hook 
- 'find-file-hooks
- (function
-  (lambda ()
-    (or save-place-loaded (load-save-place-alist-from-file))
-    (let ((cell (assoc buffer-file-name save-place-alist)))
-      (if cell
-	  (progn
-	    (goto-char (cdr cell))
-	    ;; and make sure it will be saved again for later.
-	    (setq save-place t)))))))
+
+(defun save-place-find-file-hook ()
+  (or save-place-loaded (load-save-place-alist-from-file))
+  (let ((cell (assoc buffer-file-name save-place-alist)))
+    (if cell
+	(progn
+	  (or after-find-file-from-revert-buffer
+	      (goto-char (cdr cell)))
+	  ;; and make sure it will be saved again for later
+	  (setq save-place t)))))
 
-(add-hook 'kill-emacs-hook
-	  (function
-	   (lambda ()
-	     (progn
-	       (save-places-to-alist)
-	       (save-place-alist-to-file)))))
+(defun save-place-kill-emacs-hook ()
+  ;; First update the alist.  This loads the old save-place-file if nec.
+  (save-places-to-alist)
+  ;; Now save the alist in the file, if we have ever loaded the file
+  ;; (including just now).
+  (if save-place-loaded
+      (save-place-alist-to-file)))
+
+(add-hook 'find-file-hooks 'save-place-find-file-hook t)
+
+(add-hook 'kill-emacs-hook 'save-place-kill-emacs-hook)
 
 (add-hook 'kill-buffer-hook 'save-place-to-alist)