Mercurial > emacs
comparison lisp/minibuffer.el @ 94062:9fefa536be58
* minibuffer.el (completion-all-completion-with-base-size): New var.
(completion--some): New function.
(completion-table-with-context, completion--file-name-table):
Return the base-size if requested.
(completion-table-in-turn): Generalize to multiple arguments.
(complete-in-turn): Compatibility alias.
(completion-styles-alist): New var.
(completion-styles): New customization.
(minibuffer-try-completion, minibuffer-all-completions):
New functions.
(minibuffer--do-completion, minibuffer-complete-and-exit)
(minibuffer-try-word-completion): Use them.
(display-completion-list, minibuffer-completion-help): Use them.
Handle all-completions's new base-size info to set completion-base-size.
* info.el (Info-read-node-name-1): Use completion-table-with-context,
completion-table-with-terminator and complete-with-action.
Remove the now obsolete completion-base-size-function property.
* simple.el (completion-list-mode-map): Move init into declaration.
(completion-list-mode): Use define-derived-mode.
(completion-setup-function): Use any completion-base-size that may
have been set before. Remove handling of completion-base-size-function.
* loadup.el: Move abbrev.el up earlier.
author | Stefan Monnier <monnier@iro.umontreal.ca> |
---|---|
date | Sun, 13 Apr 2008 22:12:02 +0000 |
parents | ec343c7600a2 |
children | f2cff391663b |
comparison
equal
deleted
inserted
replaced
94061:d4e9da5a29d5 | 94062:9fefa536be58 |
---|---|
22 ;;; Commentary: | 22 ;;; Commentary: |
23 | 23 |
24 ;; Names starting with "minibuffer--" are for functions and variables that | 24 ;; Names starting with "minibuffer--" are for functions and variables that |
25 ;; are meant to be for internal use only. | 25 ;; are meant to be for internal use only. |
26 | 26 |
27 ;; TODO: | |
28 ;; - make the `hide-spaces' arg of all-completions obsolete. | |
29 | |
27 ;; BUGS: | 30 ;; BUGS: |
28 ;; - envvar completion for file names breaks completion-base-size. | 31 ;; - envvar completion for file names breaks completion-base-size. |
29 | 32 |
30 ;;; Code: | 33 ;;; Code: |
31 | 34 |
32 (eval-when-compile (require 'cl)) | 35 (eval-when-compile (require 'cl)) |
33 | 36 |
37 (defvar completion-all-completions-with-base-size nil | |
38 "If non-nil, `all-completions' may return the base-size in the last cdr. | |
39 The base-size is the length of the prefix that is elided from each | |
40 element in the returned list of completions. See `completion-base-size'.") | |
41 | |
34 ;;; Completion table manipulation | 42 ;;; Completion table manipulation |
35 | 43 |
44 (defun completion--some (fun xs) | |
45 "Apply FUN to each element of XS in turn. | |
46 Return the first non-nil returned value. | |
47 Like CL's `some'." | |
48 (let (res) | |
49 (while (and (not res) xs) | |
50 (setq res (funcall fun (pop xs)))) | |
51 res)) | |
52 | |
36 (defun apply-partially (fun &rest args) | 53 (defun apply-partially (fun &rest args) |
54 "Do a \"curried\" partial application of FUN to ARGS. | |
55 ARGS is a list of the first N arguments to pass to FUN. | |
56 The result is a new function that takes the remaining arguments, | |
57 and calls FUN." | |
37 (lexical-let ((fun fun) (args1 args)) | 58 (lexical-let ((fun fun) (args1 args)) |
38 (lambda (&rest args2) (apply fun (append args1 args2))))) | 59 (lambda (&rest args2) (apply fun (append args1 args2))))) |
39 | 60 |
40 (defun complete-with-action (action table string pred) | 61 (defun complete-with-action (action table string pred) |
41 "Perform completion ACTION. | 62 "Perform completion ACTION. |
88 (setq ,var (,fun))) | 109 (setq ,var (,fun))) |
89 ,var)))) | 110 ,var)))) |
90 | 111 |
91 (defun completion-table-with-context (prefix table string pred action) | 112 (defun completion-table-with-context (prefix table string pred action) |
92 ;; TODO: add `suffix', and think about how we should support `pred'. | 113 ;; TODO: add `suffix', and think about how we should support `pred'. |
93 ;; Notice that `pred' is not a predicate when called from read-file-name. | 114 ;; Notice that `pred' is not a predicate when called from read-file-name |
115 ;; or Info-read-node-name-2. | |
94 ;; (if pred (setq pred (lexical-let ((pred pred)) | 116 ;; (if pred (setq pred (lexical-let ((pred pred)) |
95 ;; ;; FIXME: this doesn't work if `table' is an obarray. | 117 ;; ;; FIXME: this doesn't work if `table' is an obarray. |
96 ;; (lambda (s) (funcall pred (concat prefix s)))))) | 118 ;; (lambda (s) (funcall pred (concat prefix s)))))) |
97 (let ((comp (complete-with-action action table string nil))) ;; pred | 119 (let ((comp (complete-with-action action table string pred))) |
98 (if (stringp comp) | 120 (cond |
99 (concat prefix comp) | 121 ;; In case of try-completion, add the prefix. |
100 comp))) | 122 ((stringp comp) (concat prefix comp)) |
123 ;; In case of non-empty all-completions, | |
124 ;; add the prefix size to the base-size. | |
125 ((consp comp) | |
126 (let ((last (last comp))) | |
127 (when completion-all-completions-with-base-size | |
128 (setcdr last (+ (or (cdr last) 0) (length prefix)))) | |
129 comp)) | |
130 (t comp)))) | |
101 | 131 |
102 (defun completion-table-with-terminator (terminator table string pred action) | 132 (defun completion-table-with-terminator (terminator table string pred action) |
103 (let ((comp (complete-with-action action table string pred))) | 133 (let ((comp (complete-with-action action table string pred))) |
104 (if (eq action nil) | 134 (if (eq action nil) |
105 (if (eq comp t) | 135 (if (eq comp t) |
108 (eq (complete-with-action action table comp pred) t)) | 138 (eq (complete-with-action action table comp pred) t)) |
109 (concat comp terminator) | 139 (concat comp terminator) |
110 comp)) | 140 comp)) |
111 comp))) | 141 comp))) |
112 | 142 |
113 (defun completion-table-in-turn (a b) | 143 (defun completion-table-in-turn (&rest tables) |
114 "Create a completion table that first tries completion in A and then in B. | 144 "Create a completion table that tries each table in TABLES in turn." |
115 A and B should not be costly (or side-effecting) expressions." | 145 (lexical-let ((tables tables)) |
116 (lexical-let ((a a) (b b)) | |
117 (lambda (string pred action) | 146 (lambda (string pred action) |
118 (or (complete-with-action action a string pred) | 147 (completion--some (lambda (table) |
119 (complete-with-action action b string pred))))) | 148 (complete-with-action action table string pred)) |
149 tables)))) | |
150 | |
151 (defmacro complete-in-turn (a b) `(completion-table-in-turn ,a ,b)) | |
152 (define-obsolete-function-alias | |
153 'complete-in-turn 'completion-table-in-turn "23.1") | |
120 | 154 |
121 ;;; Minibuffer completion | 155 ;;; Minibuffer completion |
122 | 156 |
123 (defgroup minibuffer nil | 157 (defgroup minibuffer nil |
124 "Controlling the behavior of the minibuffer." | 158 "Controlling the behavior of the minibuffer." |
160 If the value is `lazy', the *Completions* buffer is only displayed after | 194 If the value is `lazy', the *Completions* buffer is only displayed after |
161 the second failed attempt to complete." | 195 the second failed attempt to complete." |
162 :type '(choice (const nil) (const t) (const lazy)) | 196 :type '(choice (const nil) (const t) (const lazy)) |
163 :group 'minibuffer) | 197 :group 'minibuffer) |
164 | 198 |
199 (defvar completion-styles-alist | |
200 '((basic try-completion all-completions) | |
201 ;; (partial-completion | |
202 ;; completion-pcm--try-completion completion-pcm--all-completions) | |
203 ) | |
204 "List of available completion styles. | |
205 Each element has the form (NAME TRY-COMPLETION ALL-COMPLETIONS) | |
206 where NAME is the name that should be used in `completion-styles' | |
207 TRY-COMPLETION is the function that does the completion, and | |
208 ALL-COMPLETIONS is the function that lists the completions.") | |
209 | |
210 (defcustom completion-styles '(basic) | |
211 "List of completion styles to use." | |
212 :type `(repeat (choice ,@(mapcar (lambda (x) (list 'const (car x))) | |
213 completion-styles-alist))) | |
214 :group 'minibuffer | |
215 :version "23.1") | |
216 | |
217 (defun minibuffer-try-completion (string table pred) | |
218 (if (and (symbolp table) (get table 'no-completion-styles)) | |
219 (try-completion string table pred) | |
220 (completion--some (lambda (style) | |
221 (funcall (intern (concat style "try-completion")) | |
222 string table pred)) | |
223 completion-styles))) | |
224 | |
225 (defun minibuffer-all-completions (string table pred &optional hide-spaces) | |
226 (let ((completion-all-completions-with-base-size t)) | |
227 (if (and (symbolp table) (get table 'no-completion-styles)) | |
228 (all-completions string table pred hide-spaces) | |
229 (completion--some (lambda (style) | |
230 (funcall (intern (concat style "all-completions")) | |
231 string table pred hide-spaces)) | |
232 completion-styles)))) | |
233 | |
165 (defun minibuffer--bitset (modified completions exact) | 234 (defun minibuffer--bitset (modified completions exact) |
166 (logior (if modified 4 0) | 235 (logior (if modified 4 0) |
167 (if completions 2 0) | 236 (if completions 2 0) |
168 (if exact 1 0))) | 237 (if exact 1 0))) |
169 | 238 |
182 101 5 ??? impossible | 251 101 5 ??? impossible |
183 110 6 some completion happened | 252 110 6 some completion happened |
184 111 7 completed to an exact completion" | 253 111 7 completed to an exact completion" |
185 (let* ((beg (field-beginning)) | 254 (let* ((beg (field-beginning)) |
186 (string (buffer-substring beg (point))) | 255 (string (buffer-substring beg (point))) |
187 (completion (funcall (or try-completion-function 'try-completion) | 256 (completion (funcall (or try-completion-function |
257 'minibuffer-try-completion) | |
188 string | 258 string |
189 minibuffer-completion-table | 259 minibuffer-completion-table |
190 minibuffer-completion-predicate))) | 260 minibuffer-completion-predicate))) |
191 (cond | 261 (cond |
192 ((null completion) | 262 ((null completion) |
288 minibuffer-completion-table | 358 minibuffer-completion-table |
289 minibuffer-completion-predicate) | 359 minibuffer-completion-predicate) |
290 (when completion-ignore-case | 360 (when completion-ignore-case |
291 ;; Fixup case of the field, if necessary. | 361 ;; Fixup case of the field, if necessary. |
292 (let* ((string (field-string)) | 362 (let* ((string (field-string)) |
293 (compl (try-completion string | 363 (compl (minibuffer-try-completion |
294 minibuffer-completion-table | 364 string |
295 minibuffer-completion-predicate))) | 365 minibuffer-completion-table |
366 minibuffer-completion-predicate))) | |
296 (when (and (stringp compl) | 367 (when (and (stringp compl) |
297 ;; If it weren't for this piece of paranoia, I'd replace | 368 ;; If it weren't for this piece of paranoia, I'd replace |
298 ;; the whole thing with a call to complete-do-completion. | 369 ;; the whole thing with a call to complete-do-completion. |
299 (= (length string) (length compl))) | 370 (= (length string) (length compl))) |
300 (let ((beg (field-beginning)) | 371 (let ((beg (field-beginning)) |
323 (minibuffer-message "Confirm") | 394 (minibuffer-message "Confirm") |
324 nil)) | 395 nil)) |
325 (t nil))))) | 396 (t nil))))) |
326 | 397 |
327 (defun minibuffer-try-word-completion (string table predicate) | 398 (defun minibuffer-try-word-completion (string table predicate) |
328 (let ((completion (try-completion string table predicate))) | 399 (let ((completion (minibuffer-try-completion string table predicate))) |
329 (if (not (stringp completion)) | 400 (if (not (stringp completion)) |
330 completion | 401 completion |
331 | 402 |
332 ;; Completing a single word is actually more difficult than completing | 403 ;; Completing a single word is actually more difficult than completing |
333 ;; as much as possible, because we first have to find the "current | 404 ;; as much as possible, because we first have to find the "current |
367 ;; consider adding a space or a hyphen. | 438 ;; consider adding a space or a hyphen. |
368 (when (= (length string) (length completion)) | 439 (when (= (length string) (length completion)) |
369 (let ((exts '(" " "-")) | 440 (let ((exts '(" " "-")) |
370 tem) | 441 tem) |
371 (while (and exts (not (stringp tem))) | 442 (while (and exts (not (stringp tem))) |
372 (setq tem (try-completion (concat string (pop exts)) | 443 (setq tem (minibuffer-try-completion (concat string (pop exts)) |
373 table predicate))) | 444 table predicate))) |
374 (if (stringp tem) (setq completion tem)))) | 445 (if (stringp tem) (setq completion tem)))) |
375 | 446 |
376 ;; Otherwise cut after the first word. | 447 ;; Otherwise cut after the first word. |
377 (if (string-match "\\W" completion (length string)) | 448 (if (string-match "\\W" completion (length string)) |
378 ;; First find first word-break in the stuff found by completion. | 449 ;; First find first word-break in the stuff found by completion. |
490 (goto-char (point-max)) | 561 (goto-char (point-max)) |
491 (if (null completions) | 562 (if (null completions) |
492 (insert "There are no possible completions of what you have typed.") | 563 (insert "There are no possible completions of what you have typed.") |
493 | 564 |
494 (insert "Possible completions are:\n") | 565 (insert "Possible completions are:\n") |
566 (let ((last (last completions))) | |
567 ;; Get the base-size from the tail of the list. | |
568 (set (make-local-variable 'completion-base-size) (or (cdr last) 0)) | |
569 (setcdr last nil)) ;Make completions a properly nil-terminated list. | |
495 (minibuffer--insert-strings completions)))) | 570 (minibuffer--insert-strings completions)))) |
571 | |
496 (let ((completion-common-substring common-substring)) | 572 (let ((completion-common-substring common-substring)) |
497 (run-hooks 'completion-setup-hook)) | 573 (run-hooks 'completion-setup-hook)) |
498 nil) | 574 nil) |
499 | 575 |
500 (defun minibuffer-completion-help () | 576 (defun minibuffer-completion-help () |
501 "Display a list of possible completions of the current minibuffer contents." | 577 "Display a list of possible completions of the current minibuffer contents." |
502 (interactive) | 578 (interactive) |
503 (message "Making completion list...") | 579 (message "Making completion list...") |
504 (let* ((string (field-string)) | 580 (let* ((string (field-string)) |
505 (completions (all-completions | 581 (completions (minibuffer-all-completions |
506 string | 582 string |
507 minibuffer-completion-table | 583 minibuffer-completion-table |
508 minibuffer-completion-predicate | 584 minibuffer-completion-predicate |
509 t))) | 585 t))) |
510 (message nil) | 586 (message nil) |
511 (if (and completions | 587 (if (and completions |
512 (or (cdr completions) (not (equal (car completions) string)))) | 588 (or (consp (cdr completions)) |
589 (not (equal (car completions) string)))) | |
513 (with-output-to-temp-buffer "*Completions*" | 590 (with-output-to-temp-buffer "*Completions*" |
514 (display-completion-list (sort completions 'string-lessp))) | 591 (let* ((last (last completions)) |
592 (base-size (cdr last))) | |
593 ;; Remove the base-size tail because `sort' requires a properly | |
594 ;; nil-terminated list. | |
595 (when last (setcdr last nil)) | |
596 (display-completion-list (nconc (sort completions 'string-lessp) | |
597 base-size)))) | |
515 | 598 |
516 ;; If there are no completions, or if the current input is already the | 599 ;; If there are no completions, or if the current input is already the |
517 ;; only possible completion, then hide (previous&stale) completions. | 600 ;; only possible completion, then hide (previous&stale) completions. |
518 (let ((window (and (get-buffer "*Completions*") | 601 (let ((window (and (get-buffer "*Completions*") |
519 (get-buffer-window "*Completions*" 0)))) | 602 (get-buffer-window "*Completions*" 0)))) |
595 ;; If there's no real completion, but substitute-in-file-name | 678 ;; If there's no real completion, but substitute-in-file-name |
596 ;; changed the string, then return the new string. | 679 ;; changed the string, then return the new string. |
597 str)))) | 680 str)))) |
598 | 681 |
599 ((eq action t) | 682 ((eq action t) |
600 (let ((all (file-name-all-completions name realdir))) | 683 (let ((all (file-name-all-completions name realdir)) |
601 (if (memq read-file-name-predicate '(nil file-exists-p)) | 684 ;; Actually, this is not always right in the presence of |
602 all | 685 ;; envvars, but there's not much we can do, I think. |
686 (base-size (length (file-name-directory string)))) | |
687 | |
688 ;; Check the predicate, if necessary. | |
689 (unless (memq read-file-name-predicate '(nil file-exists-p)) | |
603 (let ((comp ()) | 690 (let ((comp ()) |
604 (pred | 691 (pred |
605 (if (eq read-file-name-predicate 'file-directory-p) | 692 (if (eq read-file-name-predicate 'file-directory-p) |
606 ;; Brute-force speed up for directory checking: | 693 ;; Brute-force speed up for directory checking: |
607 ;; Discard strings which don't end in a slash. | 694 ;; Discard strings which don't end in a slash. |
611 ;; Must do it the hard (and slow) way. | 698 ;; Must do it the hard (and slow) way. |
612 read-file-name-predicate))) | 699 read-file-name-predicate))) |
613 (let ((default-directory realdir)) | 700 (let ((default-directory realdir)) |
614 (dolist (tem all) | 701 (dolist (tem all) |
615 (if (funcall pred tem) (push tem comp)))) | 702 (if (funcall pred tem) (push tem comp)))) |
616 (nreverse comp))))) | 703 (setq all (nreverse comp)))) |
704 | |
705 ;; Add base-size, but only if the list is non-empty. | |
706 (if (consp all) (nconc all base-size)))) | |
617 | 707 |
618 (t | 708 (t |
619 ;; Only other case actually used is ACTION = lambda. | 709 ;; Only other case actually used is ACTION = lambda. |
620 (let ((default-directory dir)) | 710 (let ((default-directory dir)) |
621 (funcall (or read-file-name-predicate 'file-exists-p) str))))))) | 711 (funcall (or read-file-name-predicate 'file-exists-p) str))))))) |