/[emacs]/emacs/lisp/savehist.el
ViewVC logotype

Diff of /emacs/lisp/savehist.el

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.8 by monnier, Mon Oct 24 17:21:30 2005 UTC revision 1.9 by monnier, Tue Nov 1 05:49:46 2005 UTC
# Line 4  Line 4 
4    
5  ;; Author: Hrvoje Niksic <hniksic@xemacs.org>  ;; Author: Hrvoje Niksic <hniksic@xemacs.org>
6  ;; Keywords: minibuffer  ;; Keywords: minibuffer
7  ;; Version: 9  ;; Version: 19
8    
9  ;; This file is part of GNU Emacs.  ;; This file is part of GNU Emacs.
10    
# Line 32  Line 32 
32  ;; variables may be specified by customizing  ;; variables may be specified by customizing
33  ;; `savehist-additional-variables'.  ;; `savehist-additional-variables'.
34    
35  ;; To use savehist, put the following to `~/.emacs':  ;; To use savehist, turn on savehist-mode by putting the following in
36    ;; `~/.emacs':
37  ;;  ;;
38  ;; (require 'savehist)  ;;     (savehist-mode 1)
39  ;; (savehist-load)  ;;
40    ;; or with customize: `M-x customize-option RET savehist-mode RET'.
41    ;;
42    ;; You can also explicitly save history with `M-x savehist-save' and
43    ;; load it by loading the `savehist-file' with `M-x load'.
44    
45  ;; If you are using a version of Emacs that does not ship with this  ;; If you are using a version of Emacs that does not ship with this
46  ;; package, be sure to have `savehist.el' in a directory that is in  ;; package, be sure to have `savehist.el' in a directory that is in
# Line 53  Line 58 
58    "Save minibuffer history."    "Save minibuffer history."
59    :group 'minibuffer)    :group 'minibuffer)
60    
61    ;;;###autoload
62    (defcustom savehist-mode nil
63      "Mode for automatic saving of minibuffer history.
64    Set this by calling the `savehist-mode' function or using the customize
65    interface."
66      :type 'boolean
67      :set (lambda (symbol value) (savehist-mode (or value 0)))
68      :initialize 'custom-initialize-default
69      :require 'savehist
70      :group 'savehist)
71    
72  (defcustom savehist-save-minibuffer-history t  (defcustom savehist-save-minibuffer-history t
73    "If non-nil, save all recorded minibuffer histories."    "*If non-nil, save all recorded minibuffer histories.
74    If you want to save only specific histories, use `savehist-save-hook' to
75    modify the value of `savehist-minibuffer-history-variables'."
76    :type 'boolean    :type 'boolean
77    :group 'savehist)    :group 'savehist)
78    
79  (defcustom savehist-additional-variables ()  (defcustom savehist-additional-variables ()
80    "List of additional variables to save.    "*List of additional variables to save.
81  Each element is a symbol whose value will be persisted across Emacs  Each element is a symbol whose value will be persisted across Emacs
82  sessions that use savehist.  The contents of variables should be  sessions that use savehist.  The contents of variables should be
83  printable with the Lisp printer.  If the variable's value is a list,  printable with the Lisp printer.  You don't need to add minibuffer
84  it will be trimmed to `savehist-length' elements.  history variables to this list, all minibuffer histories will be
85    saved automatically as long as `savehist-save-minibuffer-history' is
86  You don't need to add minibuffer history variables to this list.  All  non-nil.
87  minibuffer histories will be saved automatically."  
88    :type '(repeat (symbol :tag "Variable"))  User options should be saved with the customize interface.  This
89    list is useful for saving automatically updated variables that are not
90    minibuffer histories, such as `compile-command' or `kill-ring'."
91      :type '(repeat variable)
92    :group 'savehist)    :group 'savehist)
93    
94  (defcustom savehist-file "~/.emacs-history"  (defcustom savehist-file
95    "File name to save minibuffer history to.    (cond
96  The minibuffer history is a series of Lisp expressions, which should be     ;; Backward compatibility with previous versions of savehist.
97  loaded using `savehist-load' from your .emacs.  See `savehist-load' for     ((file-exists-p "~/.emacs-history") "~/.emacs-history")
98  more details."     ((and (not (featurep 'xemacs)) (file-directory-p "~/.emacs.d/"))
99        "~/.emacs.d/history")
100       ((and (featurep 'xemacs) (file-directory-p "~/.xemacs/"))
101        "~/.xemacs/history")
102       ;; For users without `~/.emacs.d/' or `~/.xemacs/'.
103       (t "~/.emacs-history"))
104      "*File name where minibuffer history is saved to and loaded from.
105    The minibuffer history is a series of Lisp expressions loaded
106    automatically when `savehist-mode' is turned on.  See `savehist-mode'
107    for more details.
108    
109    If you want your minibuffer history shared between Emacs and XEmacs,
110    customize this value and make sure that `savehist-coding-system' is
111    set to a coding system that exists in both emacsen."
112    :type 'file    :type 'file
113    :group 'savehist)    :group 'savehist)
114    
115  (defcustom savehist-length 100  (defcustom savehist-file-modes #o600
116    "Maximum length of a minibuffer list.    "*Default permissions of the history file.
 Minibuffer histories with more entries are trimmed when saved, the older  
 entries being removed first.  If set to nil, the length is unlimited."  
   :type '(choice integer  
                  (const :tag "Unlimited" nil))  
   :group 'savehist)  
   
 (defcustom savehist-modes #o600  
   "Default permissions of the history file.  
117  This is decimal, not octal.  The default is 384 (0600 in octal).  This is decimal, not octal.  The default is 384 (0600 in octal).
118  Set to nil to use the default permissions that Emacs uses, typically  Set to nil to use the default permissions that Emacs uses, typically
119  mandated by umask.  The default is a bit more restrictive to protect  mandated by umask.  The default is a bit more restrictive to protect
# Line 96  the user's privacy." Line 122  the user's privacy."
122    :group 'savehist)    :group 'savehist)
123    
124  (defcustom savehist-autosave-interval (* 5 60)  (defcustom savehist-autosave-interval (* 5 60)
125    "The interval during which savehist should autosave the history buffer."    "*The interval between autosaves of minibuffer history.
126    If set to nil, disables timer-based autosaving."
127    :type 'integer    :type 'integer
128    :group 'savehist)    :group 'savehist)
129    
130  (defvar savehist-coding-system  (defcustom savehist-save-hook nil
131    ;; UTF-8 is usually preferable to ISO-2022-8 when available, but under    "Hook called by savehist-save before saving the variables.
132    ;; XEmacs, UTF-8 is provided by external packages, and may not always be  You can use this hook to influence choice and content of variables to
133    ;; available, so even if it currently is available, we prefer not to  save."
134    ;; use is.    :type 'hook)
135    (if (featurep 'xemacs) 'iso-2022-8 'utf-8)  
136    (defvar savehist-coding-system (if (featurep 'xemacs) 'iso-2022-8 'utf-8)
137    "The coding system savehist uses for saving the minibuffer history.    "The coding system savehist uses for saving the minibuffer history.
138  Changing this value while Emacs is running is supported, but considered  Changing this value while Emacs is running is supported, but considered
139  unwise, unless you know what you are doing.")  unwise, unless you know what you are doing.")
# Line 116  unwise, unless you know what you are doi Line 144  unwise, unless you know what you are doi
144    
145  (defvar savehist-last-checksum nil)  (defvar savehist-last-checksum nil)
146    
147  (defvar savehist-minibuffer-history-variables nil)  (defvar savehist-minibuffer-history-variables nil
148      "List of minibuffer histories.
149    The contents of this variable is built while Emacs is running, and saved
150    along with minibuffer history.  You can change its value off
151    `savehist-save-hook' to influence which variables are saved.")
152    
153    ;; Coding system without any conversion, used for calculating an
154    ;; internal checksum.  Should be as fast as possible, ideally simply
155    ;; exposing the internal representation of buffer text.
156    (defconst savehist-no-conversion (if (featurep 'xemacs) 'binary 'no-conversion))
157    
158    ;; Whether the history has already been loaded.  This prevents
159    ;; toggling savehist-mode from destroying existing minibuffer history.
160    (defvar savehist-loaded nil)
161    
162  (defconst savehist-no-conversion (if (featurep 'xemacs) 'binary 'no-conversion)  (eval-when-compile
163    "Coding system without conversion, only used for calculating checksums.    (when (featurep 'xemacs)
164  It should be as discriminating as `savehist-coding-system' but faster.")      ;; Must declare this under XEmacs, which doesn't have built-in
165        ;; minibuffer history truncation.
166        (defvar history-length 100)))
167    
168  ;; Functions.  ;; Functions.
169    
170    ;;;###autoload
171    (defun savehist-mode (arg)
172      "Toggle savehist-mode.
173    Positive ARG turns on `savehist-mode'.  When on, savehist-mode causes
174    minibuffer history to be saved periodically and when exiting Emacs.
175    When turned on for the first time in an Emacs session, it causes the
176    previous minibuffer history to be loaded from `savehist-file'.
177    
178    This mode should normally be turned on from your Emacs init file.
179    Calling it at any other time replaces your current minibuffer histories,
180    which is probably undesirable."
181      (interactive "P")
182      (setq savehist-mode
183            (if (null arg)
184                (not savehist-mode)
185              (> (prefix-numeric-value arg) 0)))
186      (if (not savehist-mode)
187          (savehist-uninstall)
188        (when (and (not savehist-loaded)
189                   (file-exists-p savehist-file))
190          (condition-case errvar
191              (progn
192                ;; Don't set coding-system-for-read -- we rely on the
193                ;; coding cookie to convey that information.  That way, if
194                ;; the user changes the value of savehist-coding-system,
195                ;; we can still correctly load the old file.
196                (load savehist-file nil (not (interactive-p)))
197                (setq savehist-loaded t))
198            (error
199             ;; Don't install the mode if reading failed.  Doing so would
200             ;; effectively destroy the user's data at the next save.
201             (setq savehist-mode nil)
202             (savehist-uninstall)
203             (signal (car errvar) (cdr errvar)))))
204        (savehist-install)))
205    (add-minor-mode 'savehist-mode "")
206    
207    (defun savehist-load ()
208      "Obsolete function provided for transition from old versions of savehist.
209    Don't call this from new code, use (savehist-mode 1) instead.
210    
211    This function loads the variables stored in `savehist-file' and turns on
212    savehist-mode.  If savehist-file is in the old format that doesn't record
213    the value of `savehist-minibuffer-history-variables', that value is
214    deducted from the contents of the file."
215      (savehist-mode 1)
216      ;; Old versions of savehist distributed with XEmacs didn't save
217      ;; savehist-minibuffer-history-variables.  If that variable is nil
218      ;; after loading the file, try to intuit the intended value.
219      (when (null savehist-minibuffer-history-variables)
220        (setq savehist-minibuffer-history-variables
221              (with-temp-buffer
222                (ignore-errors
223                  (insert-file-contents savehist-file))
224                (let ((vars ()) form)
225                  (while (setq form (condition-case nil
226                                        (read (current-buffer)) (error nil)))
227                    ;; Each form read is of the form (setq VAR VALUE).
228                    ;; Collect VAR, i.e. (nth form 1).
229                    (push (nth 1 form) vars))
230                  vars)))))
231    (make-obsolete 'savehist-load 'savehist-mode)
232    
233  (defun savehist-install ()  (defun savehist-install ()
234    "Hook savehist into Emacs.    "Hook savehist into Emacs.
235  This will install `savehist-autosave' in `kill-emacs-hook' and on a timer.  Normally invoked by calling `savehist-mode' to set the minor mode.
236  To undo this, call `savehist-uninstall'."  Installs `savehist-autosave' in `kill-emacs-hook' and on a timer.   To
237    undo this, call `savehist-uninstall'."
238    (add-hook 'minibuffer-setup-hook 'savehist-minibuffer-hook)    (add-hook 'minibuffer-setup-hook 'savehist-minibuffer-hook)
239    (add-hook 'kill-emacs-hook 'savehist-autosave)    (add-hook 'kill-emacs-hook 'savehist-autosave)
240    ;; Install an invocation of savehist-autosave on a timer.  This    ;; Install an invocation of savehist-autosave on a timer.  This
241    ;; should not cause noticeable delays for users -- savehist-autosave    ;; should not cause noticeable delays for users -- savehist-autosave
242    ;; executes in under 5 ms on my system.    ;; executes in under 5 ms on my system.
243    (unless savehist-timer    (when (and savehist-autosave-interval
244                 (null savehist-timer))
245      (setq savehist-timer      (setq savehist-timer
246            (if (featurep 'xemacs)            (if (featurep 'xemacs)
247                (start-itimer                (start-itimer
248                 "savehist" 'savehist-autosave savehist-autosave-interval                 "savehist" 'savehist-autosave savehist-autosave-interval
249                 savehist-autosave-interval)                 savehist-autosave-interval)
250              (run-with-timer savehist-autosave-interval savehist-autosave-interval              (run-with-timer savehist-autosave-interval
251                              'savehist-autosave)))))                              savehist-autosave-interval 'savehist-autosave)))))
252    
253  (defun savehist-uninstall ()  (defun savehist-uninstall ()
254    "Undo installing savehist."    "Undo installing savehist.
255    Normally invoked by calling `savehist-mode' to unset the minor mode."
256    (remove-hook 'minibuffer-setup-hook 'savehist-minibuffer-hook)    (remove-hook 'minibuffer-setup-hook 'savehist-minibuffer-hook)
257    (remove-hook 'kill-emacs-hook 'savehist-autosave)    (remove-hook 'kill-emacs-hook 'savehist-autosave)
258    (when savehist-timer    (when savehist-timer
# Line 152  To undo this, call `savehist-uninstall'. Line 261  To undo this, call `savehist-uninstall'.
261        (cancel-timer savehist-timer))        (cancel-timer savehist-timer))
262      (setq savehist-timer nil)))      (setq savehist-timer nil)))
263    
 ;;;###autoload  
 (defun savehist-load (&optional no-install)  
   "Load the minibuffer histories from `savehist-file'.  
 Unless NO-INSTALL is present and non-nil, the function will also install  
 `savehist-autosave' in `kill-emacs-hook' and on a timer, ensuring that  
 history is saved before leaving Emacs.  
   
 This function should be normally used from your Emacs init file.  Since  
 it removes your current minibuffer histories, it is unwise to call it at  
 any other time."  
   (interactive "P")  
   ;; Don't set coding-system-for-read here.  We rely on autodetection  
   ;; and the coding cookie to convey that information.  That way, if  
   ;; the user changes the value of savehist-coding-system, we can  
   ;; still correctly load the old file.  
   (load savehist-file t (not (interactive-p)))  
   (unless no-install  
     (savehist-install)))  
   
 ;;;###autoload  
264  (defun savehist-save (&optional auto-save)  (defun savehist-save (&optional auto-save)
265    "Save the values of minibuffer history variables.    "Save the values of minibuffer history variables.
266  Unbound symbols referenced in `savehist-additional-variables' are ignored.  Unbound symbols referenced in `savehist-additional-variables' are ignored.
# Line 182  If AUTO-SAVE is non-nil, compare the sav Line 271  If AUTO-SAVE is non-nil, compare the sav
271      (insert      (insert
272       (format ";; -*- mode: emacs-lisp; coding: %s -*-\n" savehist-coding-system)       (format ";; -*- mode: emacs-lisp; coding: %s -*-\n" savehist-coding-system)
273       ";; Minibuffer history file, automatically generated by `savehist'.\n\n")       ";; Minibuffer history file, automatically generated by `savehist'.\n\n")
274        (run-hooks 'savehist-save-hook)
275      (let ((print-length nil)      (let ((print-length nil)
276            (print-string-length nil)            (print-string-length nil)
277            (print-level nil)            (print-level nil)
278            (print-readably t)            (print-readably t)
279            (print-quoted t)            (print-quoted t))
280            (symbol-list (append        ;; Save the minibuffer histories, along with the value of
281                          (and savehist-save-minibuffer-history        ;; savehist-minibuffer-history-variables itself.
282                               (cons 'savehist-minibuffer-history-variables        (when savehist-save-minibuffer-history
283                                     savehist-minibuffer-history-variables))          (prin1 `(setq savehist-minibuffer-history-variables
284                          savehist-additional-variables)))                        ',savehist-minibuffer-history-variables)
285        (dolist (sym symbol-list)                 (current-buffer))
286          (when (boundp sym)          (insert ?\n)
287            (let ((value (savehist-process-for-saving (symbol-value sym))))          (dolist (symbol savehist-minibuffer-history-variables)
288              (prin1 `(setq ,sym ',value) (current-buffer))            (when (boundp symbol)
289              (insert ?\n)))))              (let ((value (savehist-trim-history (symbol-value symbol))))
290                  (when value               ; don't save empty histories
291                    (prin1 `(setq ,symbol ',value) (current-buffer))
292                    (insert ?\n))))))
293          ;; Save the additional variables.
294          (dolist (symbol savehist-additional-variables)
295            (when (boundp symbol)
296              (let ((value (symbol-value symbol)))
297                (when (savehist-printable value)
298                  (prin1 `(setq ,symbol ',value) (current-buffer))
299                  (insert ?\n))))))
300      ;; If autosaving, avoid writing if nothing has changed since the      ;; If autosaving, avoid writing if nothing has changed since the
301      ;; last write.      ;; last write.
302      (let ((checksum (md5 (current-buffer) nil nil savehist-no-conversion)))      (let ((checksum (md5 (current-buffer) nil nil savehist-no-conversion)))
# Line 210  If AUTO-SAVE is non-nil, compare the sav Line 310  If AUTO-SAVE is non-nil, compare the sav
310                (coding-system-for-write savehist-coding-system))                (coding-system-for-write savehist-coding-system))
311            (write-region (point-min) (point-max) savehist-file nil            (write-region (point-min) (point-max) savehist-file nil
312                          (unless (interactive-p) 'quiet)))                          (unless (interactive-p) 'quiet)))
313          (when savehist-modes          (when savehist-file-modes
314            (set-file-modes savehist-file savehist-modes))            (set-file-modes savehist-file savehist-file-modes))
315          (setq savehist-last-checksum checksum)))))          (setq savehist-last-checksum checksum)))))
316    
317  (defun savehist-autosave ()  (defun savehist-autosave ()
318    "Save the minibuffer history if it has been modified since the last save."    "Save the minibuffer history if it has been modified since the last save.
319    (savehist-save t))  Does nothing if savehist-mode is off."
320      (when savehist-mode
321  (defun savehist-process-for-saving (value)      (savehist-save t)))
322    ;; Process VALUE for saving to file.  If it is a list, retain only  
323    ;; the first `savehist-length' values and prune non-printable ones.  (defun savehist-trim-history (value)
324    ;; If VALUE is not a list, return it as-is if it is printable and    ;; Retain only the first history-length items in VALUE.  Only used
325    ;; nil otherwise.    ;; under XEmacs, which doesn't (yet) implement automatic trimming of
326    (cond    ;; history lists to history-length items.
327     ((listp value)    (if (and (featurep 'xemacs)
328      (when (and savehist-length (> (length value) savehist-length))             (natnump history-length)
329        ;; This should be: (setq value (subseq value 0 savehist-length))             (> (length value) history-length))
330        (setq value (copy-sequence value))        ;; Equivalent to `(subseq value 0 history-length)', but doesn't
331        (setcdr (nthcdr savehist-length value) nil))        ;; need cl-extra at run-time.
332      ;; And this should be (remove-if-not #'savehist-printable value)        (loop repeat history-length collect (pop value))
333      (delq nil (mapcar (lambda (x) (if (savehist-printable x) x)) value)))      value))
    ((savehist-printable value) value)  
    (t nil)))  
