* mh-init.el (mh-image-load-path): Remove use of pushnew since it
[bpt/emacs.git] / lisp / savehist.el
CommitLineData
216ee1a4 1;;; savehist.el --- Save minibuffer history.
cb23c7c1 2
216ee1a4 3;; Copyright (C) 1997, 2005 Free Software Foundation
cb23c7c1
RS
4
5;; Author: Hrvoje Niksic <hniksic@xemacs.org>
6;; Keywords: minibuffer
216ee1a4 7;; Version: 7
cb23c7c1
RS
8
9;; This file is part of GNU Emacs.
10
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)
14;; any later version.
15
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.
20
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.
25
26;;; Commentary:
27
216ee1a4
SM
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,
cb23c7c1
RS
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
35;; saved that way.
36
37;; To use savehist, put the following to `~/.emacs':
38;;
39;; (require 'savehist)
40;; (savehist-load)
41
42;; Be sure to have `savehist.el' in a directory that is in your
43;; load-path, and byte-compile it.
216ee1a4 44
cb23c7c1
RS
45;;; Code:
46
216ee1a4 47(require 'custom)
216ee1a4 48
cb23c7c1
RS
49;; User variables
50
51(defgroup savehist nil
52 "Save minibuffer history."
53 :group 'minibuffer)
54
cb23c7c1
RS
55(defcustom savehist-history-variables
56 '(
57 ;; Catch-all minibuffer history
58 minibuffer-history
59 ;; File-oriented commands
60 file-name-history
61 ;; Regexp-related reads
62 regexp-history
63 ;; Searches in minibuffer (via `M-r' and such)
64 minibuffer-history-search-history
65 ;; Query replace
66 query-replace-history
67 ;; eval-expression (`M-:')
68 read-expression-history
69 ;; shell-command (`M-!')
70 shell-command-history
71 ;; compile
72 compile-history
73 ;; find-tag (`M-.')
74 find-tag-history
75 ;; grep
76 grep-history
77 ;; Viper stuff
78 vip-ex-history vip-search-history
79 vip-replace1-history vip-replace2-history
80 vip-shell-history vip-search-history
81
82 ;; XEmacs-specific:
83 ;; Buffer-related commands
84 buffer-history
85 ;; Reads of variables and functions
86 variable-history function-history
87 ;; Extended commands
88 read-command-history
89
90 ;; Info, lookup, and bookmark historys
91 Info-minibuffer-history
216ee1a4 92 Info-search-history
cb23c7c1
RS
93 Manual-page-minibuffer-history
94
95 ;; Emacs-specific:
96 ;; Extended commands
97 extended-command-history)
98 "*List of symbols to be saved.
99Every symbol should refer to a variable. The variable will be saved
100only if it is bound and has a non-nil value. Thus it is safe to
101specify a superset of the variables a user is expected to want to
102save.
103
216ee1a4
SM
104Default value contains minibuffer history variables used by Emacs, XEmacs,
105and Viper (uh-oh). Note that, if you customize this variable, you
106can lose the benefit of future versions of Emacs adding new values to
107the list. Because of that it might be more useful to add values using
108`add-to-list'."
cb23c7c1
RS
109 :type '(repeat (symbol :tag "Variable"))
110 :group 'savehist)
111
112(defcustom savehist-file "~/.emacs-history"
113 "*File name to save minibuffer history to.
114The minibuffer history is a series of Lisp expressions, which should be
115loaded using `savehist-load' from your .emacs. See `savehist-load' for
116more details."
117 :type 'file
118 :group 'savehist)
119
120(defcustom savehist-length 100
121 "*Maximum length of a minibuffer list.
122If set to nil, the length is unlimited."
123 :type '(choice integer
124 (const :tag "Unlimited" nil))
125 :group 'savehist)
126
216ee1a4 127(defcustom savehist-modes #o600
cb23c7c1 128 "*Default permissions of the history file.
216ee1a4
SM
129This is decimal, not octal. The default is 384 (0600 in octal).
130Set to nil to use the default permissions that Emacs uses, typically
131mandated by umask. The default is a bit more restrictive to protect
132the user's privacy."
cb23c7c1
RS
133 :type 'integer
134 :group 'savehist)
135
216ee1a4
SM
136(defcustom savehist-autosave-interval (* 5 60)
137 "*The interval during which savehist should autosave the history buffer."
138 :type 'integer
139 :group 'savehist)
140
3930b7e4 141(defvar savehist-coding-system (if (coding-system-p 'utf-8) 'utf-8 'iso-2022-8)
216ee1a4
SM
142 "The coding system savehist uses for saving the minibuffer history.
143Changing this value while Emacs is running is supported, but considered
144unwise, unless you know what you are doing.")
145
146;; Internal variables.
147
148(defvar savehist-timer nil)
149
150(defvar savehist-last-checksum nil)
151
3930b7e4
SM
152(defconst savehist-no-conversion (if (featurep 'xemacs) 'binary 'no-conversion)
153 ;; FIXME: Why not use savehist-coding-system?
154 "Coding system without conversion, only used for calculating checksums.")
cb23c7c1
RS
155\f
156;; Functions
157
158;;;###autoload
159(defun savehist-load (&optional no-hook)
160 "Load the minibuffer histories from `savehist-file'.
161Unless NO-HOOK is specified, the function will also add the save function
216ee1a4
SM
162to `kill-emacs-hook' and on a timer, ensuring that the minibuffer contents
163will be saved before leaving Emacs.
cb23c7c1
RS
164
165This function should be normally used from your Emacs init file. Since it
166removes your current minibuffer histories, it is unwise to call it at any
167other time."
168 (interactive "P")
169 (unless no-hook
216ee1a4
SM
170 (add-hook 'kill-emacs-hook 'savehist-autosave)
171 ;; Install an invocation of savehist-autosave on a timer. This
172 ;; should not cause a noticeable delay -- savehist-autosave
173 ;; executes in under 5 ms on my system.
174 (unless savehist-timer
175 (setq savehist-timer
3930b7e4 176 (if (fboundp 'start-itimer)
216ee1a4
SM
177 (start-itimer
178 "savehist" 'savehist-autosave savehist-autosave-interval
179 savehist-autosave-interval)
3930b7e4
SM
180 (run-with-idle-timer savehist-autosave-interval savehist-autosave-interval
181 'savehist-autosave)))))
216ee1a4
SM
182 ;; Don't set coding-system-for-read here. We rely on autodetection
183 ;; and the coding cookie to convey that information. That way, if
184 ;; the user changes the value of savehist-coding-system, we can
185 ;; still correctly load the old file.
186 (load savehist-file t (not (interactive-p))))
cb23c7c1
RS
187
188;;;###autoload
216ee1a4 189(defun savehist-save (&optional auto-save)
cb23c7c1 190 "Save the histories from `savehist-history-variables' to `savehist-file'.
216ee1a4
SM
191Unbound symbols referenced in `savehist-history-variables' are ignored.
192If AUTO-SAVE is non-nil, compare the saved contents to the one last saved,
193 and don't save the buffer if they are the same."
cb23c7c1 194 (interactive)
216ee1a4
SM
195 (with-temp-buffer
196 (insert
197 (format ";; -*- mode: emacs-lisp; coding: %s -*-\n" savehist-coding-system)
198 ";; Minibuffer history file, automatically generated by `savehist'.\n\n")
199 (let ((print-length nil)
200 (print-string-length nil)
201 (print-level nil)
202 (print-readably t)
203 (print-quoted t))
204 (dolist (sym savehist-history-variables)
205 (when (boundp sym)
206 (let ((value (savehist-process-for-saving (symbol-value sym))))
207 (prin1 `(setq ,sym ',value) (current-buffer))
208 (insert ?\n)))))
209 ;; If autosaving, avoid writing if nothing has changed since the
210 ;; last write.
211 (let ((checksum (md5 (current-buffer) nil nil savehist-no-conversion)))
212 (unless (and auto-save (equal checksum savehist-last-checksum))
213 ;; Set file-precious-flag when saving the buffer because we
214 ;; don't want a half-finished write ruining the entire
215 ;; history. (Remember that this is run from a timer and from
216 ;; kill-emacs-hook.)
217 (let ((file-precious-flag t)
218 (coding-system-for-write savehist-coding-system))
219 (write-region (point-min) (point-max) savehist-file nil
220 (unless (interactive-p) 'quiet)))
221 (when savehist-modes
222 (set-file-modes savehist-file savehist-modes))
223 (setq savehist-last-checksum checksum)))))
224
225(defun savehist-autosave ()
226 "Save the minibuffer history if it has been modified since the last save."
227 (savehist-save t))
228
229(defun savehist-process-for-saving (value)
230 ;; Process VALUE for saving to file. If it is a list, retain only
231 ;; the first `savehist-length' values and prune non-printable ones.
232 ;; If VALUE is not a list, return it as-is if it is printable and
233 ;; nil otherwise.
234 (cond
235 ((listp value)
236 (when (and savehist-length (> (length value) savehist-length))
3930b7e4
SM
237 (setq value (copy-sequence value))
238 (setcdr (nthcdr savehist-length value) nil))
239 (delq nil (mapcar (lambda (x) (if (savehist-printable x) x)) value)))
216ee1a4
SM
240 ((savehist-printable value) value)
241 (t nil)))
242
243(defun savehist-printable (value)
3930b7e4 244 "Return non-nil if VALUE is printable."
216ee1a4
SM
245 ;; Quick response for oft-encountered types known to be printable.
246 (cond
247 ((stringp value))
248 ((numberp value))
249 ((symbolp value))
250 (t
251 ;; For others, check explicitly.
252 (condition-case nil
253 (let ((print-readably t)
254 (print-level nil)
255 (chars ()))
256 ;; Print the value into a string...
257 (prin1 value (lambda (char) (push char chars)))
258 ;; ...and attempt to read it.
259 (read (apply #'string (nreverse chars)))
260 ;; The attempt worked: the object is printable.
261 t)
262 ;; The attempt failed: the object is not printable.
263 (error nil)))))
cb23c7c1
RS
264
265(provide 'savehist)
266
267;;; savehist.el ends here