annotate lisp/dired/gmhist.el @ 9:6f2bbbbbe05a

Added tag r19-15b5 for changeset 4b173ad71786
author cvs
date Mon, 13 Aug 2007 08:47:36 +0200
parents 376386a54a3c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1 ;;;; gmhist.el - Provide generic minibuffer history for commands
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
2
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
3 (defconst gmhist-version (substring "!Revision: 4.27 !" 11 -2)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
4 "Id: gmhist.el,v 4.27 1992/04/20 17:17:47 sk RelBeta
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
5 Report bugs to Sebastian Kremer <sk@thp.uni-koeln.de>.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
6
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
7 ;; Copyright (C) 1990 by Sebastian Kremer <sk@thp.uni-koeln.de>
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
8
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
9 ;; This program is free software; you can redistribute it and/or modify
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
10 ;; it under the terms of the GNU General Public License as published by
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
11 ;; the Free Software Foundation; either version 1, or (at your option)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
12 ;; any later version.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
13 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
14 ;; This program is distributed in the hope that it will be useful,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
15 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
16 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
17 ;; GNU General Public License for more details.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
18 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
19 ;; You should have received a copy of the GNU General Public License
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
20 ;; along with this program; if not, write to the Free Software
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
21 ;; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
22
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
23 ;; LISPDIR ENTRY for the Elisp Archive ===============================
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
24 ;; LCD Archive Entry:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
25 ;; gmhist|Sebastian Kremer|sk@thp.uni-koeln.de
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
26 ;; |Generic minibuffer history package.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
27 ;; |Date: 1992/04/20 17:17:47 |Revision: 4.27 |
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
28
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
29 ;; INSTALLATION ======================================================
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
30 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
31 ;; Put this file into your load-path and the following in your
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
32 ;; ~/.emacs:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
33 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
34 ;; (autoload 'read-with-history-in "gmhist")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
35 ;; (autoload 'read-file-name-with-history-in "gmhist")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
36 ;; (autoload 'completing-read-with-history-in "gmhist")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
37 ;; (autoload 'gmhist-make-magic "gmhist" nil t)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
38
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
39 ;; USAGE =============================================================
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
40 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
41 ;; - as an Elisp programmer: use functions read-with-history-in,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
42 ;; completing-read-with-history-in, read-file-name-with-history-in or
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
43 ;; gmhist-interactive inside the interactive clause of your functions
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
44 ;; instead of a string specification. See the examples at the end of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
45 ;; the file.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
46 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
47 ;; - as an Emacs user: To provide `simple' functions with history,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
48 ;; just type M-x gmhist-make-magic and enter the name of the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
49 ;; function, e.g., `eval-expression'. This function's arguments
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
50 ;; are then remembered across calls and are available by typing
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
51 ;; M-p to the minibuffer prompt of the function. More history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
52 ;; commands are mentioned in the documentation of variable
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
53 ;; gmhist-map.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
54 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
55 ;; Type M-x gmhist-remove-magic to restore the function's old
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
56 ;; interactive behaviour.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
57 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
58 ;; `Simple' functions are those that prompt for strings, file
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
59 ;; names or lisp objects and perhaps use prefix args and the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
60 ;; region. See the file gmhist-app.el for examples with simple
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
61 ;; and other functions.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
62
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
63 ;; I'd like to thank Jamie Zawinski, Piet van Oostrum and Mike
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
64 ;; Williams for very helpful feedback and ideas.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
65
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
66
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
67 (provide 'gmhist)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
68
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
69 ;; Emacs 19 has s-expr interactive's on some functions (sometimes to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
70 ;; emulate functionality gmhist would give). So we sometimes have to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
71 ;; test this to avoid letting gmhist-make-magic bombing on non-string
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
72 ;; interactive specifications:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
73 ;; XEmacs fix:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
74 (defvar gmhist-emacs-19-p (not (equal (substring emacs-version 0 2) "18")))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
75
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
76 (defvar gmhist-default-format "[%s] " ; saves screen space, too
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
77 "Format used by gmhist to indicate the presence of a default value.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
78 Set this to \"(default %s) \" to get the standard format.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
79
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
80 (defvar gmhist-search-history nil "History of history searches.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
81
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
82 (defun read-with-history-in (GMHIST-SYMBOL rwhi-prompt &optional
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
83 GMHIST-INITIAL GMHIST-READ)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
84 ;; We have to be careful about dynamical scoping here so as not to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
85 ;; shadow other lisp code that depends on fluid vars like `prompt
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
86 ;; (notorious in minibuffer code, e.g. electric-replace).
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
87 ;; That's why our own fluid vars have upper-case names starting with
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
88 ;; GMHIST- and why `rwhi-prompt' instead of `prompt' is used as
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
89 ;; formal argument. Similar below.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
90 "\
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
91 Read a string, maintaining minibuffer history across calls in GMHIST-SYMBOL,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
92 prompting with PROMPT, with optional GMHIST-INITIAL as initial contents.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
93 If optional fourth arg GMHIST-READ is non-nil, then interpret the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
94 result as a lisp object and return that object.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
95 See variable gmhist-map for history commands available during edit.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
96 Example:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
97 (defun foo-command (cmd)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
98 (interactive (list (read-with-history-in 'foo-history \"Foo: \" )))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
99 (message \"Fooing %s...\" cmd))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
100
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
101 See function gmhist-make-magic on how to give an existing function
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
102 history.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
103
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
104 These properties (see function put) of GMHIST-SYMBOL are supported:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
105
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
106 cursor-end Put cursor at end of a newly retrieved history line.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
107 cursor-pos A regexp to put the cursor on.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
108 keep-dups If t, duplicate commands are remembered, too.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
109 initial-hist Initial value of the history list.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
110 hist-ignore Regexp of commands that are not to be added to the history.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
111 backup If t, backup in the history list (as if user had typed
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
112 M-p as first thing). Can also be an integer to backup
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
113 more than one history item.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
114 default An empty string as input will default to the last
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
115 command (whether the last command was added to the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
116 history or not). The default is stored in this
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
117 property, thus its initial value is the first default.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
118 dangerous Commands matching this regexp will never be the default.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
119 no-default If you don't want defaults at all, set this to t.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
120
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
121 Use the following only if you know what you are doing:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
122
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
123 hist-function Name of a function to call instead of doing normal
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
124 history processing. read-with-history-in becomes
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
125 effectively an alias for this function.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
126
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
127 These will be flushed soon (use let-binding minibuffer-completion-table
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
128 etc. instead):
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
129
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
130 hist-map Minibuffer key map to use instead of gmhist-map.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
131 completion-table
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
132 completion-predicate
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
133 Used in completion on history strings, when the hist-map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
134 property has gmhist-completion-map as value.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
135 The special value `t' for the table means to use the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
136 current history list.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
137 Thus, to get completion on history items just do:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
138 (put 'foo-history 'hist-map gmhist-completion-map)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
139 (put 'foo-history 'completion-table t)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
140
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
141 Hooks:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
142 gmhist-after-insert-hook is run after a history item is
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
143 inserted into the minibuffer.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
144 gmhist-load-hook is run after this package is loaded.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
145 gmhist-hook is run as first thing inside read-with-history-in.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
146 gmhist-before-move-hook is run before history motion takes place.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
147 Function gmhist-remember-zero is a candidate for that hook.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
148 "
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
149 ;; We don't use property names prefixed with 'ghmist-' because the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
150 ;; caller has freedom to use anything for GMHIST-SYMBOL.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
151 ;; The history list is never truncated, but I don't think this will
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
152 ;; cause problems. All histories together have at most a few k.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
153 ;; On the other hand, some people run an Emacs session for weeks.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
154 ;; Could use gmhist-hook to truncate the current history list.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
155 ;; You can use 'initial-hist to save (part of) the history in a file
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
156 ;; and provide it at next startup. [Is there an exit-emacs-hook?]
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
157 ;; You can use 'hist-function to implement a completely different
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
158 ;; history mechanism, e.g., a ring instead of a list, without having
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
159 ;; to modify existing gmhist applications.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
160 (run-hooks 'gmhist-hook)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
161 (let ((hist-function (get GMHIST-SYMBOL 'hist-function)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
162 (if (fboundp hist-function) ; hist-function must be a symbol
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
163 (funcall hist-function ; not lambda
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
164 GMHIST-SYMBOL rwhi-prompt GMHIST-INITIAL GMHIST-READ)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
165 (or (boundp GMHIST-SYMBOL) ; history list defaults to nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
166 (set GMHIST-SYMBOL (get GMHIST-SYMBOL 'initial-hist)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
167 ;; else do the usual history processing simply using lists:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
168 (let* ((history (symbol-value GMHIST-SYMBOL))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
169 (minibuffer-completion-table (let ((table
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
170 (get GMHIST-SYMBOL
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
171 'completion-table)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
172 (if (eq t table)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
173 (mapcar (function list)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
174 history)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
175 table)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
176 (minibuffer-completion-predicate (get GMHIST-SYMBOL
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
177 'completion-predicate))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
178 (minibuffer-history-symbol GMHIST-SYMBOL))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
179 (gmhist-new-read-from-minibuffer rwhi-prompt
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
180 GMHIST-INITIAL
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
181 (or (get GMHIST-SYMBOL 'hist-map)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
182 gmhist-map)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
183 GMHIST-READ)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
184
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
185 (defun completing-read-with-history-in (crwhi-hist-sym &rest args)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
186 "Like completing-read, but with additional first arg HISTORY-SYMBOL."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
187 (let ((minibuffer-history-symbol crwhi-hist-sym))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
188 (apply 'gmhist-completing-read args)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
189
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
190 (defun gmhist-completing-read (crwhi-prompt table
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
191 &optional predicate
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
192 mustmatch initial)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
193 "Like completing-read, but see minibuffer-history-symbol."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
194 (let ((minibuffer-completion-confirm (if (eq mustmatch t) nil t))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
195 (minibuffer-completion-table table)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
196 (minibuffer-completion-predicate predicate))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
197 (gmhist-new-read-from-minibuffer crwhi-prompt
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
198 initial
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
199 (gmhist-lookup-keymap
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
200 (if mustmatch
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
201 gmhist-must-match-map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
202 gmhist-completion-map)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
203
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
204
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
205 (defun read-file-name-with-history-in (crwhi-hist-sym &rest args)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
206 "Like read-file-name, but with additional first arg HISTORY-SYMBOL."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
207 (let ((file-history-symbol crwhi-hist-sym))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
208 (apply 'gmhist-read-file-name args)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
209
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
210 (defvar file-history-symbol 'file-history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
211 "*If non-nil, it is the name (a symbol) of a variable on which to cons
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
212 filenames entered in the minibuffer.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
213 You may let-bind this to another symbol around calls to read-file-name.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
214
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
215 (defun gmhist-read-file-name
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
216 (grfn-prompt &optional dir default mustmatch initial)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
217 "Args: PROMPT &optional DIR DEFAULT MUSTMATCH INITIAL.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
218 Read file name, maintaining history in file-history-symbol, prompting
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
219 with PROMPT, with optional INITIAL input and completing in directory DIR.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
220 Value is not expanded! You must call expand-file-name yourself.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
221 Default name to arg DEFAULT if user enters a null string (or, if
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
222 INITIAL was given, leaves it unchanged).
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
223 MUSTMATCH non-nil means require existing file's name.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
224 Non-nil and non-t means also require confirmation after completion.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
225 DIR defaults to current buffer's default-directory.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
226
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
227 This function differs from read-file-name in providing a history of
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
228 filenames bound to file-history-symbol and (for pre-Emacs 19) in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
229 providing an argument INITIAL not present in Emacs 18's read-file-name."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
230 (setq dir (or dir default-directory)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
231 default (or default buffer-file-name))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
232 (if file-history-symbol
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
233 (progn (put file-history-symbol 'cursor-end t)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
234 (put file-history-symbol 'no-default t)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
235 ;; $'s should be quoted (against substitute-in-file-name) in file
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
236 ;; names inserted here
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
237 (if initial
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
238 (setq initial (gmhist-quote-dollars (gmhist-unexpand-home initial)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
239 (if insert-default-directory
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
240 (setq initial (gmhist-quote-dollars (gmhist-unexpand-home dir)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
241 (let* ((minibuffer-completion-confirm (if (eq mustmatch t) nil t))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
242 (minibuffer-completion-table 'read-file-name-internal)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
243 (minibuffer-completion-predicate dir)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
244 (minibuffer-history-symbol file-history-symbol)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
245 (val (gmhist-new-read-from-minibuffer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
246 grfn-prompt initial (gmhist-lookup-keymap
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
247 (if mustmatch
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
248 gmhist-filename-must-match-map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
249 gmhist-filename-completion-map)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
250
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
251 (or (and (or (and (stringp initial)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
252 (string= initial val))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
253 (and (null initial)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
254 (zerop (length val))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
255 default)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
256 (substitute-in-file-name val))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
257
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
258 (defun gmhist-unexpand-home (file)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
259 ;; Make prompt look nicer by un-expanding home dir.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
260 ;; read-file-name does this, too.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
261 ;; Avoid clobbering match-data with string-match.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
262 (let* ((home (expand-file-name "~/"))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
263 (home-len (length home))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
264 (file-len (length file)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
265 (if (and home
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
266 (stringp file)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
267 (>= file-len home-len)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
268 (string= home (substring file 0 home-len))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
269 (eq ?/ (aref file (1- home-len))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
270 (concat "~/" (substring file home-len))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
271 file)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
272
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
273 ; (defun gmhist-quote-dollars (file)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
274 ; "Quote `$' as `$$' in FILE to get it past function `substitute-in-file-name.'"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
275 ; (apply (function concat)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
276 ; (mapcar (function
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
277 ; (lambda (char)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
278 ; (if (= char ?$)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
279 ; "$$"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
280 ; (vector char))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
281 ; file)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
282 ;; 10000 iterations of (gmhist-quote-dollars "foo") took 19 seconds
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
283 ;; and *lots* of garbage collections (about a dozen or more)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
284
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
285 ;; This version does not cons and is much faster in the usual case
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
286 ;; without $ present:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
287 ;; 10000 iterations of (gmhist-quote-dollars "foo") took 4 seconds and
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
288 ;; not a single garbage collection.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
289 (defun gmhist-quote-dollars (file)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
290 "Quote `$' as `$$' in FILE to get it past function `substitute-in-file-name.'"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
291 (let ((pos 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
292 (while (setq pos (string-match "\\$" file pos))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
293 (setq file (concat (substring file 0 pos)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
294 "$";; precede by escape character (also a $)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
295 (substring file pos))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
296 ;; add 2 instead 1 since another $ was inserted
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
297 pos (+ 2 pos)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
298 file))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
299
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
300
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
301
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
302 (defun read-buffer-with-history-in (rbwhi-hist-sym &rest args)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
303 "Like read-buffer, but with additional first arg HISTORY-SYMBOL."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
304 (let ((buffer-history-symbol rbwhi-hist-sym))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
305 (apply 'gmhist-read-buffer args)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
306
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
307 (defvar buffer-history-symbol 'buffer-history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
308 "*If non-nil, it is the name (a symbol) of a variable on which to cons
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
309 buffer names entered in the minibuffer.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
310
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
311 (defun gmhist-read-buffer (grb-prompt &optional default existing)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
312 "Read a buffer name, maintaining history in buffer-history-symbol and return as string.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
313 Args PROMPT &optional DEFAULT EXISTING.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
314 Optional arg EXISTING means an existing buffer must be entered."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
315 (if (bufferp default);; want string in prompt, not buffer object
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
316 (setq default (buffer-name default)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
317 (if buffer-history-symbol
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
318 (put buffer-history-symbol 'default default)) ; also if nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
319 (let* ((minibuffer-history-symbol buffer-history-symbol)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
320 (name (gmhist-completing-read
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
321 grb-prompt
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
322 ;;(function (lambda (buf) (list (buffer-name buf))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
323 ;; convert to alist in format (BUF-NAME . BUF-OBJ)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
324 (mapcar
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
325 (function (lambda (arg) (cons (buffer-name arg) arg)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
326 (buffer-list))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
327 (function (lambda (elt) (get-buffer (car elt))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
328 existing)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
329 (if (equal "" name)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
330 default
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
331 name)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
332
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
333 (defvar minibuffer-history-symbol 'minibuffer-history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
334 "*If non-nil, it is the name (a symbol) of a variable on which to cons
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
335 the string entered in the minibuffer.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
336 Input is stored as string, even for e.g. `read-buffer'.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
337
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
338 (defvar minibuffer-history nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
339 "List of strings entered using the minibuffer, most recent first.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
340
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
341 (put 'minibuffer-history 'no-default t)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
342
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
343 (defvar minibuffer-history-read-only nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
344 "If non-nil, nothing will be stored on `minibuffer-history-symbol'.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
345 History motions commands are still available in the minibuffer.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
346
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
347 (defvar minibuffer-history-position nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
348 "If currently reading the minibuffer, the history position.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
349
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
350 (defvar minibuffer-initial-contents nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
351 "If currently reading the minibuffer, the initial contents.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
352
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
353 ;; Save the subr, we need it inside the redefined version:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
354 (or (fboundp 'gmhist-old-read-from-minibuffer)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
355 (fset 'gmhist-old-read-from-minibuffer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
356 (symbol-function 'read-from-minibuffer)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
357
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
358 (defun gmhist-new-read-from-minibuffer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
359 (gnrfm-prompt &optional initial-contents keymap read position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
360 "Read a string from the minibuffer, prompting with string PROMPT.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
361 If optional second arg INITIAL-CONTENTS is non-nil, it is a string
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
362 to be inserted into the minibuffer before reading input.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
363 Third arg KEYMAP is a keymap to use whilst reading;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
364 if omitted or nil, the default is `minibuffer-local-map'.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
365 If fourth arg READ is non-nil, then interpret the result as a lisp object
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
366 and return that object:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
367 in other words, do `(car (read-from-string INPUT-STRING))'
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
368 Fifth arg POSITION, if non-nil, is where to put point
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
369 in the minibuffer after inserting INITIAL-CONTENTS.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
370
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
371 The ambient value of `minibuffer-history-symbol' (q.v.) is used and set.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
372
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
373 *** This is the gmhist version.***"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
374 (if (null minibuffer-history-symbol)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
375 (if gmhist-emacs-19-p
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
376 (gmhist-old-read-from-minibuffer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
377 gnrfm-prompt initial-contents keymap read position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
378 (gmhist-old-read-from-minibuffer gnrfm-prompt initial-contents
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
379 keymap read))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
380 (gmhist-read-from-minibuffer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
381 gnrfm-prompt initial-contents keymap read position)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
382
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
383 (defun gmhist-read-from-minibuffer (grfm-prompt
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
384 &optional
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
385 initial-contents keymap read position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
386 (or keymap (setq keymap minibuffer-local-map))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
387 (or minibuffer-history-read-only
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
388 (boundp minibuffer-history-symbol) ; history list defaults to nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
389 ;; create history list if not already done
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
390 (set minibuffer-history-symbol
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
391 (get minibuffer-history-symbol 'initial-hist)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
392 (let* ((minibuffer-history-position 0) ; fluid var for motion commands
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
393 (minibuffer-initial-contents initial-contents) ; ditto
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
394 (history (symbol-value minibuffer-history-symbol))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
395 ;; Command is an s-exp when read->t. In this case,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
396 ;; cannot have empty input:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
397 (no-default (or read
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
398 (get minibuffer-history-symbol 'no-default)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
399 (dangerous (if no-default
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
400 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
401 (get minibuffer-history-symbol 'dangerous)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
402 ;; Idea for 'backup feature by Mike Williams
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
403 (backup (get minibuffer-history-symbol 'backup))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
404 (default (if no-default
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
405 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
406 (get minibuffer-history-symbol 'default)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
407 (the-prompt (if default
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
408 (concat grfm-prompt (format gmhist-default-format
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
409 default))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
410 grfm-prompt))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
411 (the-initial (if (or minibuffer-initial-contents
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
412 (not backup))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
413 minibuffer-initial-contents
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
414 ;; else we must backup in the history list
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
415 (setq backup (min (max 0 (or (and (integerp backup)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
416 backup)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
417 1))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
418 (length history)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
419 (if (zerop (setq minibuffer-history-position backup))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
420 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
421 ;; else backup is at least 1
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
422 (let ((backup-input (nth (1- backup) history)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
423 (if read
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
424 (prin1-to-string backup-input)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
425 backup-input)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
426 command)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
427 ;; Read the command from minibuffer, providing history motion
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
428 ;; key map and minibuffer completion
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
429 (setq command
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
430 (if position
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
431 ;; avoid passing POSITION arg unless given (presumably
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
432 ;; we are in Emacs 19 then)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
433 (gmhist-old-read-from-minibuffer the-prompt the-initial keymap
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
434 position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
435 (gmhist-old-read-from-minibuffer the-prompt the-initial keymap)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
436 ;; Care about default values unless forbidden:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
437 (or no-default
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
438 (setq command (gmhist-handle-default command default dangerous)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
439 (if minibuffer-history-read-only
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
440 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
441 (let (ignore)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
442 ;; Add to history if first command, or not a dup, or not to be ignored
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
443 (or (and history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
444 (or (if (get minibuffer-history-symbol 'keep-dups)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
445 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
446 (equal command (car history)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
447 (if (stringp (setq ignore (get minibuffer-history-symbol
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
448 'hist-ignore)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
449 (string-match ignore
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
450 (gmhist-stringify (car history))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
451 (set minibuffer-history-symbol (cons command history)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
452 ;; Return command's value to caller:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
453 (if read
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
454 (car (read-from-string command))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
455 command)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
456
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
457 (defun gmhist-handle-default (command default dangerous)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
458 (if (string= "" command)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
459 (if default (setq command default)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
460 ;; Set default value unless it is dangerous.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
461 (or (and (stringp dangerous)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
462 ;; Should actually save match-data as we call string-match
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
463 (string-match dangerous (gmhist-stringify command)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
464 (put minibuffer-history-symbol 'default command))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
465 ;; Return the prefrobnicated command:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
466 command)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
467
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
468
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
469 ;; Minibuffer key maps to implement history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
470
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
471 (defvar gmhist-define-keys-hook nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
472 "Hook run inside function `gmhist-define-keys' (q.v.), after the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
473 standard gmhist bindings.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
474
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
475 (or (fboundp 'gmhist-define-keys)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
476 (defun gmhist-define-keys (map)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
477 "Bind the standard history commands in MAP, a key map.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
478
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
479 When gmhist is loaded, this function is only defined if you have not
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
480 already defined it, so that you can customize it without worrying
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
481 about load order.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
482 You can also use `gmhist-define-keys-hook' if you just want to add to
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
483 existing bindings."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
484 (define-key map "\M-p" 'gmhist-previous)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
485 (define-key map "\M-n" 'gmhist-next)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
486 (define-key map "\M-r" 'gmhist-search-backward)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
487 (define-key map "\M-s" 'gmhist-search-forward)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
488 ;;(define-key map "\M-<" 'gmhist-beginning)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
489 ;;(define-key map "\M-<" 'gmhist-beginning)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
490 ;; Last two for bash/readline compatibility. Better M-a and M-e ?
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
491 ;; In query-replace, multi-line text together with next-line's
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
492 ;; misfeature of adding blank lines really lets you lose without M-<
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
493 ;; and M->.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
494 ;;(define-key map "\M-a" 'gmhist-beginning)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
495 ;;(define-key map "\M-e" 'gmhist-end)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
496 ;; M-a is already used in electric replace
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
497 ;; Try this as general purpose mover:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
498 (define-key map "\M-g" 'gmhist-toggle)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
499 (define-key map "\M-G" 'gmhist-switch-history)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
500 (define-key map "\M-?" 'gmhist-show)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
501 (run-hooks 'gmhist-define-keys-hook)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
502
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
503 (defun gmhist-lookup-keymap (map)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
504 (if (keymapp map)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
505 map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
506 (gmhist-lookup-keymap (symbol-value map))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
507
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
508 (defvar gmhist-map nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
509 "Key map for generic minibuffer history.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
510 \\<gmhist-map>\\[gmhist-previous], \\[gmhist-next], \
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
511 \\[gmhist-beginning], \\[gmhist-end] move through, \
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
512 \\[gmhist-search-backward] and \\[gmhist-search-forward] search,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
513 \\[gmhist-show] displays the history:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
514 \\{gmhist-map}")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
515
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
516 (if gmhist-map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
517 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
518 (setq gmhist-map (copy-keymap minibuffer-local-map))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
519 (gmhist-define-keys gmhist-map))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
520
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
521 (defvar gmhist-completion-map nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
522 "Key map for generic minibuffer history with completion, see gmhist-map.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
523
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
524 (if gmhist-completion-map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
525 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
526 ;; If you have loaded D. Gillespie's complete.el or Christopher
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
527 ;; McConnell's completer.el *before* gmhist, you get it in gmhist,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
528 ;; too:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
529 (setq gmhist-completion-map (copy-keymap minibuffer-local-completion-map))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
530 (gmhist-define-keys gmhist-completion-map))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
531
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
532 (defvar gmhist-must-match-map nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
533 "Key map for generic minibuffer history with completion that must match,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
534 see gmhist-map.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
535
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
536 (if gmhist-must-match-map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
537 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
538 (setq gmhist-must-match-map (copy-keymap minibuffer-local-must-match-map))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
539 (gmhist-define-keys gmhist-must-match-map))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
540
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
541 (defvar gmhist-filename-completion-map 'gmhist-completion-map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
542 "A keymap (or a symbol pointing to one) to use in filename
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
543 completion that need not match. Defaults to 'gmhist-completion-map.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
544
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
545 (defvar gmhist-filename-must-match-map 'gmhist-must-match-map
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
546
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
547 "A keymap (or a symbol pointing to one) to use in filename
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
548 completion that must match. Defaults to 'gmhist-must-match-map.")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
549
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
550
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
551 ;; Minibuffer commands to implement history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
552 ;; They run inside read-with-history-in and heavily depend on fluid
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
553 ;; vars from there.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
554
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
555 (defun gmhist-goto (n)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
556 ;; Go to history position N, 1 <= N <= length of history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
557 ;; N<0 means the future and inserts an empty string
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
558 ;; N=0 means minibuffer-initial-contents (fluid var from
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
559 ;; gmhist-new-read-from-minibuffer)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
560 (run-hooks 'gmhist-before-move-hook)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
561 (erase-buffer)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
562 (setq minibuffer-history-position n)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
563 (if (< n 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
564 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
565 (insert
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
566 (gmhist-stringify
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
567 (if (= n 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
568 (or minibuffer-initial-contents "")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
569 (nth (1- n) (symbol-value minibuffer-history-symbol)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
570 (run-hooks 'gmhist-after-insert-hook)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
571 ;; next two actually would be a good application for this hook
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
572 (goto-char (if (get minibuffer-history-symbol 'cursor-end)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
573 (point-max)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
574 (point-min)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
575 (let ((pos (get minibuffer-history-symbol 'cursor-pos)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
576 (if (stringp pos)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
577 (if (eobp)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
578 (re-search-backward pos nil t)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
579 (re-search-forward pos nil t))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
580
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
581 (defun gmhist-beginning ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
582 "Go to the oldest command in the history."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
583 (interactive)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
584 (gmhist-goto (length (symbol-value minibuffer-history-symbol))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
585
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
586 (defun gmhist-end ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
587 "Position before the most recent command in the history."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
588 (interactive)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
589 (gmhist-goto 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
590
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
591 (defun gmhist-toggle (&optional n)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
592 "If at end of history, move to beginning, else move to end.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
593 Prefix arg is history position to go to."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
594 (interactive "P")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
595 (if n
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
596 (gmhist-goto (prefix-numeric-value n))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
597 (if (= 0 minibuffer-history-position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
598 (gmhist-beginning)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
599 (gmhist-end))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
600
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
601 (defun gmhist-switch-history (new-history)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
602 "Switch to a different history."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
603 (interactive
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
604 (let ((enable-recursive-minibuffers t))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
605 (list (read-from-minibuffer "Switch to history: " nil nil t))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
606 (setq minibuffer-history-symbol new-history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
607 minibuffer-history-position 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
608
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
609 (defun gmhist-next (n)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
610 "Go to next history position."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
611 ;; fluid vars: minibuffer-history-symbol minibuffer-history-position
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
612 ;; Inserts the next element of minibuffer-history-symbol's value
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
613 ;; into the minibuffer.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
614 ;; minibuffer-history-position is the current history position.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
615 (interactive "p")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
616 ;; clip the new history position to the valid range:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
617 (let ((narg (min (max 0 (- minibuffer-history-position n))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
618 (length (symbol-value minibuffer-history-symbol)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
619 (if (= minibuffer-history-position narg)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
620 (error "No %s item in %s"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
621 (if (= 0 minibuffer-history-position) "following" "preceding")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
622 minibuffer-history-symbol)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
623 (gmhist-goto narg))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
624
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
625 (defun gmhist-previous (n)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
626 "Go to previous history position."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
627 (interactive "p")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
628 (gmhist-next (- n)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
629
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
630 ;; Searching the history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
631
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
632 (defun gmhist-search-backward (regexp &optional forward)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
633 "Search backward in the history list for REGEXP.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
634 With prefix argument, search for line that contains match for current line."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
635 (interactive
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
636 (if current-prefix-arg
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
637 (list (regexp-quote (buffer-string)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
638 (let ((enable-recursive-minibuffers t))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
639 (list (read-with-history-in 'gmhist-search-history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
640 "History search (regexp): ")))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
641 (let* (found
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
642 (direction (if forward -1 1))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
643 (pos (+ minibuffer-history-position direction)) ; find _next_ match!
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
644 (history (symbol-value minibuffer-history-symbol))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
645 (len (length history)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
646 (while (and (if forward (> pos 0) (<= pos len))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
647 (not (setq found
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
648 (string-match
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
649 regexp
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
650 (gmhist-stringify (nth (1- pos) history))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
651 (setq pos (+ pos direction)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
652 (or found (error "%s not found in %s" regexp minibuffer-history-symbol))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
653 (gmhist-goto pos)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
654
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
655 (defun gmhist-search-forward (regexp &optional backward)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
656 "Search forward in the history list for REGEXP.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
657 With prefix argument, search for line that matches current line
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
658 instead of prompting for REGEXP."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
659 (interactive
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
660 (if current-prefix-arg
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
661 (list (regexp-quote (buffer-string)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
662 (let ((enable-recursive-minibuffers t))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
663 (list (read-with-history-in 'gmhist-search-history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
664 "History search forward (regexp): ")))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
665 (gmhist-search-backward regexp (not backward)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
666
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
667 ;; Misc.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
668
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
669 (defun gmhist-stringify (elt)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
670 ;; If ELT is not a string, convert it to one.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
671 (if (stringp elt) elt (prin1-to-string elt)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
672
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
673 (defun gmhist-show ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
674 "Show the history list in another buffer.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
675 Use \\[scroll-other-window] to scroll, with negative arg to scroll back."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
676 (interactive)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
677 (let ((count 0))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
678 (with-output-to-temp-buffer (concat "*" (symbol-name minibuffer-history-symbol) "*")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
679 (mapcar
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
680 (function
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
681 (lambda (x)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
682 (princ (format "%2s%2d: %s\n"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
683 (if (eq (setq count (1+ count))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
684 minibuffer-history-position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
685 "> "
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
686 " ")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
687 count x))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
688 (symbol-value minibuffer-history-symbol)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
689
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
690 (defun gmhist-remember-zero ()
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
691 "Put this function on gmhist-before-move-hook to make gmhist
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
692 remember the initial value even after you edited it:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
693
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
694 (setq gmhist-before-move-hook 'gmhist-remember-zero)"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
695 (if (zerop minibuffer-history-position)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
696 (setq minibuffer-initial-contents (buffer-string))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
697
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
698 ;; Hack up interactive specifications of existing functions
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
699
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
700 (defun gmhist-copy-function (fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
701 (let ((old (gmhist-symbol-function fun)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
702 (if (consp old) ; interpreted, or v18 compiled
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
703 ;; copy-sequence does not copy recursively.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
704 ;; Iteration is faster than recursion, and we need just two levels
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
705 ;; to be able to use setcdr to mung the interactive spec.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
706 (let (new elt)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
707 (while old
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
708 (setq elt (car old)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
709 old (cdr old)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
710 new (cons (if (sequencep elt)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
711 (copy-sequence elt)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
712 elt)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
713 new)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
714 (nreverse new))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
715 ;; else v19 compiled
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
716 (let ((new (append old nil)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
717 (setcar (nthcdr 5 new) (copy-sequence (aref old 5)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
718 (apply 'make-byte-code new)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
719
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
720 (defun gmhist-check-autoload (fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
721 "If FUN is an autoload, load its definition."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
722 (let ((lis (symbol-function fun)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
723 (if (and (listp lis) ; FUN could also be a subr
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
724 (eq 'autoload (car lis)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
725 (load (nth 1 lis)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
726
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
727 (defun gmhist-replace-spec (fun new-spec &optional copy-first)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
728 "Replace the interactive specification of FUN with NEW-SPEC.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
729 FUN must be a symbol with a function definition.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
730 Autoload functions are taken care of by loading the appropriate file first.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
731 If FUN is a pure storage function (one dumped into Emacs) it is first
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
732 copied onto itself, because pure storage cannot be modified.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
733 Optional non-nil third arg COPY-FIRST is used internally for this.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
734 The old spec is put on FUN's gmhist-old-interactive-spec property.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
735 That property is never overwritten by this function. It is used by
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
736 function gmhist-remove-magic."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
737 (gmhist-check-autoload fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
738 (if copy-first ; copy (from pure storage)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
739 (fset fun (gmhist-copy-function fun)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
740 (let* ((flambda (gmhist-symbol-function fun))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
741 (fint (and (consp flambda)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
742 (if (eq 'interactive (car-safe (nth 2 flambda)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
743 (nth 2 flambda)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
744 (if (eq 'interactive (car-safe (nth 3 flambda)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
745 (nth 3 flambda)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
746 (error "%s is not interactive" fun)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
747 (old-spec (if fint
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
748 (nth 1 fint)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
749 (gmhist-spec fun))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
750 ;; Save old interactive spec as property of FUN:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
751 (or (get fun 'gmhist-old-interactive-spec)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
752 (put fun 'gmhist-old-interactive-spec old-spec))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
753 ;; Replace '(interactive OLD-SPEC) with '(interactive NEW-SPEC)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
754 (if copy-first
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
755 ;; This should not fail - if it does, we must abort.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
756 (if (consp flambda)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
757 (setcdr fint (list new-spec))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
758 ;; can't "aset" a #<byte-code> object, though aref works...
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
759 (setq flambda (append flambda nil))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
760 (setcar (nthcdr 5 flambda) new-spec)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
761 (setq flambda (apply 'make-byte-code flambda))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
762 (fset fun flambda))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
763 ;; else prepare for a second try
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
764 (condition-case err
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
765 (setcdr fint (list new-spec))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
766 (error
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
767 ;; Setcdr bombs on preloaded functions:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
768 ;; (error "Attempt to modify read-only object")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
769 ;; There seems to be no simple way to test whether an object
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
770 ;; resides in pure storage, so we let it bomb and try again
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
771 ;; after copying it into writable storage.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
772 (gmhist-replace-spec fun new-spec t))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
773
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
774 (defun gmhist-spec (fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
775 "Get the current interactive specification for FUN (a symbol).
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
776 Signal an error if FUN is not interactive."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
777 (let ((flambda (gmhist-symbol-function fun))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
778 fint)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
779 (cond ((consp flambda) ; interpreted, or v18 compiled
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
780 ;; do it exactly like call-interactively, even if this
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
781 ;; means (interactive...) can come arbitrary late in FUN's body
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
782 (setq fint (assq 'interactive (cdr (cdr flambda))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
783 (or fint
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
784 (error "Cannot get spec of a non-interactive command: %s!" fun))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
785 (nth 1 fint))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
786 (t ; otherwise it's a v19 compiled-code object
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
787 (aref flambda 5)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
788
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
789 (defun gmhist-symbol-function (fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
790 ;; Return FUN's ultimate definition.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
791 ;; Recurse if FUN is fset to another function's name.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
792 (let ((flambda (symbol-function fun)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
793 (if (symbolp flambda)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
794 ;; Prefer recursion over while because infinite loop is caught
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
795 ;; by max-lisp-eval-depth.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
796 (gmhist-symbol-function flambda)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
797 flambda)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
798
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
799 ;; Automagic gmhistification
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
800
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
801 ;; There should be a builtin split function - inverse to mapconcat.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
802 (defun gmhist-split (pat str &optional limit)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
803 "Splitting on regexp PAT, turn string STR into a list of substrings.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
804 Optional third arg LIMIT (>= 1) is a limit to the length of the
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
805 resulting list.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
806 Thus, if SEP is a regexp that only matches itself,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
807
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
808 (mapconcat 'identity (gmhist-split SEP STRING) SEP)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
809
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
810 is always equal to STRING."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
811 (let* ((start (string-match pat str))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
812 (result (list (substring str 0 start)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
813 (count 1)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
814 (end (if start (match-end 0))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
815 (if end ; else nothing left
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
816 (while (and (or (not (integerp limit))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
817 (< count limit))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
818 (string-match pat str end))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
819 (setq start (match-beginning 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
820 count (1+ count)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
821 result (cons (substring str end start) result)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
822 end (match-end 0)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
823 start end)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
824 ))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
825 (if (and (or (not (integerp limit))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
826 (< count limit))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
827 end) ; else nothing left
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
828 (setq result
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
829 (cons (substring str end) result)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
830 (nreverse result)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
831
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
832 (defun gmhist-interactive (spec hist)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
833 "Interpret SPEC, an interactive string, like call-interactively
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
834 would, only with minibuffer history in HIST (a symbol).
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
835
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
836 If the value of HIST is another symbol (which can never happen if
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
837 history lists are already stored on it), this symbol is taken instead
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
838 to facilitate dynamic indirections.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
839
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
840 Currently recognized key letters are:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
841
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
842 a b B c C d D k m N n s S x X f F r p P v
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
843
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
844 and initial `*'.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
845
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
846 Use it inside interactive like this
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
847
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
848 \(interactive \(gmhist-interactive \"sPrompt: \\nP\" 'foo-history\)\)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
849
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
850 or even like this:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
851
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
852 \(interactive
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
853 \(gmhist-interactive \"sReplace: \\nsReplace %s with: \" 'replace-history\)\)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
854 "
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
855 (or (stringp spec)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
856 (error "gmhist-interactive: not a string %s" spec))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
857 (if (and (> (length spec) 0) (eq ?\* (aref spec 0)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
858 (progn
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
859 (barf-if-buffer-read-only)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
860 (setq spec (substring spec 1))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
861 (if (and (boundp hist)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
862 (symbolp (symbol-value hist))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
863 (not (null (symbol-value hist))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
864 (setq hist (symbol-value hist)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
865 (let ((spec-list (mapcar '(lambda (x)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
866 ;; forgive empty entries like
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
867 ;; call-interactively does:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
868 (if (equal "" x)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
869 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
870 (cons (aref x 0) (substring x 1))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
871 (gmhist-split "\n" spec)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
872 cur-arg args-so-far special elt char prompt xprompt)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
873 (setq spec-list (delq nil spec-list))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
874 (while spec-list
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
875 (setq elt (car spec-list)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
876 spec-list (cdr spec-list)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
877 special nil ; special handling of args-so-far
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
878 char (car elt)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
879 prompt (cdr elt)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
880 xprompt (apply (function format) prompt (reverse args-so-far)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
881 (cond ((eq char ?a) ; Symbol defined as a function
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
882 (setq cur-arg (intern
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
883 (completing-read-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
884 hist xprompt obarray 'fboundp t nil))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
885 ((eq char ?b) ; Name of existing buffer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
886 (setq cur-arg (read-buffer-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
887 hist xprompt (other-buffer) t)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
888 ((eq char ?B) ; Name of possibly non-existing buffer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
889 (setq cur-arg (read-buffer-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
890 hist xprompt (other-buffer) nil)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
891 ((eq char ?c) ; Character
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
892 (message xprompt) ; history doesn't make sense for this
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
893 (setq cur-arg (read-char)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
894 ((eq char ?C) ; Command
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
895 (setq cur-arg (intern
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
896 (completing-read-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
897 hist xprompt obarray 'commandp t nil))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
898 ((eq char ?d) ; Value of point. Does not do I/O.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
899 (setq cur-arg (point)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
900 ((eq char ?D) ; directory name
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
901 ;; This does not check file-directory-p, but neither does
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
902 ;; call-interactively.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
903 (setq cur-arg (read-file-name-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
904 hist
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
905 xprompt
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
906 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
907 default-directory
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
908 'confirm)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
909 ((eq char ?f) ; existing file name
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
910 (setq cur-arg (read-file-name-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
911 hist
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
912 xprompt
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
913 nil nil 'confirm)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
914 ((eq char ?F) ; possibly nonexistent file name
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
915 (setq cur-arg (read-file-name-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
916 hist
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
917 xprompt)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
918 ((eq char ?k) ; Key sequence (string)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
919 (setq cur-arg (read-key-sequence (if (equal xprompt "")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
920 nil xprompt))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
921 ((eq char ?m) ; Value of mark. Does not do I/O.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
922 (setq cur-arg (or (mark) (error "The mark is not set now"))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
923 ((eq char ?N) ; Prefix arg, else number from minibuf
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
924 (if current-prefix-arg
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
925 (setq cur-arg (prefix-numeric-value current-prefix-arg))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
926 (while (not (integerp
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
927 (setq cur-arg
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
928 (read-with-history-in hist xprompt nil t)))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
929 ((eq char ?n) ; Read number from minibuffer
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
930 (while (not (integerp
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
931 (setq cur-arg
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
932 (read-with-history-in hist xprompt nil t))))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
933 ((eq char ?p) ; cooked prefix arg
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
934 (setq cur-arg (prefix-numeric-value current-prefix-arg)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
935 ((eq char ?P) ; raw prefix arg
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
936 (setq cur-arg current-prefix-arg))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
937 ((eq char ?r) ; region
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
938 (let (region-min region-max)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
939 ;; take some pains to behave exactly like interactive "r"
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
940 (setq region-min (min (or (mark)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
941 (error "The mark is not set now"))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
942 (point))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
943 region-max (max (or (mark)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
944 (error "The mark is not set now"))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
945 (point)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
946 (setq args-so-far
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
947 (append (list region-max region-min) args-so-far)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
948 special t)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
949 ((eq char '?s) ; string
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
950 (setq cur-arg (read-with-history-in hist xprompt)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
951 ((eq char ?S) ; any symbol
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
952 (setq cur-arg (read-with-history-in hist xprompt nil t)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
953 ((eq char ?v) ; Variable name
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
954 (setq cur-arg (completing-read-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
955 hist xprompt obarray 'user-variable-p t nil)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
956 ((memq char '(?x ?X)) ; lisp expression
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
957 (setq cur-arg (read-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
958 hist
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
959 xprompt
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
960 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
961 ;; have to tell gmhist to read s-exps
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
962 ;; instead of strings:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
963 t))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
964 (if (eq char ?X) ; lisp expression, evaluated
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
965 (setq cur-arg (eval cur-arg))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
966
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
967 (t
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
968 (error "Invalid control letter `%c' in gmhist-interactive" char)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
969 (or special
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
970 (setq args-so-far (cons cur-arg args-so-far))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
971 (reverse args-so-far)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
972
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
973 (defun gmhist-new-spec (fun &optional hist no-error)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
974 "Return a new interactive specification for FUN, suitable for use
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
975 with setcdr in function gmhist-replace-spec.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
976 Use symbol HIST to store the history. HIST defaults to `FUN-history'.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
977 The returned spec does the same as the old one, only with history in HIST.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
978
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
979 If FUN is an autoload object, its file is loaded first.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
980
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
981 See function gmhist-interactive for a list of recognized interactive
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
982 keys letters.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
983
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
984 Unless optional third arg NO-ERROR is given, signals an error if FUN's
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
985 interactive string contains unknown key letters or has no interactive string.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
986 With NO-ERROR, it returns nil."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
987 (or hist (setq hist (intern (concat (symbol-name fun) "-history"))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
988 (gmhist-check-autoload fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
989 (let ((spec (gmhist-spec fun)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
990 (if (stringp spec)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
991 (list 'gmhist-interactive spec (list 'quote hist))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
992 (if no-error
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
993 nil
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
994 (error "Can't gmhistify %s's spec: %s" fun spec)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
995
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
996 (defun gmhist-make-magic (fun &optional hist)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
997 "Make FUN magically maintain minibuffer history in symbol HIST.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
998 HIST defaults to `FUN-history'.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
999 This works by modifying the interactive specification, which must be a
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1000 string. For more complicated cases, see gmhist-replace-spec.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1001 The magic goes away when you call gmhist-remove-magic on FUN."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1002 (interactive "CPut gmhist magic on command: ")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1003 (let ((new-spec (gmhist-new-spec fun hist t)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1004 (if new-spec
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1005 (gmhist-replace-spec fun new-spec)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1006 ;; else there was some error. Try to find out if this is a retry.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1007 (if (not (get fun 'gmhist-old-interactive-spec))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1008 (error "Too complicated for gmhist: %s" fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1009 (message "Another attempt to put magic on %s..." fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1010 (gmhist-remove-magic fun) ; will abort if not a retry
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1011 ;; This time we don't catch errors - magic or blow!
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1012 (gmhist-replace-spec fun (gmhist-new-spec fun hist))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1013 (message "Another attempt to put magic on %s...done." fun)))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1014
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1015 (defun gmhist-remove-magic (fun)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1016 "Remove the magic that gmhist-make-magic put on FUN,
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1017 restoring the old interactive spec."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1018 (interactive "CRemove gmhist magic from command: ")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1019 (gmhist-replace-spec
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1020 fun
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1021 (or (get fun 'gmhist-old-interactive-spec)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1022 (error "Can't find %s's old interactive spec!" fun))))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1023
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1024 ;; Now make yourself magic
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1025 (gmhist-make-magic 'gmhist-make-magic 'gmhist-make-magic-history)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1026 (gmhist-make-magic 'gmhist-remove-magic 'gmhist-make-magic-history)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1027
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1028
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1029 ;; Examples, pedagogic and serious ones. More in gmhist-app.el.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1030
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1031 ;;(defun foo-command (cmd)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1032 ;; (interactive (list
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1033 ;; (read-with-history-in 'foo-history "Foo: ")))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1034 ;; (message "Foo %s" cmd))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1035 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1036 ;; ;; The interactive clause could also have been the simpler
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1037 ;; ;; (interactive (gmhist-interactive "sFoo: " 'foo-history))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1038 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1039 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1040 ;;;(put 'foo-history 'hist-map minibuffer-local-map) ; disable motion ...
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1041 ;;;(put 'foo-history 'hist-function 'gmhist-read-nohistory) ; and history
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1042 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1043 ;;(put 'foo-history 'hist-function nil) ; enable history ...
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1044 ;;(put 'foo-history 'hist-map nil) ; and motion again
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1045 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1046 ;;(defun gmhist-read-nohistory (symbol prompt initial-input read)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1047 ;; "An example function to put on the hist-function property."
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1048 ;; (message "read-nohistory...")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1049 ;; (sit-for 2)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1050 ;; (read-string prompt initial-input))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1051 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1052 ;; Example for reading file names:
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1053 ;;(defun bar-command (cmd)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1054 ;; (interactive
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1055 ;; (list
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1056 ;; (read-file-name-with-history-in
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1057 ;; ;; HIST-SYM PROMPT DIR DFLT MUSTMATCH
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1058 ;; 'bar-history "Bar: " nil nil 'confirm)))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1059 ;; (message "Bar %s" cmd))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1060 ;;
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1061 ;; Example function to apply gmhist-make-magic to.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1062 ;; Compare the missing initial input in bar to the magic version of zod.
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1063 ;;(defun zod-command (cmd)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1064 ;; (interactive "fZod: ")
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1065 ;; (message "Zod %s" cmd))
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1066
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1067 ;; Finally run the load-hook
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1068
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1069 (run-hooks 'gmhist-load-hook)
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1070
376386a54a3c Import from CVS: tag r19-14
cvs
parents:
diff changeset
1071 ;; End of file gmhist.el