Code cleanup: make arguments constant whenever possible.
[bpt/emacs.git] / lisp / icomplete.el
CommitLineData
fa157191 1;;; icomplete.el --- minibuffer completion incremental feedback
239c87a1 2
47fda8fc
SM
3;; Copyright (C) 1992, 1993, 1994, 1997, 1999, 2001, 2005
4;; Free Software Foundation, Inc.
d462ff97 5
1934dbf4
GM
6;; Author: Ken Manheimer <klm@i.am>
7;; Maintainer: Ken Manheimer <klm@i.am>
8;; Created: Mar 1993 Ken Manheimer, klm@nist.gov - first release to usenet
9;; Last update: Ken Manheimer <klm@i.am>, 11/18/1999.
be010748 10;; Keywords: help, abbrev
d462ff97 11
239c87a1 12;; This file is part of GNU Emacs.
d462ff97 13
239c87a1
RS
14;; GNU Emacs is free software; you can redistribute it and/or modify
15;; it under the terms of the GNU General Public License as published by
16;; the Free Software Foundation; either version 2, or (at your option)
17;; any later version.
d462ff97 18
239c87a1
RS
19;; GNU Emacs is distributed in the hope that it will be useful,
20;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22;; GNU General Public License for more details.
c89164c5 23
239c87a1 24;; You should have received a copy of the GNU General Public License
b578f267
EN
25;; along with GNU Emacs; see the file COPYING. If not, write to the
26;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
27;; Boston, MA 02111-1307, USA.
d462ff97 28
239c87a1 29;;; Commentary:
d462ff97 30
b578f267
EN
31;; Loading this package implements a more fine-grained minibuffer
32;; completion feedback scheme. Prospective completions are concisely
33;; indicated within the minibuffer itself, with each successive
34;; keystroke.
35
5e537651 36;; See `icomplete-completions' docstring for a description of the
b578f267
EN
37;; icomplete display format.
38
39;; See the `icomplete-minibuffer-setup-hook' docstring for a means to
40;; customize icomplete setup for interoperation with other
41;; minibuffer-oriented packages.
42
1934dbf4
GM
43;; To activate icomplete mode, load the package and use the
44;; `icomplete-mode' function. You can subsequently deactivate it by
45;; invoking the function icomplete-mode with a negative prefix-arg
46;; (C-U -1 ESC-x icomplete-mode). Also, you can prevent activation of
47;; the mode during package load by first setting the variable
48;; `icomplete-mode' to nil. Icompletion can be enabled any time after
49;; the package is loaded by invoking icomplete-mode without a prefix
50;; arg.
92f7d003 51
b578f267
EN
52;; Thanks to everyone for their suggestions for refinements of this
53;; package. I particularly have to credit Michael Cook, who
54;; implemented an incremental completion style in his 'iswitch'
55;; functions that served as a model for icomplete. Some other
5e537651 56;; contributors: Noah Friedman (restructuring as minor mode), Colin
1be5a284 57;; Rafferty (lemacs reconciliation), Lars Lindberg, RMS, and others.
b578f267
EN
58
59;; klm.
c89164c5 60
239c87a1
RS
61;;; Code:
62
63;;;_* Provide
d462ff97
RS
64(provide 'icomplete)
65
5e537651
SE
66
67(defgroup icomplete nil
68 "Show completions dynamically in minibuffer."
69 :prefix "icomplete-"
70 :group 'minibuffer)
71
1934dbf4
GM
72;;;_* User Customization variables
73(defcustom icomplete-prospects-length 80
74 "*Length of string displaying the prospects."
75 :type 'integer
76 :group 'icomplete)
77
5e537651 78(defcustom icomplete-compute-delay .3
92f7d003 79 "*Completions-computation stall, used only with large-number
5e537651
SE
80completions - see `icomplete-delay-completions-threshold'."
81 :type 'number
82 :group 'icomplete)
83
84(defcustom icomplete-delay-completions-threshold 400
85 "*Pending-completions number over which to apply icomplete-compute-delay."
86 :type 'integer
87 :group 'icomplete)
88
89(defcustom icomplete-max-delay-chars 3
90 "*Maximum number of initial chars to apply icomplete compute delay."
91 :type 'integer
92 :group 'icomplete)
93
94(defcustom icomplete-show-key-bindings t
95 "*If non-nil, show key bindings as well as completion for sole matches."
96 :type 'boolean
97 :group 'icomplete)
98
99(defcustom icomplete-minibuffer-setup-hook nil
239c87a1
RS
100 "*Icomplete-specific customization of minibuffer setup.
101
102This hook is run during minibuffer setup iff icomplete will be active.
103It is intended for use in customizing icomplete for interoperation
9c8acefd 104with other features and packages. For instance:
239c87a1 105
92f7d003 106 \(add-hook 'icomplete-minibuffer-setup-hook
239c87a1
RS
107 \(function
108 \(lambda ()
9c8acefd
EZ
109 \(make-local-variable 'max-mini-window-height)
110 \(setq max-mini-window-height 3))))
239c87a1 111
9c8acefd 112will constrain Emacs to a maximum minibuffer height of 3 lines when
5e537651
SE
113icompletion is occurring."
114 :type 'hook
115 :group 'icomplete)
116
117
118;;;_* Initialization
d462ff97 119
c89164c5 120;;;_ + Internal Variables
47fda8fc
SM
121;;;_ = icomplete-eoinput nil
122(defvar icomplete-eoinput nil
d462ff97
RS
123 "Point where minibuffer input ends and completion info begins.")
124(make-variable-buffer-local 'icomplete-eoinput)
239c87a1
RS
125;;;_ = icomplete-pre-command-hook
126(defvar icomplete-pre-command-hook nil
127 "Incremental-minibuffer-completion pre-command-hook.
128
129Is run in minibuffer before user input when `icomplete-mode' is non-nil.
130Use `icomplete-mode' function to set it up properly for incremental
131minibuffer completion.")
132(add-hook 'icomplete-pre-command-hook 'icomplete-tidy)
133;;;_ = icomplete-post-command-hook
134(defvar icomplete-post-command-hook nil
135 "Incremental-minibuffer-completion post-command-hook.
136
137Is run in minibuffer after user input when `icomplete-mode' is non-nil.
138Use `icomplete-mode' function to set it up properly for incremental
139minibuffer completion.")
140(add-hook 'icomplete-post-command-hook 'icomplete-exhibit)
141
92f7d003 142(defun icomplete-get-keys (func-name)
1be5a284
RS
143 "Return strings naming keys bound to `func-name', or nil if none.
144Examines the prior, not current, buffer, presuming that current buffer
145is minibuffer."
146 (if (commandp func-name)
92f7d003
KH
147 (save-excursion
148 (let* ((sym (intern func-name))
1be5a284
RS
149 (buf (other-buffer))
150 (map (save-excursion (set-buffer buf) (current-local-map)))
151 (keys (where-is-internal sym map)))
92f7d003
KH
152 (if keys
153 (concat "<"
154 (mapconcat 'key-description
155 (sort keys
156 #'(lambda (x y)
157 (< (length x) (length y))))
158 ", ")
159 ">"))))))
160
239c87a1 161;;;_ > icomplete-mode (&optional prefix)
c89164c5 162;;;###autoload
47fda8fc 163(define-minor-mode icomplete-mode
4b404c58
GM
164 "Toggle incremental minibuffer completion for this Emacs session.
165With a numeric argument, turn Icomplete mode on iff ARG is positive."
47fda8fc
SM
166 :global t :group 'icomplete
167 (if icomplete-mode
4b404c58
GM
168 ;; The following is not really necessary after first time -
169 ;; no great loss.
47fda8fc
SM
170 (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)
171 (remove-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)))
239c87a1
RS
172
173;;;_ > icomplete-simple-completing-p ()
174(defun icomplete-simple-completing-p ()
239c87a1
RS
175 "Non-nil if current window is minibuffer that's doing simple completion.
176
177Conditions are:
178 the selected window is a minibuffer,
179 and not in the middle of macro execution,
47fda8fc 180 and `minibuffer-completion-table' is not a symbol (which would
81276211 181 indicate some non-standard, non-simple completion mechanism,
239c87a1
RS
182 like file-name and other custom-func completions)."
183
184 (and (window-minibuffer-p (selected-window))
efcf38c7 185 (not executing-kbd-macro)
47fda8fc
SM
186 ;; (or minibuffer-completing-file-name
187 (not (functionp minibuffer-completion-table)))) ;; )
d183f322 188
239c87a1 189;;;_ > icomplete-minibuffer-setup ()
239c87a1 190(defun icomplete-minibuffer-setup ()
239c87a1 191 "Run in minibuffer on activation to establish incremental completion.
d183f322 192Usually run by inclusion in `minibuffer-setup-hook'."
47fda8fc
SM
193 (when (and icomplete-mode (icomplete-simple-completing-p))
194 (add-hook 'pre-command-hook
195 (lambda () (run-hooks 'icomplete-pre-command-hook))
196 nil t)
197 (add-hook 'post-command-hook
198 (lambda () (run-hooks 'icomplete-post-command-hook))
199 nil t)
200 (run-hooks 'icomplete-minibuffer-setup-hook)))
1934dbf4
GM
201;\f
202
203
239c87a1
RS
204;;;_* Completion
205
206;;;_ > icomplete-tidy ()
207(defun icomplete-tidy ()
208 "Remove completions display \(if any) prior to new user input.
d183f322 209Should be run in on the minibuffer `pre-command-hook'. See `icomplete-mode'
239c87a1 210and `minibuffer-setup-hook'."
47fda8fc 211 (when icomplete-eoinput
239c87a1 212
47fda8fc
SM
213 (unless (>= icomplete-eoinput (point-max))
214 (let ((buffer-undo-list t)) ; prevent entry
215 (delete-region icomplete-eoinput (point-max))))
239c87a1 216
47fda8fc
SM
217 ;; Reestablish the safe value.
218 (setq icomplete-eoinput nil)))
d183f322 219
239c87a1 220;;;_ > icomplete-exhibit ()
d462ff97 221(defun icomplete-exhibit ()
239c87a1 222 "Insert icomplete completions display.
d183f322 223Should be run via minibuffer `post-command-hook'. See `icomplete-mode'
239c87a1 224and `minibuffer-setup-hook'."
47fda8fc
SM
225 (when (icomplete-simple-completing-p)
226 (save-excursion
227 (goto-char (point-max))
228 ;; Register the end of input, so we know where the extra stuff
229 ;; (match-status info) begins:
230 (setq icomplete-eoinput (point))
d462ff97 231 ; Insert the match-status information:
47fda8fc
SM
232 (if (and (> (point-max) (minibuffer-prompt-end))
233 buffer-undo-list ; Wait for some user input.
234 (or
235 ;; Don't bother with delay after certain number of chars:
236 (> (- (point) (field-beginning)) icomplete-max-delay-chars)
237 ;; Don't delay if alternatives number is small enough:
238 (and (sequencep minibuffer-completion-table)
239 (< (length minibuffer-completion-table)
240 icomplete-delay-completions-threshold))
241 ;; Delay - give some grace time for next keystroke, before
242 ;; embarking on computing completions:
243 (sit-for icomplete-compute-delay)))
244 (let ((text (while-no-input
245 (icomplete-completions
246 (field-string)
247 minibuffer-completion-table
248 minibuffer-completion-predicate
249 (not minibuffer-completion-confirm))))
250 (buffer-undo-list t))
251 (if text (insert text)))))))
d183f322 252
239c87a1
RS
253;;;_ > icomplete-completions (name candidates predicate require-match)
254(defun icomplete-completions (name candidates predicate require-match)
d462ff97
RS
255 "Identify prospective candidates for minibuffer completion.
256
c89164c5 257The display is updated with each minibuffer keystroke during
d462ff97
RS
258minibuffer completion.
259
260Prospective completion suffixes (if any) are displayed, bracketed by
261one of \(), \[], or \{} pairs. The choice of brackets is as follows:
262
263 \(...) - a single prospect is identified and matching is enforced,
264 \[...] - a single prospect is identified but matching is optional, or
265 \{...} - multiple prospects, separated by commas, are indicated, and
81276211 266 further input is required to distinguish a single one.
d462ff97 267
81276211 268The displays for unambiguous matches have ` [Matched]' appended
d183f322 269\(whether complete or not), or ` \[No matches]', if no eligible
1be5a284 270matches exist. \(Keybindings for uniquely matched commands
92f7d003
KH
271are exhibited within the square braces.)"
272
273 ;; 'all-completions' doesn't like empty
274 ;; minibuffer-completion-table's (ie: (nil))
275 (if (and (listp candidates) (null (car candidates)))
276 (setq candidates nil))
d462ff97
RS
277
278 (let ((comps (all-completions name candidates predicate))
279 ; "-determined" - only one candidate
280 (open-bracket-determined (if require-match "(" "["))
1934dbf4
GM
281 (close-bracket-determined (if require-match ")" "]")))
282 ;; `concat'/`mapconcat' is the slow part. With the introduction of
283 ;; `icomplete-prospects-length', there is no need for `catch'/`throw'.
284 (if (null comps) (format " %sNo matches%s"
285 open-bracket-determined
286 close-bracket-determined)
287 (let* ((most-try (try-completion name (mapcar (function list) comps)))
288 (most (if (stringp most-try) most-try (car comps)))
289 (most-len (length most))
290 (determ (and (> most-len (length name))
291 (concat open-bracket-determined
292 (substring most (length name))
293 close-bracket-determined)))
47fda8fc 294 ;;"-prospects" - more than one candidate
1934dbf4
GM
295 (prospects-len 0)
296 prospects most-is-exact comp)
297 (if (eq most-try t)
298 (setq prospects nil)
299 (while (and comps (< prospects-len icomplete-prospects-length))
300 (setq comp (substring (car comps) most-len)
301 comps (cdr comps))
302 (cond ((string-equal comp "") (setq most-is-exact t))
303 ((member comp prospects))
304 (t (setq prospects (cons comp prospects)
305 prospects-len (+ (length comp) 1 prospects-len))))))
306 (if prospects
307 (concat determ
47fda8fc 308 "{"
1934dbf4
GM
309 (and most-is-exact ",")
310 (mapconcat 'identity
311 (sort prospects (function string-lessp))
312 ",")
313 (and comps ",...")
47fda8fc 314 "}")
1934dbf4
GM
315 (concat determ
316 " [Matched"
317 (let ((keys (and icomplete-show-key-bindings
318 (commandp (intern-soft most))
319 (icomplete-get-keys most))))
47fda8fc 320 (if keys (concat "; " keys) ""))
1934dbf4 321 "]"))))))
d462ff97 322
239c87a1
RS
323;;;_* Local emacs vars.
324;;;Local variables:
325;;;outline-layout: (-2 :)
326;;;End:
d462ff97 327
47fda8fc 328;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f
d462ff97 329;;; icomplete.el ends here