diff options
| author | Richard M. Stallman | 1993-08-13 01:08:54 +0000 |
|---|---|---|
| committer | Richard M. Stallman | 1993-08-13 01:08:54 +0000 |
| commit | 722074ef8735586605223cc6bfdde31272de7c97 (patch) | |
| tree | d6e7b9ccaf15e7bbaff2fca1f348ed98670f1c20 | |
| parent | 11eb4275a3650d5083b3e7e705e5e614845270ab (diff) | |
| download | emacs-722074ef8735586605223cc6bfdde31272de7c97.tar.gz emacs-722074ef8735586605223cc6bfdde31272de7c97.zip | |
entered into RCS
| -rw-r--r-- | lisp/saveplace.el | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/lisp/saveplace.el b/lisp/saveplace.el new file mode 100644 index 00000000000..deaa13ed4f3 --- /dev/null +++ b/lisp/saveplace.el | |||
| @@ -0,0 +1,186 @@ | |||
| 1 | ;;; saveplace.el --- automatically save place in files. | ||
| 2 | |||
| 3 | ;; Copyright (C) 1993 Free Software Foundation, Inc. | ||
| 4 | |||
| 5 | ;; Author: Karl Fogel <kfogel@cs.oberlin.edu> | ||
| 6 | ;; Maintainer: FSF | ||
| 7 | ;; Created: July, 1993 | ||
| 8 | ;; Version: 1.0 | ||
| 9 | ;; Keywords: bookmarks, placeholders | ||
| 10 | |||
| 11 | ;; This file is part of GNU Emacs. | ||
| 12 | |||
| 13 | ;; GNU Emacs is free software; you can redistribute it and/or modify | ||
| 14 | ;; it under the terms of the GNU General Public License as published by | ||
| 15 | ;; the Free Software Foundation; either version 2, or (at your option) | ||
| 16 | ;; any later version. | ||
| 17 | |||
| 18 | ;; GNU Emacs is distributed in the hope that it will be useful, | ||
| 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 21 | ;; GNU General Public License for more details. | ||
| 22 | |||
| 23 | ;; You should have received a copy of the GNU General Public License | ||
| 24 | ;; along with GNU Emacs; see the file COPYING. If not, write to | ||
| 25 | ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. | ||
| 26 | |||
| 27 | ;; Automatically save place in files, so that visiting them later | ||
| 28 | ;; (even during a different Emacs session) automatically moves point | ||
| 29 | ;; to the saved position, when the file is first found. Uses the | ||
| 30 | ;; value of buffer-local variable save-place to determine whether to | ||
| 31 | ;; save position or not. | ||
| 32 | ;; | ||
| 33 | ;; Don't autoload this, rather, load it, since it modifies | ||
| 34 | ;; find-file-hooks and other hooks. | ||
| 35 | |||
| 36 | ;; this is what I was using during testing: | ||
| 37 | ;; (define-key ctl-x-map "p" 'toggle-save-place) | ||
| 38 | |||
| 39 | (defvar save-place-alist nil | ||
| 40 | "Alist of saved places to go back to when revisiting files. | ||
| 41 | Each element looks like (FILENAME . POSITION); | ||
| 42 | visiting file FILENAME goes automatically to position POSITION | ||
| 43 | rather than the beginning of the buffer. | ||
| 44 | This alist is saved between Emacs sessions.") | ||
| 45 | |||
| 46 | (defvar save-place nil | ||
| 47 | "*Non-nil means automatically save place in each file. | ||
| 48 | This means when you visit a file, point goes to the last place | ||
| 49 | where it was when you previously visited the same file. | ||
| 50 | This variable is automatically buffer-local. | ||
| 51 | |||
| 52 | If you wish your place in any file to always be automatically saved, | ||
| 53 | simply put this in your `~/.emacs' file: | ||
| 54 | |||
| 55 | \(setq-default save-place t\)") | ||
| 56 | |||
| 57 | (make-variable-buffer-local 'save-place) | ||
| 58 | |||
| 59 | (defvar save-place-file "~/.emacs-places" | ||
| 60 | "*Name of the file that records `save-place-alist' value.") | ||
| 61 | |||
| 62 | (defvar save-place-loaded nil | ||
| 63 | "Non-nil means that the `save-place-file' has been loaded.") | ||
| 64 | |||
| 65 | (defun toggle-save-place (&optional parg) | ||
| 66 | "Toggle whether to save your place in this file between sessions. | ||
| 67 | If this mode is enabled, point is recorded when you kill the buffer | ||
| 68 | or exit Emacs. Visiting this file again will go to that position, | ||
| 69 | even in a later Emacs session. | ||
| 70 | |||
| 71 | If called with a prefix arg, the mode is enabled if and only if | ||
| 72 | the argument is positive. | ||
| 73 | |||
| 74 | To save places automatically in all files, put this in your `.emacs' file: | ||
| 75 | |||
| 76 | \(setq-default save-place t\)" | ||
| 77 | (interactive "P") | ||
| 78 | (if (not buffer-file-name) | ||
| 79 | (message | ||
| 80 | (format "Buffer \"%s\" not visiting a file." (buffer-name))) | ||
| 81 | (if (and save-place (or (not parg) (<= parg 0))) | ||
| 82 | (progn | ||
| 83 | (message "No place will be saved in this file.") | ||
| 84 | (setq save-place nil)) | ||
| 85 | (message "Place will be saved.") | ||
| 86 | (setq save-place t)))) | ||
| 87 | |||
| 88 | (defun save-place-to-alist () | ||
| 89 | ;; put filename and point in a cons box and then cons that onto the | ||
| 90 | ;; front of the save-place-alist, if save-place is non-nil. | ||
| 91 | ;; Otherwise, just delete that file from the alist. | ||
| 92 | ;; first check to make sure alist has been loaded in from the master | ||
| 93 | ;; file. If not, do so, then feel free to modify the alist. It | ||
| 94 | ;; will be saved again when Emacs is killed. | ||
| 95 | (or save-place-loaded (load-save-place-alist-from-file)) | ||
| 96 | (if buffer-file-name | ||
| 97 | (progn | ||
| 98 | (let ((cell (assoc buffer-file-name save-place-alist))) | ||
| 99 | (if cell | ||
| 100 | (setq save-place-alist (delq cell save-place-alist)))) | ||
| 101 | (if save-place | ||
| 102 | (setq save-place-alist | ||
| 103 | (cons (cons buffer-file-name (point)) | ||
| 104 | save-place-alist)))))) | ||
| 105 | |||
| 106 | (defun save-place-alist-to-file () | ||
| 107 | (let ((file (expand-file-name save-place-file))) | ||
| 108 | (save-excursion | ||
| 109 | (message (format "Saving places to %s..." file)) | ||
| 110 | (set-buffer (get-buffer-create " *Saved Places*")) | ||
| 111 | (delete-region (point-min) (point-max)) | ||
| 112 | (if (file-readable-p file) | ||
| 113 | (insert-file-contents file)) | ||
| 114 | (delete-region (point-min) (point-max)) | ||
| 115 | (goto-char (point-min)) | ||
| 116 | (print save-place-alist (current-buffer)) | ||
| 117 | (write-file file) | ||
| 118 | (kill-buffer (current-buffer)) | ||
| 119 | (message (format "Saving places to %s... done." file))))) | ||
| 120 | |||
| 121 | (defun load-save-place-alist-from-file () | ||
| 122 | (if (not save-place-loaded) | ||
| 123 | (progn | ||
| 124 | (setq save-place-loaded t) | ||
| 125 | (let ((file (expand-file-name save-place-file))) | ||
| 126 | ;; make sure that the alist does not get overwritten, and then | ||
| 127 | ;; load it if it exists: | ||
| 128 | (if (file-readable-p file) | ||
| 129 | (save-excursion | ||
| 130 | (message (format "Loading places from %s..." | ||
| 131 | save-place-file)) | ||
| 132 | ;; don't want to use find-file because we have been | ||
| 133 | ;; adding hooks to it. | ||
| 134 | (set-buffer (get-buffer-create " *Saved Places*")) | ||
| 135 | (delete-region (point-min) (point-max)) | ||
| 136 | (insert-file-contents file) | ||
| 137 | (goto-char (point-min)) | ||
| 138 | (setq save-place-alist | ||
| 139 | (car (read-from-string | ||
| 140 | (buffer-substring (point-min) (point-max))))) | ||
| 141 | (kill-buffer (current-buffer)) | ||
| 142 | (message (format "Loading places from %s... done." file)) | ||
| 143 | t) | ||
| 144 | t) | ||
| 145 | nil)))) | ||
| 146 | |||
| 147 | (defun save-places-to-alist () | ||
| 148 | ;; go through buffer-list, saving places to alist if save-place is | ||
| 149 | ;; non-nil, deleting them from alist if it is nil. | ||
| 150 | (let ((buf-list (buffer-list))) | ||
| 151 | (while buf-list | ||
| 152 | ;; put this into a save-excursion in case someone is counting on | ||
| 153 | ;; another function in kill-emacs-hook to act on the last buffer | ||
| 154 | ;; they were in: | ||
| 155 | (save-excursion | ||
| 156 | (set-buffer (car buf-list)) | ||
| 157 | ;; save-place checks buffer-file-name too, but we can avoid | ||
| 158 | ;; overhead of function call by checking here too. | ||
| 159 | (and buffer-file-name (save-place-to-alist)) | ||
| 160 | (setq buf-list (cdr buf-list)))))) | ||
| 161 | |||
| 162 | (add-hook | ||
| 163 | 'find-file-hooks | ||
| 164 | (function | ||
| 165 | (lambda () | ||
| 166 | (or save-place-loaded (load-save-place-alist-from-file)) | ||
| 167 | (let ((cell (assoc buffer-file-name save-place-alist))) | ||
| 168 | (if cell | ||
| 169 | (progn | ||
| 170 | (goto-char (cdr cell)) | ||
| 171 | ;; and make sure it will be saved again for later. | ||
| 172 | (setq save-place t))))))) | ||
| 173 | |||
| 174 | (add-hook 'kill-emacs-hook | ||
| 175 | (function | ||
| 176 | (lambda () | ||
| 177 | (progn | ||
| 178 | (save-places-to-alist) | ||
| 179 | (save-place-alist-to-file))))) | ||
| 180 | |||
| 181 | (add-hook 'kill-buffer-hook 'save-place-to-alist) | ||
| 182 | |||
| 183 | (provide 'saveplace) ; why not... | ||
| 184 | |||
| 185 | ;;; saveplace.el ends here | ||
| 186 | |||