334    
335  (defun savehist-printable (value)  (defun savehist-printable (value)
336    "Return non-nil if VALUE is printable."    "Return non-nil if VALUE is printable."
   ;; Quick response for oft-encountered types known to be printable.  
337    (cond    (cond
338       ;; Quick response for oft-encountered types known to be printable.
339     ((stringp value))     ((stringp value))
340     ((numberp value))     ((numberp value))
341     ((symbolp value))     ((symbolp value))
342     (t     (t
343      ;; For others, check explicitly.      ;; For others, check explicitly.
344      (condition-case nil      (with-temp-buffer
345          (let ((print-readably t)        (condition-case nil
346                (print-level nil)            (let ((print-readably t) (print-level nil))
347                (chars ()))            ;; Print the value into a buffer...
348            ;; Print the value into a string...            (prin1 value (current-buffer))
           (prin1 value (lambda (char) (push char chars)))  
349            ;; ...and attempt to read it.            ;; ...and attempt to read it.
350            (read (apply #'string (nreverse chars)))            (read (point-min-marker))
351            ;; The attempt worked: the object is printable.            ;; The attempt worked: the object is printable.
352            t)            t)
353        ;; The attempt failed: the object is not printable.          ;; The attempt failed: the object is not printable.
354        (error nil)))))          (error nil))))))
355    
356  (defun savehist-minibuffer-hook ()  (defun savehist-minibuffer-hook ()
357    (add-to-list 'savehist-minibuffer-history-variables    (add-to-list 'savehist-minibuffer-history-variables
358                 minibuffer-history-variable))                 minibuffer-history-variable))
359    
360  (provide 'savehist)  (provide 'savehist)
361    
362  ;; arch-tag: b3ce47f4-c5ad-4ebc-ad02-73aba705cf9f  ;; arch-tag: b3ce47f4-c5ad-4ebc-ad02-73aba705cf9f
363    
364  ;;; savehist.el ends here  ;;; savehist.el ends here

Legend:
Removed from v.1.8  
changed lines
  Added in v.1.9

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26