1 ;;; savehist.el --- Save minibuffer history.
3 ;; Copyright (C) 1997, 2005 Free Software Foundation
5 ;; Author: Hrvoje Niksic <hniksic@xemacs.org>
6 ;; Keywords: minibuffer
9 ;; This file is part of GNU Emacs.
11 ;; GNU Emacs is free software; you can redistribute it and/or modify
12 ;; it under the terms of the GNU General Public License as published by
13 ;; the Free Software Foundation; either version 2, or (at your option)
16 ;; GNU Emacs is distributed in the hope that it will be useful,
17 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 ;; GNU General Public License for more details.
21 ;; You should have received a copy of the GNU General Public License
22 ;; along with GNU Emacs; see the file COPYING. If not, write to the
23 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24 ;; Boston, MA 02110-1301, USA.
28 ;; Many editors (e.g. Vim) have the feature of saving minibuffer
29 ;; history to an external file after exit. This package provides the
30 ;; same feature in Emacs. When Emacs is about the exit,
31 ;; `savehist-save' will dump the contents of various minibuffer
32 ;; histories (as determined by `savehist-history-variables') to a save
33 ;; file (`~/.emacs-history' by default). Although the package was
34 ;; designed for saving the minibuffer histories, any variables can be
37 ;; To use savehist, put the following to `~/.emacs':
39 ;; (require 'savehist)
42 ;; Be sure to have `savehist.el' in a directory that is in your
43 ;; load-path, and byte-compile it.
51 (defgroup savehist nil
52 "Save minibuffer history."
55 (defcustom savehist-history-variables
57 ;; Catch-all minibuffer history
59 ;; File-oriented commands
61 ;; Regexp-related reads
63 ;; Searches in minibuffer (via `M-r' and such)
64 minibuffer-history-search-history
67 ;; eval-expression (`M-:')
68 read-expression-history
69 ;; shell-command (`M-!')
79 vip-ex-history vip-search-history
80 vip-replace1-history vip-replace2-history
81 vip-shell-history vip-search-history
84 ;; Buffer-related commands
86 ;; Reads of variables and functions
87 variable-history function-history
91 ;; Info, lookup, and bookmark historys
92 Info-minibuffer-history
94 Manual-page-minibuffer-history
98 extended-command-history
)
99 "*List of symbols to be saved.
100 Every symbol should refer to a variable. The variable will be saved
101 only if it is bound and has a non-nil value. Thus it is safe to
102 specify a superset of the variables a user is expected to want to
105 Default value contains minibuffer history variables used by Emacs, XEmacs,
106 and Viper (uh-oh). Note that, if you customize this variable, you
107 can lose the benefit of future versions of Emacs adding new values to
108 the list. Because of that it might be more useful to add values using
110 :type
'(repeat (symbol :tag
"Variable"))
113 (defcustom savehist-file
"~/.emacs-history"
114 "*File name to save minibuffer history to.
115 The minibuffer history is a series of Lisp expressions, which should be
116 loaded using `savehist-load' from your .emacs. See `savehist-load' for
121 (defcustom savehist-length
100
122 "*Maximum length of a minibuffer list.
123 If set to nil, the length is unlimited."
124 :type
'(choice integer
125 (const :tag
"Unlimited" nil
))
128 (defcustom savehist-modes
#o600
129 "*Default permissions of the history file.
130 This is decimal, not octal. The default is 384 (0600 in octal).
131 Set to nil to use the default permissions that Emacs uses, typically
132 mandated by umask. The default is a bit more restrictive to protect
137 (defcustom savehist-autosave-interval
(* 5 60)
138 "*The interval during which savehist should autosave the history buffer."
142 (defvar savehist-coding-system
143 ;; UTF-8 is usually preferable to ISO-2022-8 when available, but under
144 ;; XEmacs, UTF-8 is provided by external packages, and may not always be
145 ;; available, so even if it currently is available, we prefer not to
147 (if (featurep 'xemacs
) 'iso-2022-8
'utf-8
)
148 "The coding system savehist uses for saving the minibuffer history.
149 Changing this value while Emacs is running is supported, but considered
150 unwise, unless you know what you are doing.")
152 ;; Internal variables.
154 (defvar savehist-timer nil
)
156 (defvar savehist-last-checksum nil
)
158 (defconst savehist-no-conversion
(if (featurep 'xemacs
) 'binary
'no-conversion
)
159 ;; FIXME: Why not use savehist-coding-system?
160 "Coding system without conversion, only used for calculating checksums.")
165 (defun savehist-load (&optional no-hook
)
166 "Load the minibuffer histories from `savehist-file'.
167 Unless NO-HOOK is specified, the function will also add the save function
168 to `kill-emacs-hook' and on a timer, ensuring that the minibuffer contents
169 will be saved before leaving Emacs.
171 This function should be normally used from your Emacs init file. Since it
172 removes your current minibuffer histories, it is unwise to call it at any
176 (add-hook 'kill-emacs-hook
'savehist-autosave
)
177 ;; Install an invocation of savehist-autosave on a timer. This
178 ;; should not cause a noticeable delay -- savehist-autosave
179 ;; executes in under 5 ms on my system.
180 (unless savehist-timer
182 (if (featurep 'xemacs
)
184 "savehist" 'savehist-autosave savehist-autosave-interval
185 savehist-autosave-interval
)
186 (run-with-idle-timer savehist-autosave-interval savehist-autosave-interval
187 'savehist-autosave
)))))
188 ;; Don't set coding-system-for-read here. We rely on autodetection
189 ;; and the coding cookie to convey that information. That way, if
190 ;; the user changes the value of savehist-coding-system, we can
191 ;; still correctly load the old file.
192 (load savehist-file t
(not (interactive-p))))
195 (defun savehist-save (&optional auto-save
)
196 "Save the histories from `savehist-history-variables' to `savehist-file'.
197 Unbound symbols referenced in `savehist-history-variables' are ignored.
198 If AUTO-SAVE is non-nil, compare the saved contents to the one last saved,
199 and don't save the buffer if they are the same."
203 (format ";; -*- mode: emacs-lisp; coding: %s -*-\n" savehist-coding-system
)
204 ";; Minibuffer history file, automatically generated by `savehist'.\n\n")
205 (let ((print-length nil
)
206 (print-string-length nil
)
210 (dolist (sym savehist-history-variables
)
212 (let ((value (savehist-process-for-saving (symbol-value sym
))))
213 (prin1 `(setq ,sym
',value
) (current-buffer))
215 ;; If autosaving, avoid writing if nothing has changed since the
217 (let ((checksum (md5 (current-buffer) nil nil savehist-no-conversion
)))
218 (unless (and auto-save
(equal checksum savehist-last-checksum
))
219 ;; Set file-precious-flag when saving the buffer because we
220 ;; don't want a half-finished write ruining the entire
221 ;; history. (Remember that this is run from a timer and from
223 (let ((file-precious-flag t
)
224 (coding-system-for-write savehist-coding-system
))
225 (write-region (point-min) (point-max) savehist-file nil
226 (unless (interactive-p) 'quiet
)))
228 (set-file-modes savehist-file savehist-modes
))
229 (setq savehist-last-checksum checksum
)))))
231 (defun savehist-autosave ()
232 "Save the minibuffer history if it has been modified since the last save."
235 (defun savehist-process-for-saving (value)
236 ;; Process VALUE for saving to file. If it is a list, retain only
237 ;; the first `savehist-length' values and prune non-printable ones.
238 ;; If VALUE is not a list, return it as-is if it is printable and
242 (when (and savehist-length
(> (length value
) savehist-length
))
243 ;; This should be: (setq value (subseq value 0 savehist-length))
244 (setq value
(copy-sequence value
))
245 (setcdr (nthcdr savehist-length value
) nil
))
246 ;; And this should be (remove-if-not #'savehist-printable value)
247 (delq nil
(mapcar (lambda (x) (if (savehist-printable x
) x
)) value
)))
248 ((savehist-printable value
) value
)
251 (defun savehist-printable (value)
252 "Return non-nil if VALUE is printable."
253 ;; Quick response for oft-encountered types known to be printable.
259 ;; For others, check explicitly.
261 (let ((print-readably t
)
264 ;; Print the value into a string...
265 (prin1 value
(lambda (char) (push char chars
)))
266 ;; ...and attempt to read it.
267 (read (apply #'string
(nreverse chars
)))
268 ;; The attempt worked: the object is printable.
270 ;; The attempt failed: the object is not printable.
275 ;; arch-tag: b3ce47f4-c5ad-4ebc-ad02-73aba705cf9f
276 ;;; savehist.el ends here