Initial revision
[bpt/emacs.git] / lisp / icomplete.el
CommitLineData
d462ff97
RS
1;;; icomplete.el - minibuffer completion incremental feedback
2;;; This package is in the publid domain.
3
4;;; Author: Ken Manheimer <klm@nist.gov>
5;;; Maintainer: Ken Manheimer <klm@nist.gov>
6;;; Version: icomplete.el,v 3.2 1993/11/19 18:42:52 klm Exp klm
7;;; Created: Mar 1993 klm@nist.gov - first release to usenet
8;;; Keywords: help, abbrev
9
10;;; Commentary:
11
12;;; Loading this package implements a more finely-grained completion
13;;; feedback scheme, indicating, within the minibuffer, the
14;;; prospective minibuffer completion candidates, as you type. See
15;;; the documentation string for 'icomplete-prompt' for a specific
16;;; description of icompletion.
17
18;;; This will not work on Emacs 18 versions - there may be a version
19;;; for v18 in the elisp archives, at archive.cis.ohio-state.edu, in
20;;; /pub/gnu/emacs/elisp-archive.
21
22;;; Code:
23
24;;;_ + Provide
25(provide 'icomplete)
26
27;;;_ + User Customization variables
28;;;_ = icomplete-inhibit
29(defvar icomplete-inhibit nil
30 "*Set this variable to t at any time to inhibit icomplete.")
31
32;;;_ + Setup
33;;;_ - Internal Variables
34;;;_ = icomplete-eoinput 1
35(defvar icomplete-eoinput 1
36 "Point where minibuffer input ends and completion info begins.")
37(make-variable-buffer-local 'icomplete-eoinput)
38;;;_ > icomplete-prime-session ()
39(defun icomplete-prime-session ()
40
41 "Prep emacs v 19 for icompletion. For emacs v19.18 and later revs,
42icomplete is installed in 'minibuffer-setup-hook'. Global pre- and
43post-command-hook functions are used in v19.17 and earlier revs."
44
45 (let* ((v19-rev (and (string-match "^19\\.\\([0-9]+\\)" emacs-version)
46 (string-to-int (substring emacs-version
47 (match-beginning 1)
48 (match-end 1))))))
49
50 (cond ((and v19-rev ; emacs v 19, some rev,
51 (> v19-rev 17))
52 ;; Post v19rev17, has minibuffer-setup-hook, use it:
53 (add-hook 'minibuffer-setup-hook 'icomplete-prime-minibuffer))
54 (v19-rev
55 ;; v19rev17 and prior (including lucid): use global
56 ;; pre- and post-command-hooks, instead:
57 (add-hook 'pre-command-hook 'icomplete-pre-command-hook 'append)
58 (add-hook 'post-command-hook
59 'icomplete-post-command-hook 'append))
60 ((format "icomplete: non v19 emacs, %s - %s"
61 emacs-version "try elisp-archive icomplete")))))
62;;;_ > icomplete-prime-minibuffer ()
63(defun icomplete-prime-minibuffer ()
64
65 "Prep emacs, v 19.18 or later, for icomplete. \(icomplete-prime-
66session establishes global hooks, instead, in emacs 19 versions 19.17
67and prior.\) Run via minibuffer-setup-hook \(emacs 19.18 or later\),
68adds icomplete pre- and post-command hooks to do icomplete display
69management."
70
71 ;; We append the hooks because preliminary version of blink-paren
72 ;; post-command-hook i have interferes with proper operation of
73 ;; minibuffer quit.
74 (make-local-variable 'pre-command-hook)
75 (make-local-variable 'post-command-hook)
76 (add-hook 'pre-command-hook 'icomplete-pre-command-hook)
77 (add-hook 'post-command-hook 'icomplete-post-command-hook))
78;;;_ > icomplete-window-minibuffer-p ()
79(defmacro icomplete-window-minibuffer-p ()
80
81 "Returns non-nil if current window is a minibuffer window.
82Trivially equates to '(window-minibuffer-p nil)', with the nil
83provided in case the argument is not optional in Lucid emacs (which
84some net correspondance seems to indicate)."
85
86 '(window-minibuffer-p nil))
87
88;;;_ + Completion
89;;;_ - Completion feedback hooks
90;;;_ > icomplete-pre-command-hook ()
91(defun icomplete-pre-command-hook ()
92 "Cleanup completions exhibit before user's new input (or whatever) is dealt
93with."
94 (if (and (icomplete-window-minibuffer-p)
95 (not (symbolp minibuffer-completion-table))
96 (not icomplete-inhibit))
97 (if (and (boundp 'icomplete-eoinput)
98 icomplete-eoinput)
99 (if (> icomplete-eoinput (point-max))
100 ;; Oops, got rug pulled out from under us - reinit:
101 (setq icomplete-eoinput (point-max))
102 (let ((buffer-undo-list buffer-undo-list )) ; prevent entry
103 (delete-region icomplete-eoinput (point-max))))
104 (make-local-variable 'icomplete-eoinput)
105 (setq icomplete-eoinput 1))))
106;;;_ > icomplete-post-command-hook ()
107(defun icomplete-post-command-hook ()
108 "Exhibit completions, leaving icomplete-eoinput with position where user
109input leaves off and exhibit begins, so icomplete-pre-command-hook can
110subsequently cleanup."
111 (if (and (icomplete-window-minibuffer-p) ; ... in a minibuffer.
112 (not icomplete-inhibit) ; ... not specifically inhibited.
113 ;(sit-for 0) ; ... redisplay and if there's input
114 ; waiting, then don't icomplete
115 ; (stigs suggestion) (too jumpy!)
116 ;; Inhibit for file-name and other custom-func completions:
117 (not (symbolp minibuffer-completion-table))
118 )
119 (let ((buffer-undo-list buffer-undo-list )) ; prevent entry
120 (icomplete-exhibit))))
121;;;_ > icomplete-window-setup-hook ()
122(defun icomplete-window-setup-hook ()
123 "Exhibit completions, leaving icomplete-eoinput with position where user
124input leaves off and exhibit begins, so icomplete-pre-command-hook can
125subsequently cleanup."
126 (if (and (icomplete-window-minibuffer-p) ; ... in a minibuffer.
127 )
128 (message "ic ws doing")(sit-for 1)))
129;;;_ > icomplete-exhibit ()
130(defun icomplete-exhibit ()
131 "Exhibit completions, leaving icomplete-eoinput with position where user
132input leaves off and exhibit begins, so icomplete-pre-command-hook can
133subsequently cleanup."
134 (if (not (symbolp minibuffer-completion-table))
135 (let ((contents (buffer-substring (point-min)(point-max)))
136 (buffer-undo-list t))
137 (save-excursion
138 (goto-char (point-max))
139 ; Register the end of input, so we
140 ; know where the extra stuff
141 ; (match-status info) begins:
142 (if (not (boundp 'icomplete-eoinput))
143 ;; In case it got wiped out by major mode business:
144 (make-local-variable 'icomplete-eoinput))
145 (setq icomplete-eoinput (point))
146 ; Insert the match-status information:
147 (if (> (point-max) 1)
148 (insert-string
149 (icomplete-prompt contents
150 minibuffer-completion-table
151 minibuffer-completion-predicate
152 (not
153 minibuffer-completion-confirm))))))))
154
155;;;_ - Completion feedback producer
156;;;_ > icomplete-prompt (name candidates predicate require-match)
157(defun icomplete-prompt (name candidates predicate require-match)
158 "Identify prospective candidates for minibuffer completion.
159
160The display is updated with each minibuffer keystroke when icomplete
161is enabled \(by loading the 'icomplete' elisp package\) and doing
162minibuffer completion.
163
164Prospective completion suffixes (if any) are displayed, bracketed by
165one of \(), \[], or \{} pairs. The choice of brackets is as follows:
166
167 \(...) - a single prospect is identified and matching is enforced,
168 \[...] - a single prospect is identified but matching is optional, or
169 \{...} - multiple prospects, separated by commas, are indicated, and
170 further input is required to distingish a single one.
171
172The displays for disambiguous matches have \" [Matched]\" appended
173\(whether complete or not), or \" \[No matches]\", if no eligible
174matches exist."
175
176 (let ((comps (all-completions name candidates predicate))
177 ; "-determined" - only one candidate
178 (open-bracket-determined (if require-match "(" "["))
179 (close-bracket-determined (if require-match ")" "]"))
180 ;"-prospects" - more than one candidate
181 (open-bracket-prospects "{")
182 (close-bracket-prospects "}")
183 )
184 (cond ((null comps) (format " %sNo matches%s"
185 open-bracket-determined
186 close-bracket-determined))
187 ((null (cdr comps)) ;one match
188 (concat (if (and (> (length (car comps))
189 (length name)))
190 (concat open-bracket-determined
191 (substring (car comps) (length name))
192 close-bracket-determined)
193 "")
194 " [Matched]"))
195 (t ;multiple matches
196 (let* ((most (try-completion name candidates predicate))
197 (most-len (length most))
198 most-is-exact
199 (alternatives
200 (apply
201 'concat
202 (cdr (apply 'append
203 (mapcar '(lambda (com)
204 (if (= (length com) most-len)
205 ;; Most is one exact match,
206 ;; note that and leave out
207 ;; for later indication:
208 (progn
209 (setq most-is-exact t)
210 ())
211 (list ","
212 (substring com
213 most-len))))
214 comps))))))
215 (concat (and (> most-len (length name))
216 (concat open-bracket-determined
217 (substring most (length name))
218 close-bracket-determined))
219 open-bracket-prospects
220 (if most-is-exact
221 (concat "," alternatives)
222 alternatives)
223 close-bracket-prospects))))))
224
225;;;_ + Initialization
226(icomplete-prime-session)
227
228;;;_* Local emacs vars.
229'(
230Local variables:
231eval: (save-excursion
232 (if (not (condition-case err (outline-mode t)
233 (wrong-number-of-arguments nil)))
234 (progn
235 (message
236 "Allout outline-mode not loaded, not adjusting buffer exposure")
237 (sit-for 1))
238 (message "Adjusting '%s' visibility" (buffer-name))
239 (outline-lead-with-comment-string ";;;_")
240 (goto-char 0)
241 (outline-exposure -1 0)))
242End:)
243
244;;; icomplete.el ends here