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)))))))