Mercurial > emacs
comparison lisp/icomplete.el @ 88155:d7ddb3e565de
sync with trunk
author | Henrik Enberg <henrik.enberg@telia.com> |
---|---|
date | Mon, 16 Jan 2006 00:03:54 +0000 |
parents | 37645a051842 |
children |
comparison
equal
deleted
inserted
replaced
88154:8ce476d3ba36 | 88155:d7ddb3e565de |
---|---|
1 ;;; icomplete.el --- minibuffer completion incremental feedback | 1 ;;; icomplete.el --- minibuffer completion incremental feedback |
2 | 2 |
3 ;; Copyright (C) 1992, 1993, 1994, 1997, 1999, 2001 | 3 ;; Copyright (C) 1992, 1993, 1994, 1997, 1999, 2001, 2002, 2003, |
4 ;;; Free Software Foundation, Inc. | 4 ;; 2004, 2005 Free Software Foundation, Inc. |
5 | 5 |
6 ;; Author: Ken Manheimer <klm@i.am> | 6 ;; Author: Ken Manheimer <klm@i.am> |
7 ;; Maintainer: 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 | 8 ;; Created: Mar 1993 Ken Manheimer, klm@nist.gov - first release to usenet |
9 ;; Last update: Ken Manheimer <klm@i.am>, 11/18/1999. | 9 ;; Last update: Ken Manheimer <klm@i.am>, 11/18/1999. |
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
22 ;; GNU General Public License for more details. | 22 ;; GNU General Public License for more details. |
23 | 23 |
24 ;; You should have received a copy of the GNU General Public License | 24 ;; You should have received a copy of the GNU General Public License |
25 ;; along with GNU Emacs; see the file COPYING. If not, write to the | 25 ;; along with GNU Emacs; see the file COPYING. If not, write to the |
26 ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 26 ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
27 ;; Boston, MA 02111-1307, USA. | 27 ;; Boston, MA 02110-1301, USA. |
28 | 28 |
29 ;;; Commentary: | 29 ;;; Commentary: |
30 | 30 |
31 ;; Loading this package implements a more fine-grained minibuffer | 31 ;; Loading this package implements a more fine-grained minibuffer |
32 ;; completion feedback scheme. Prospective completions are concisely | 32 ;; completion feedback scheme. Prospective completions are concisely |
67 (defgroup icomplete nil | 67 (defgroup icomplete nil |
68 "Show completions dynamically in minibuffer." | 68 "Show completions dynamically in minibuffer." |
69 :prefix "icomplete-" | 69 :prefix "icomplete-" |
70 :group 'minibuffer) | 70 :group 'minibuffer) |
71 | 71 |
72 (defcustom icomplete-mode nil | |
73 "*Toggle incremental minibuffer completion. | |
74 As text is typed into the minibuffer, prospective completions are indicated | |
75 in the minibuffer. | |
76 Setting this variable directly does not take effect; | |
77 use either \\[customize] or the function `icomplete-mode'." | |
78 :set (lambda (symbol value) | |
79 (icomplete-mode (if value 1 -1))) | |
80 :initialize 'custom-initialize-default | |
81 :type 'boolean | |
82 :group 'icomplete | |
83 :require 'icomplete) | |
84 | |
85 ;;;_* User Customization variables | 72 ;;;_* User Customization variables |
86 (defcustom icomplete-prospects-length 80 | 73 (defcustom icomplete-prospects-length 80 |
87 "*Length of string displaying the prospects." | 74 "*Length of string displaying the prospects." |
88 :type 'integer | 75 :type 'integer |
89 :group 'icomplete) | 76 :group 'icomplete) |
129 | 116 |
130 | 117 |
131 ;;;_* Initialization | 118 ;;;_* Initialization |
132 | 119 |
133 ;;;_ + Internal Variables | 120 ;;;_ + Internal Variables |
134 ;;;_ = icomplete-eoinput 1 | 121 ;;;_ = icomplete-eoinput nil |
135 (defvar icomplete-eoinput 1 | 122 (defvar icomplete-eoinput nil |
136 "Point where minibuffer input ends and completion info begins.") | 123 "Point where minibuffer input ends and completion info begins.") |
137 (make-variable-buffer-local 'icomplete-eoinput) | 124 (make-variable-buffer-local 'icomplete-eoinput) |
138 ;;;_ = icomplete-pre-command-hook | 125 ;;;_ = icomplete-pre-command-hook |
139 (defvar icomplete-pre-command-hook nil | 126 (defvar icomplete-pre-command-hook nil |
140 "Incremental-minibuffer-completion pre-command-hook. | 127 "Incremental-minibuffer-completion pre-command-hook. |
171 ", ") | 158 ", ") |
172 ">")))))) | 159 ">")))))) |
173 | 160 |
174 ;;;_ > icomplete-mode (&optional prefix) | 161 ;;;_ > icomplete-mode (&optional prefix) |
175 ;;;###autoload | 162 ;;;###autoload |
176 (defun icomplete-mode (&optional arg) | 163 (define-minor-mode icomplete-mode |
177 "Toggle incremental minibuffer completion for this Emacs session. | 164 "Toggle incremental minibuffer completion for this Emacs session. |
178 With a numeric argument, turn Icomplete mode on iff ARG is positive." | 165 With a numeric argument, turn Icomplete mode on iff ARG is positive." |
179 (interactive "P") | 166 :global t :group 'icomplete |
180 (let ((on-p (if (null arg) | 167 (if icomplete-mode |
181 (not icomplete-mode) | |
182 (> (prefix-numeric-value arg) 0)))) | |
183 (setq icomplete-mode on-p) | |
184 (when on-p | |
185 ;; The following is not really necessary after first time - | 168 ;; The following is not really necessary after first time - |
186 ;; no great loss. | 169 ;; no great loss. |
187 (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup)))) | 170 (add-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup) |
171 (remove-hook 'minibuffer-setup-hook 'icomplete-minibuffer-setup))) | |
188 | 172 |
189 ;;;_ > icomplete-simple-completing-p () | 173 ;;;_ > icomplete-simple-completing-p () |
190 (defun icomplete-simple-completing-p () | 174 (defun icomplete-simple-completing-p () |
191 "Non-nil if current window is minibuffer that's doing simple completion. | 175 "Non-nil if current window is minibuffer that's doing simple completion. |
192 | 176 |
193 Conditions are: | 177 Conditions are: |
194 the selected window is a minibuffer, | 178 the selected window is a minibuffer, |
195 and not in the middle of macro execution, | 179 and not in the middle of macro execution, |
196 and minibuffer-completion-table is not a symbol (which would | 180 and `minibuffer-completion-table' is not a symbol (which would |
197 indicate some non-standard, non-simple completion mechanism, | 181 indicate some non-standard, non-simple completion mechanism, |
198 like file-name and other custom-func completions)." | 182 like file-name and other custom-func completions)." |
199 | 183 |
200 (and (window-minibuffer-p (selected-window)) | 184 (and (window-minibuffer-p (selected-window)) |
201 (not executing-kbd-macro) | 185 (not executing-kbd-macro) |
202 (not (symbolp minibuffer-completion-table)))) | 186 minibuffer-completion-table |
187 ;; (or minibuffer-completing-file-name | |
188 (not (functionp minibuffer-completion-table)))) ;; ) | |
203 | 189 |
204 ;;;_ > icomplete-minibuffer-setup () | 190 ;;;_ > icomplete-minibuffer-setup () |
205 ;;;###autoload | |
206 (defun icomplete-minibuffer-setup () | 191 (defun icomplete-minibuffer-setup () |
207 "Run in minibuffer on activation to establish incremental completion. | 192 "Run in minibuffer on activation to establish incremental completion. |
208 Usually run by inclusion in `minibuffer-setup-hook'." | 193 Usually run by inclusion in `minibuffer-setup-hook'." |
209 (cond ((and icomplete-mode (icomplete-simple-completing-p)) | 194 (when (and icomplete-mode (icomplete-simple-completing-p)) |
210 (add-hook 'pre-command-hook | 195 (add-hook 'pre-command-hook |
211 (function (lambda () | 196 (lambda () (run-hooks 'icomplete-pre-command-hook)) |
212 (run-hooks 'icomplete-pre-command-hook))) | 197 nil t) |
213 nil t) | 198 (add-hook 'post-command-hook |
214 (add-hook 'post-command-hook | 199 (lambda () (run-hooks 'icomplete-post-command-hook)) |
215 (function (lambda () | 200 nil t) |
216 (run-hooks 'icomplete-post-command-hook))) | 201 (run-hooks 'icomplete-minibuffer-setup-hook))) |
217 nil t) | |
218 (run-hooks 'icomplete-minibuffer-setup-hook)))) | |
219 ; | 202 ; |
220 | 203 |
221 | 204 |
222 ;;;_* Completion | 205 ;;;_* Completion |
223 | 206 |
224 ;;;_ > icomplete-tidy () | 207 ;;;_ > icomplete-tidy () |
225 (defun icomplete-tidy () | 208 (defun icomplete-tidy () |
226 "Remove completions display \(if any) prior to new user input. | 209 "Remove completions display \(if any) prior to new user input. |
227 Should be run in on the minibuffer `pre-command-hook'. See `icomplete-mode' | 210 Should be run in on the minibuffer `pre-command-hook'. See `icomplete-mode' |
228 and `minibuffer-setup-hook'." | 211 and `minibuffer-setup-hook'." |
229 (if (icomplete-simple-completing-p) | 212 (when icomplete-eoinput |
230 (if (and (boundp 'icomplete-eoinput) | 213 |
231 icomplete-eoinput) | 214 (unless (>= icomplete-eoinput (point-max)) |
232 | 215 (let ((buffer-undo-list t)) ; prevent entry |
233 (if (> icomplete-eoinput (point-max)) | 216 (delete-region icomplete-eoinput (point-max)))) |
234 ;; Oops, got rug pulled out from under us - reinit: | 217 |
235 (setq icomplete-eoinput (point-max)) | 218 ;; Reestablish the safe value. |
236 (let ((buffer-undo-list buffer-undo-list )) ; prevent entry | 219 (setq icomplete-eoinput nil))) |
237 (delete-region icomplete-eoinput (point-max)))) | |
238 | |
239 ;; Reestablish the local variable 'cause minibuffer-setup is weird: | |
240 (make-local-variable 'icomplete-eoinput) | |
241 (setq icomplete-eoinput 1)))) | |
242 | 220 |
243 ;;;_ > icomplete-exhibit () | 221 ;;;_ > icomplete-exhibit () |
244 (defun icomplete-exhibit () | 222 (defun icomplete-exhibit () |
245 "Insert icomplete completions display. | 223 "Insert icomplete completions display. |
246 Should be run via minibuffer `post-command-hook'. See `icomplete-mode' | 224 Should be run via minibuffer `post-command-hook'. See `icomplete-mode' |
247 and `minibuffer-setup-hook'." | 225 and `minibuffer-setup-hook'." |
248 (if (icomplete-simple-completing-p) | 226 (when (icomplete-simple-completing-p) |
249 (let ((contents (buffer-substring (minibuffer-prompt-end)(point-max))) | 227 (save-excursion |
250 (buffer-undo-list t)) | 228 (goto-char (point-max)) |
251 (save-excursion | 229 ;; Register the end of input, so we know where the extra stuff |
252 (goto-char (point-max)) | 230 ;; (match-status info) begins: |
253 ; Register the end of input, so we | 231 (setq icomplete-eoinput (point)) |
254 ; know where the extra stuff | |
255 ; (match-status info) begins: | |
256 (if (not (boundp 'icomplete-eoinput)) | |
257 ;; In case it got wiped out by major mode business: | |
258 (make-local-variable 'icomplete-eoinput)) | |
259 (setq icomplete-eoinput (point)) | |
260 ; Insert the match-status information: | 232 ; Insert the match-status information: |
261 (if (and (> (point-max) (minibuffer-prompt-end)) | 233 (if (and (> (point-max) (minibuffer-prompt-end)) |
262 (or | 234 buffer-undo-list ; Wait for some user input. |
263 ;; Don't bother with delay after certain number of chars: | 235 (or |
264 (> (point-max) icomplete-max-delay-chars) | 236 ;; Don't bother with delay after certain number of chars: |
265 ;; Don't delay if alternatives number is small enough: | 237 (> (- (point) (field-beginning)) icomplete-max-delay-chars) |
266 (if minibuffer-completion-table | 238 ;; Don't delay if alternatives number is small enough: |
267 (cond ((numberp minibuffer-completion-table) | 239 (and (sequencep minibuffer-completion-table) |
268 (< minibuffer-completion-table | 240 (< (length minibuffer-completion-table) |
269 icomplete-delay-completions-threshold)) | 241 icomplete-delay-completions-threshold)) |
270 ((sequencep minibuffer-completion-table) | 242 ;; Delay - give some grace time for next keystroke, before |
271 (< (length minibuffer-completion-table) | 243 ;; embarking on computing completions: |
272 icomplete-delay-completions-threshold)) | 244 (sit-for icomplete-compute-delay))) |
273 )) | 245 (let ((text (while-no-input |
274 ;; Delay - give some grace time for next keystroke, before | 246 (list |
275 ;; embarking on computing completions: | 247 (icomplete-completions |
276 (sit-for icomplete-compute-delay))) | 248 (field-string) |
277 (insert | 249 minibuffer-completion-table |
278 (icomplete-completions contents | 250 minibuffer-completion-predicate |
279 minibuffer-completion-table | 251 (not minibuffer-completion-confirm))))) |
280 minibuffer-completion-predicate | 252 (buffer-undo-list t)) |
281 (not | 253 ;; Do nothing if while-no-input was aborted. |
282 minibuffer-completion-confirm)))))))) | 254 (if (consp text) (insert (car text)))))))) |
283 | 255 |
284 ;;;_ > icomplete-completions (name candidates predicate require-match) | 256 ;;;_ > icomplete-completions (name candidates predicate require-match) |
285 (defun icomplete-completions (name candidates predicate require-match) | 257 (defun icomplete-completions (name candidates predicate require-match) |
286 "Identify prospective candidates for minibuffer completion. | 258 "Identify prospective candidates for minibuffer completion. |
287 | 259 |
320 (most-len (length most)) | 292 (most-len (length most)) |
321 (determ (and (> most-len (length name)) | 293 (determ (and (> most-len (length name)) |
322 (concat open-bracket-determined | 294 (concat open-bracket-determined |
323 (substring most (length name)) | 295 (substring most (length name)) |
324 close-bracket-determined))) | 296 close-bracket-determined))) |
325 (open-bracket-prospects "{") | 297 ;;"-prospects" - more than one candidate |
326 (close-bracket-prospects "}") | |
327 ;"-prospects" - more than one candidate | |
328 (prospects-len 0) | 298 (prospects-len 0) |
329 prospects most-is-exact comp) | 299 prospects most-is-exact comp) |
330 (if (eq most-try t) | 300 (if (eq most-try t) |
331 (setq prospects nil) | 301 (setq prospects nil) |
332 (while (and comps (< prospects-len icomplete-prospects-length)) | 302 (while (and comps (< prospects-len icomplete-prospects-length)) |
336 ((member comp prospects)) | 306 ((member comp prospects)) |
337 (t (setq prospects (cons comp prospects) | 307 (t (setq prospects (cons comp prospects) |
338 prospects-len (+ (length comp) 1 prospects-len)))))) | 308 prospects-len (+ (length comp) 1 prospects-len)))))) |
339 (if prospects | 309 (if prospects |
340 (concat determ | 310 (concat determ |
341 open-bracket-prospects | 311 "{" |
342 (and most-is-exact ",") | 312 (and most-is-exact ",") |
343 (mapconcat 'identity | 313 (mapconcat 'identity |
344 (sort prospects (function string-lessp)) | 314 (sort prospects (function string-lessp)) |
345 ",") | 315 ",") |
346 (and comps ",...") | 316 (and comps ",...") |
347 close-bracket-prospects) | 317 "}") |
348 (concat determ | 318 (concat determ |
349 " [Matched" | 319 " [Matched" |
350 (let ((keys (and icomplete-show-key-bindings | 320 (let ((keys (and icomplete-show-key-bindings |
351 (commandp (intern-soft most)) | 321 (commandp (intern-soft most)) |
352 (icomplete-get-keys most)))) | 322 (icomplete-get-keys most)))) |
353 (if keys | 323 (if keys (concat "; " keys) "")) |
354 (concat "; " keys) | |
355 "")) | |
356 "]")))))) | 324 "]")))))) |
357 | |
358 (if icomplete-mode | |
359 (icomplete-mode 1)) | |
360 | 325 |
361 ;;;_* Local emacs vars. | 326 ;;;_* Local emacs vars. |
362 ;;;Local variables: | 327 ;;;Local variables: |
363 ;;;outline-layout: (-2 :) | 328 ;;;outline-layout: (-2 :) |
364 ;;;End: | 329 ;;;End: |
365 | 330 |
331 ;; arch-tag: 339ec25a-0741-4eb6-be63-997532e89b0f | |
366 ;;; icomplete.el ends here | 332 ;;; icomplete.el ends here |