icomplete.el 12 KB
Newer Older
Dave Love's avatar
Dave Love committed
1
;;; icomplete.el --- minibuffer completion incremental feedback
2

3 4
;; Copyright (C) 1992, 1993, 1994, 1997, 1999, 2001, 2002, 2003,
;;   2004, 2005 Free Software Foundation, Inc.
Richard M. Stallman's avatar
Richard M. Stallman committed
5

6 7 8 9
;; Author: Ken Manheimer <klm@i.am>
;; Maintainer: Ken Manheimer <klm@i.am>
;; Created: Mar 1993 Ken Manheimer, klm@nist.gov - first release to usenet
;; Last update: Ken Manheimer <klm@i.am>, 11/18/1999.
Richard M. Stallman's avatar
Richard M. Stallman committed
10
;; Keywords: help, abbrev
Richard M. Stallman's avatar
Richard M. Stallman committed
11

12
;; This file is part of GNU Emacs.
Richard M. Stallman's avatar
Richard M. Stallman committed
13

14 15 16 17
;; GNU Emacs is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
Richard M. Stallman's avatar
Richard M. Stallman committed
18

19 20 21 22
;; GNU Emacs is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.
23

24
;; You should have received a copy of the GNU General Public License
Erik Naggum's avatar
Erik Naggum committed
25
;; along with GNU Emacs; see the file COPYING.  If not, write to the
Lute Kamstra's avatar
Lute Kamstra committed
26 27
;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
;; Boston, MA 02110-1301, USA.
Richard M. Stallman's avatar
Richard M. Stallman committed
28

29
;;; Commentary:
Richard M. Stallman's avatar
Richard M. Stallman committed
30

Erik Naggum's avatar
Erik Naggum committed
31 32 33 34 35
;; Loading this package implements a more fine-grained minibuffer
;; completion feedback scheme.  Prospective completions are concisely
;; indicated within the minibuffer itself, with each successive
;; keystroke.

Stephen Eglen's avatar
Stephen Eglen committed
36
;; See `icomplete-completions' docstring for a description of the
Erik Naggum's avatar
Erik Naggum committed
37 38 39 40 41 42
;; icomplete display format.

;; See the `icomplete-minibuffer-setup-hook' docstring for a means to
;; customize icomplete setup for interoperation with other
;; minibuffer-oriented packages.

43 44 45 46 47 48 49 50
;; To activate icomplete mode, load the package and use the
;; `icomplete-mode' function.  You can subsequently deactivate it by
;; invoking the function icomplete-mode with a negative prefix-arg
;; (C-U -1 ESC-x icomplete-mode).  Also, you can prevent activation of
;; the mode during package load by first setting the variable
;; `icomplete-mode' to nil.  Icompletion can be enabled any time after
;; the package is loaded by invoking icomplete-mode without a prefix
;; arg.
51

Erik Naggum's avatar
Erik Naggum committed
52 53 54 55
;; Thanks to everyone for their suggestions for refinements of this
;; package.  I particularly have to credit Michael Cook, who
;; implemented an incremental completion style in his 'iswitch'
;; functions that served as a model for icomplete.  Some other
Stephen Eglen's avatar
Stephen Eglen committed
56
;; contributors: Noah Friedman (restructuring as minor mode), Colin
57
;; Rafferty (lemacs reconciliation), Lars Lindberg, RMS, and others.
Erik Naggum's avatar
Erik Naggum committed
58 59

;; klm.
60

61 62 63
;;; Code:

