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