(Fprimitive_undo): Use base buffer's modtime field.
[bpt/emacs.git] / lisp / icomplete.el
CommitLineData
239c87a1
RS
1;;;_. icomplete.el - minibuffer completion incremental feedback
2
3;;; Copyright (C) 1992, 1993, 1994 Free Software Foundation, Inc.
d462ff97
RS
4
5;;; Author: Ken Manheimer <klm@nist.gov>
6;;; Maintainer: Ken Manheimer <klm@nist.gov>
239c87a1 7;;; Version: Id: icomplete.el,v 4.3 1994/08/31 18:48:29 klm Exp
d462ff97
RS
8;;; Created: Mar 1993 klm@nist.gov - first release to usenet
9;;; Keywords: help, abbrev
10
239c87a1 11;; This file is part of GNU Emacs.
d462ff97 12
239c87a1
RS
13;; GNU Emacs is free software; you can redistribute it and/or modify
14;; it under the terms of the GNU General Public License as published by
15;; the Free Software Foundation; either version 2, or (at your option)
16;; any later version.
d462ff97 17
239c87a1
RS
18;; GNU Emacs is distributed in the hope that it will be useful,
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
c89164c5 22
239c87a1
RS
23;; You should have received a copy of the GNU General Public License
24;; along with GNU Emacs; see the file COPYING. If not, write to
25;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
d462ff97 26
239c87a1 27;;; Commentary:
d462ff97 28
239c87a1
RS
29;;; Loading this package implements a more fine-grained minibuffer
30;;; completion feedback scheme. Prospective completions are concisely
31;;; indicated within the minibuffer itself, with each successive
32;;; keystroke.
33
34;;; See 'icomplete-completions' docstring for a description of the
35;;; icomplete display format.
36
37;;; See the `icomplete-minibuffer-setup-hook' docstring for a means to
38;;; customize icomplete setup for interoperation with other
39;;; minibuffer-oriented packages.
40
41;;; To activate icomplete mode, simply load the package. You can
42;;; subsequently deactivate it by invoking the function icomplete-mode
43;;; with a negative prefix-arg (C-U -1 ESC-x icomplete-mode). Also,
44;;; you can prevent activation of the mode during package load by
45;;; first setting the variable `icomplete-mode' to nil. Icompletion
46;;; can be enabled any time after the package is loaded by invoking
47;;; icomplete-mode without a prefix arg.
48
49;;; This version of icomplete runs on Emacs 19.18 and later. (It
50;;; depends on the incorporation of minibuffer-setup-hook.) The elisp
51;;; archives, ftp://archive.cis.ohio-state.edu/pub/gnu/emacs/elisp-archive,
52;;; probably still has a version that works in GNU Emacs v18.
53
54;;; Thanks to everyone for their suggestions for refinements of this
55;;; package. I particularly have to credit Michael Cook, who
56;;; implemented an incremental completion style in his 'iswitch'
57;;; functions that served as a model for icomplete. Some other
58;;; contributors: Noah Freidman (restructuring as minor mode), Colin
59;;; Rafferty (lemacs reconciliation), Lars Lindberg, RMS, and
60;;; others.
61
62;;; klm.
c89164c5 63
239c87a1
RS
64;;; Code:
65
66;;;_* Provide
d462ff97
RS
67(provide 'icomplete)
68
239c87a1
RS
69;;;_* User Customization variables
70
71;;;_* Initialization
72;;;_ = icomplete-minibuffer-setup-hook
73(defvar icomplete-minibuffer-setup-hook nil
74 "*Icomplete-specific customization of minibuffer setup.
75
76This hook is run during minibuffer setup iff icomplete will be active.
77It is intended for use in customizing icomplete for interoperation
78with other packages. For instance:
79
80 \(add-hook 'icomplete-minibuffer-setup-hook
81 \(function
82 \(lambda ()
83 \(make-local-variable 'resize-minibuffer-window-max-height)
84 \(setq resize-minibuffer-window-max-height 3))))
85
86will constrain rsz-mini to a maximum minibuffer height of 3 lines when
87icompletion is occurring.")
d462ff97 88
c89164c5 89;;;_ + Internal Variables
239c87a1
RS
90;;;_ = icomplete-mode
91(defvar icomplete-mode t
92 "Non-nil enables incremental minibuffer completion, once
93`\\[icomplete-mode]' function has set things up.")
c89164c5 94;;;_ = icomplete-eoinput 1
d462ff97
RS
95(defvar icomplete-eoinput 1
96 "Point where minibuffer input ends and completion info begins.")
97(make-variable-buffer-local 'icomplete-eoinput)
239c87a1
RS
98;;;_ = icomplete-pre-command-hook
99(defvar icomplete-pre-command-hook nil
100 "Incremental-minibuffer-completion pre-command-hook.
101
102Is run in minibuffer before user input when `icomplete-mode' is non-nil.
103Use `icomplete-mode' function to set it up properly for incremental
104minibuffer completion.")
105(add-hook 'icomplete-pre-command-hook 'icomplete-tidy)
106;;;_ = icomplete-post-command-hook
107(defvar icomplete-post-command-hook nil
108 "Incremental-minibuffer-completion post-command-hook.
109
110Is run in minibuffer after user input when `icomplete-mode' is non-nil.
111Use `icomplete-mode' function to set it up properly for incremental
112minibuffer completion.")
113(add-hook 'icomplete-post-command-hook 'icomplete-exhibit)
114
115;;;_ > icomplete-mode (&optional prefix)
c89164c5 116;;;###autoload
239c87a1
RS
117(defun icomplete-mode (&optional prefix)
118 "Activate incremental minibuffer completion for this emacs session,
119or deactivate with negative prefix arg."
120 (interactive "p")
121 (or prefix (setq prefix 0))
122 (cond ((>= prefix 0)
123 (setq icomplete-mode t)
124 ;; The following is not really necessary after first time -
125 ;; no great loss.
126 (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup))
127 (t (setq icomplete-mode nil))))
128
129;;;_ > icomplete-simple-completing-p ()
130(defun icomplete-simple-completing-p ()
131
132 "Non-nil if current window is minibuffer that's doing simple completion.
133
134Conditions are:
135 the selected window is a minibuffer,
136 and not in the middle of macro execution,
137 and minibuffer-completion-table is not a symbol (which would
138 indicate some non-standard, non-simple completion mechansm,
139 like file-name and other custom-func completions)."
140
141 (and (window-minibuffer-p (selected-window))
142 (not executing-macro)
143 (not (symbolp minibuffer-completion-table))))
144;;;_ > icomplete-minibuffer-setup ()
145;;;###autoload
146(defun icomplete-minibuffer-setup ()
147
148 "Run in minibuffer on activation to establish incremental completion.
149
150Usually run by inclusion in minibuffer-setup-hook."
151
152 (cond ((and icomplete-mode (icomplete-simple-completing-p))
153 (make-local-variable 'pre-command-hook)
154 (setq pre-command-hook (copy-sequence pre-command-hook))
155 (add-hook 'pre-command-hook
156 (function (lambda ()
157 (run-hooks 'icomplete-pre-command-hook))))
158 (make-local-variable 'post-command-hook)
159 (setq post-command-hook (copy-sequence post-command-hook))
160 (add-hook 'post-command-hook
161 (function (lambda ()
162 (run-hooks 'icomplete-post-command-hook))))
163 (run-hooks 'icomplete-minibuffer-setup-hook))))
164
165;;;_* Completion
166
167;;;_ > icomplete-tidy ()
168(defun icomplete-tidy ()
169 "Remove completions display \(if any) prior to new user input.
170
171Should be run in on the minibuffer pre-command-hook. See `icomplete-mode'
172and `minibuffer-setup-hook'."
173 (if (icomplete-simple-completing-p)
d462ff97
RS
174 (if (and (boundp 'icomplete-eoinput)
175 icomplete-eoinput)
239c87a1 176
d462ff97
RS
177 (if (> icomplete-eoinput (point-max))
178 ;; Oops, got rug pulled out from under us - reinit:
179 (setq icomplete-eoinput (point-max))
c89164c5 180 (let ((buffer-undo-list buffer-undo-list )) ; prevent entry
d462ff97 181 (delete-region icomplete-eoinput (point-max))))
239c87a1 182
c89164c5 183 ;; Reestablish the local variable 'cause minibuffer-setup is weird:
d462ff97
RS
184 (make-local-variable 'icomplete-eoinput)
185 (setq icomplete-eoinput 1))))
239c87a1 186;;;_ > icomplete-exhibit ()
d462ff97 187(defun icomplete-exhibit ()
239c87a1
RS
188 "Insert icomplete completions display.
189
190Should be run via minibuffer post-command-hook. See `icomplete-mode'
191and `minibuffer-setup-hook'."
192 (if (icomplete-simple-completing-p)
d462ff97
RS
193 (let ((contents (buffer-substring (point-min)(point-max)))
194 (buffer-undo-list t))
195 (save-excursion
196 (goto-char (point-max))
197 ; Register the end of input, so we
198 ; know where the extra stuff
199 ; (match-status info) begins:
200 (if (not (boundp 'icomplete-eoinput))
201 ;; In case it got wiped out by major mode business:
202 (make-local-variable 'icomplete-eoinput))
203 (setq icomplete-eoinput (point))
204 ; Insert the match-status information:
205 (if (> (point-max) 1)
206 (insert-string
239c87a1
RS
207 (icomplete-completions contents
208 minibuffer-completion-table
209 minibuffer-completion-predicate
210 (not
211 minibuffer-completion-confirm))))))))
212;;;_ > icomplete-completions (name candidates predicate require-match)
213(defun icomplete-completions (name candidates predicate require-match)
d462ff97
RS
214 "Identify prospective candidates for minibuffer completion.
215
c89164c5 216The display is updated with each minibuffer keystroke during
d462ff97
RS
217minibuffer completion.
218
219Prospective completion suffixes (if any) are displayed, bracketed by
220one of \(), \[], or \{} pairs. The choice of brackets is as follows:
221
222 \(...) - a single prospect is identified and matching is enforced,
223 \[...] - a single prospect is identified but matching is optional, or
224 \{...} - multiple prospects, separated by commas, are indicated, and
225 further input is required to distingish a single one.
226
227The displays for disambiguous matches have \" [Matched]\" appended
228\(whether complete or not), or \" \[No matches]\", if no eligible
229matches exist."
230
231 (let ((comps (all-completions name candidates predicate))
232 ; "-determined" - only one candidate
233 (open-bracket-determined (if require-match "(" "["))
234 (close-bracket-determined (if require-match ")" "]"))
235 ;"-prospects" - more than one candidate
236 (open-bracket-prospects "{")
237 (close-bracket-prospects "}")
238 )
239 (cond ((null comps) (format " %sNo matches%s"
240 open-bracket-determined
241 close-bracket-determined))
242 ((null (cdr comps)) ;one match
243 (concat (if (and (> (length (car comps))
244 (length name)))
245 (concat open-bracket-determined
246 (substring (car comps) (length name))
247 close-bracket-determined)
248 "")
249 " [Matched]"))
250 (t ;multiple matches
251 (let* ((most (try-completion name candidates predicate))
252 (most-len (length most))
253 most-is-exact
254 (alternatives
255 (apply
239c87a1
RS
256 (function concat)
257 (cdr (apply
258 (function nconc)
259 (mapcar '(lambda (com)
260 (if (= (length com) most-len)
261 ;; Most is one exact match,
262 ;; note that and leave out
263 ;; for later indication:
264 (progn
265 (setq most-is-exact t)
266 ())
267 (list ","
268 (substring com
269 most-len))))
270 comps))))))
d462ff97
RS
271 (concat (and (> most-len (length name))
272 (concat open-bracket-determined
273 (substring most (length name))
274 close-bracket-determined))
275 open-bracket-prospects
276 (if most-is-exact
277 (concat "," alternatives)
278 alternatives)
279 close-bracket-prospects))))))
280
239c87a1
RS
281;;;_ + Initialization
282;;; If user hasn't setq-default icomplete-mode to nil, then setup for
283;;; activation:
284(if icomplete-mode
285 (icomplete-mode))
286
287
288;;;_* Local emacs vars.
289;;;Local variables:
290;;;outline-layout: (-2 :)
291;;;End:
d462ff97
RS
292
293;;; icomplete.el ends here
c89164c5 294