;;;_* Provide
Richard M. Stallman's avatar
Richard M. Stallman committed
64 65
(provide 'icomplete)

Stephen Eglen's avatar
Stephen Eglen committed
66 67 68 69 70 71

(defgroup icomplete nil
  "Show completions dynamically in minibuffer."
  :prefix "icomplete-"
  :group 'minibuffer)

72 73 74 75 76 77
;;;_* User Customization variables
(defcustom icomplete-prospects-length 80
  "*Length of string displaying the prospects."
  :type 'integer
  :group 'icomplete)

Stephen Eglen's avatar
Stephen Eglen committed
78
(defcustom icomplete-compute-delay .3
79
  "*Completions-computation stall, used only with large-number
Stephen Eglen's avatar
Stephen Eglen committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
completions - see `icomplete-delay-completions-threshold'."
  :type 'number
  :group 'icomplete)

(defcustom icomplete-delay-completions-threshold 400
  "*Pending-completions number over which to apply icomplete-compute-delay."
  :type 'integer
  :group 'icomplete)

(defcustom icomplete-max-delay-chars 3
  "*Maximum number of initial chars to apply icomplete compute delay."
  :type 'integer
  :group 'icomplete)

(defcustom icomplete-show-key-bindings t
  "*If non-nil, show key bindings as well as completion for sole matches."
  :type 'boolean
  :group 'icomplete)

(defcustom icomplete-minibuffer-setup-hook nil
100 101 102 103
  "*Icomplete-specific customization of minibuffer setup.

This hook is run during minibuffer setup iff icomplete will be active.
It is intended for use in customizing icomplete for interoperation
104
with other features and packages.  For instance:
105

106
  \(add-hook 'icomplete-minibuffer-setup-hook
107 108
	    \(function
	     \(lambda ()
109 110
	       \(make-local-variable 'max-mini-window-height)
	       \(setq max-mini-window-height 3))))
111

112
will constrain Emacs to a maximum minibuffer height of 3 lines when
Stephen Eglen's avatar
Stephen Eglen committed
113 114 115 116 117 118
icompletion is occurring."
  :type 'hook
  :group 'icomplete)


;;;_* Initialization
Richard M. Stallman's avatar
Richard M. Stallman committed
119

120
;;;_ + Internal Variables
121 122
;;;_  = icomplete-eoinput nil
(defvar icomplete-eoinput nil
Richard M. Stallman's avatar
Richard M. Stallman committed
123 124
  "Point where minibuffer input ends and completion info begins.")
(make-variable-buffer-local 'icomplete-eoinput)
125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
;;;_  = icomplete-pre-command-hook
(defvar icomplete-pre-command-hook nil
  "Incremental-minibuffer-completion pre-command-hook.

Is run in minibuffer before user input when `icomplete-mode' is non-nil.
Use `icomplete-mode' function to set it up properly for incremental
minibuffer completion.")
(add-hook 'icomplete-pre-command-hook 'icomplete-tidy)
;;;_  = icomplete-post-command-hook
(defvar icomplete-post-command-hook nil
  "Incremental-minibuffer-completion post-command-hook.

Is run in minibuffer after user input when `icomplete-mode' is non-nil.
Use `icomplete-mode' function to set it up properly for incremental
minibuffer completion.")
(add-hook 'icomplete-post-command-hook 'icomplete-exhibit)

142
(defun icomplete-get-keys (func-name)
143 144 145 146
  "Return strings naming keys bound to `func-name', or nil if none.
Examines the prior, not current, buffer, presuming that current buffer
is minibuffer."
  (if (commandp func-name)
147 148
    (save-excursion
      (let* ((sym (intern func-name))
149 150 151
	     (buf (other-buffer))
	     (map (save-excursion (set-buffer buf) (current-local-map)))
	     (keys (where-is-internal sym map)))
152 153 154 155 156 157 158 159 160
	(if keys
	    (concat "<"
		    (mapconcat 'key-description
			       (sort keys
				     #'(lambda (x y)
					 (< (length x) (length y))))
			       ", ")
		    ">"))))))

161
;;;_ > icomplete-mode (&optional prefix)
162
;;;###autoload
163
(define-minor-mode icomplete-mode
164 165
  "Toggle incremental minibuffer completion for this Emacs session.
With a numeric argument, turn Icomplete mode on iff ARG is positive."
166 167
  :global t :group 'icomplete
  (if icomplete-mode
168 169
      ;; The following is not really necessary after first time -
      ;; no great loss.
170 171
      (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)
    (remove-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)))
172 173 174 175 176 177 178 179

;;;_ > icomplete-simple-completing-p ()
(defun icomplete-simple-completing-p ()
  "Non-nil if current window is minibuffer that's doing simple completion.

Conditions are:
   the selected window is a minibuffer,
   and not in the middle of macro execution,
180
   and `minibuffer-completion-table' is not a symbol (which would
181
       indicate some non-standard, non-simple completion mechanism,
182 183 184
       like file-name and other custom-func completions)."

  (and (window-minibuffer-p (selected-window))
185
       (not executing-kbd-macro)
186
       minibuffer-completion-table
187 188
       ;; (or minibuffer-completing-file-name
       (not (functionp minibuffer-completion-table)))) ;; )
189

190 191 192
;;;_ > icomplete-minibuffer-setup ()
(defun icomplete-minibuffer-setup ()
  "Run in minibuffer on activation to establish incremental completion.
193
Usually run by inclusion in `minibuffer-setup-hook'."
194 195 196 197 198 199 200 201
  (when (and icomplete-mode (icomplete-simple-completing-p))
    (add-hook 'pre-command-hook
	      (lambda () (run-hooks 'icomplete-pre-command-hook))
	      nil t)
    (add-hook 'post-command-hook
	      (lambda () (run-hooks 'icomplete-post-command-hook))
	      nil t)
    (run-hooks 'icomplete-minibuffer-setup-hook)))
202 203 204
;


205 206 207 208 209
;;;_* Completion

;;;_ > icomplete-tidy ()
(defun icomplete-tidy ()
  "Remove completions display \(if any) prior to new user input.
210
Should be run in on the minibuffer `pre-command-hook'.  See `icomplete-mode'
211
and `minibuffer-setup-hook'."
212
  (when icomplete-eoinput
213

214 215 216
    (unless (>= icomplete-eoinput (point-max))
      (let ((buffer-undo-list t)) ; prevent entry
	(delete-region icomplete-eoinput (point-max))))
217

218 219
    ;; Reestablish the safe value.
    (setq icomplete-eoinput nil)))
220

221
;;;_ > icomplete-exhibit ()
Richard M. Stallman's avatar
Richard M. Stallman committed
222
(defun icomplete-exhibit ()
223
  "Insert icomplete completions display.
224
Should be run via minibuffer `post-command-hook'.  See `icomplete-mode'
225
and `minibuffer-setup-hook'."
226 227 228 229 230 231
  (when (icomplete-simple-completing-p)
    (save-excursion
      (goto-char (point-max))
      ;; Register the end of input, so we know where the extra stuff
      ;; (match-status info) begins:
      (setq icomplete-eoinput (point))
Richard M. Stallman's avatar
Richard M. Stallman committed
232
                                        ; Insert the match-status information:
233 234 235 236 237 238 239 240 241 242 243 244 245
      (if (and (> (point-max) (minibuffer-prompt-end))
	       buffer-undo-list		; Wait for some user input.
	       (or
		;; Don't bother with delay after certain number of chars:
		(> (- (point) (field-beginning)) icomplete-max-delay-chars)
		;; Don't delay if alternatives number is small enough:
		(and (sequencep minibuffer-completion-table)
		     (< (length minibuffer-completion-table)
			icomplete-delay-completions-threshold))
		;; Delay - give some grace time for next keystroke, before
		;; embarking on computing completions:
		(sit-for icomplete-compute-delay)))
	  (let ((text (while-no-input
246 247 248 249 250 251
			(list
			 (icomplete-completions
			  (field-string)
			  minibuffer-completion-table
			  minibuffer-completion-predicate
			  (not minibuffer-completion-confirm)))))
252
		(buffer-undo-list t))
253 254
	    ;; Do nothing if while-no-input was aborted.
	    (if (consp text) (insert (car text))))))))
255

256 257
;;;_ > icomplete-completions (name candidates predicate require-match)
(defun icomplete-completions (name candidates predicate require-match)
Richard M. Stallman's avatar
Richard M. Stallman committed
258 259
  "Identify prospective candidates for minibuffer completion.

260
The display is updated with each minibuffer keystroke during
Richard M. Stallman's avatar
Richard M. Stallman committed
261 262 263 264 265 266 267 268
minibuffer completion.

Prospective completion suffixes (if any) are displayed, bracketed by
one of \(), \[], or \{} pairs.  The choice of brackets is as follows:

  \(...) - a single prospect is identified and matching is enforced,
  \[...] - a single prospect is identified but matching is optional, or
  \{...} - multiple prospects, separated by commas, are indicated, and
269
          further input is required to distinguish a single one.
Richard M. Stallman's avatar
Richard M. Stallman committed
270

271
The displays for unambiguous matches have ` [Matched]' appended
272
\(whether complete or not), or ` \[No matches]', if no eligible
273
matches exist.  \(Keybindings for uniquely matched commands
274 275 276 277 278 279
are exhibited within the square braces.)"

  ;; 'all-completions' doesn't like empty
  ;; minibuffer-completion-table's (ie: (nil))
  (if (and (listp candidates) (null (car candidates)))
      (setq candidates nil))
Richard M. Stallman's avatar
Richard M. Stallman committed
280 281 282 283

  (let ((comps (all-completions name candidates predicate))
                                        ; "-determined" - only one candidate
        (open-bracket-determined (if require-match "(" "["))
284 285 286 287 288 289 290 291 292 293 294 295 296
        (close-bracket-determined (if require-match ")" "]")))
    ;; `concat'/`mapconcat' is the slow part.  With the introduction of
    ;; `icomplete-prospects-length', there is no need for `catch'/`throw'.
    (if (null comps) (format " %sNo matches%s"
			     open-bracket-determined
			     close-bracket-determined)
      (let* ((most-try (try-completion name (mapcar (function list) comps)))
	     (most (if (stringp most-try) most-try (car comps)))
	     (most-len (length most))
	     (determ (and (> most-len (length name))
			  (concat open-bracket-determined
				  (substring most (length name))
				  close-bracket-determined)))
297
	     ;;"-prospects" - more than one candidate
298 299 300 301 302 303 304 305 306 307 308 309 310
	     (prospects-len 0)
	     prospects most-is-exact comp)
	(if (eq most-try t)
	    (setq prospects nil)
	  (while (and comps (< prospects-len icomplete-prospects-length))
	    (setq comp (substring (car comps) most-len)
		  comps (cdr comps))
	    (cond ((string-equal comp "") (setq most-is-exact t))
		  ((member comp prospects))
		  (t (setq prospects (cons comp prospects)
			   prospects-len (+ (length comp) 1 prospects-len))))))
	(if prospects
	    (concat determ
311
		    "{"
312 313 314 315 316
		    (and most-is-exact ",")
		    (mapconcat 'identity
			       (sort prospects (function string-lessp))
			       ",")
		    (and comps ",...")
317
		    "}")
318 319 320 321 322
	  (concat determ
		  " [Matched"
		  (let ((keys (and icomplete-show-key-bindings
				   (commandp (intern-soft most))
				   (icomplete-get-keys most))))
323
		    (if keys (concat "; " keys) ""))
324
		  "]"))))))
Richard M. Stallman's avatar
Richard M. Stallman committed
325

326 327 328 329
;;;_* Local emacs vars.
;;;Local variables:
;;;outline-layout: (-2 :)
;;;End:
Richard M. Stallman's avatar
Richard M. Stallman committed
330

331
;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f
Richard M. Stallman's avatar
Richard M. Stallman committed
332
;;; icomplete.el ends here