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