aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2008-05-20 17:03:30 +0000
committerStefan Monnier2008-05-20 17:03:30 +0000
commita38313e1060b24ac303e6d6f67d53f2c9635eb44 (patch)
tree00ec663805b59efd5d2d82893d88935bfcbab082
parenteb152aa90b1fe5539028d66cfedb880e9d0a6b8f (diff)
downloademacs-a38313e1060b24ac303e6d6f67d53f2c9635eb44.tar.gz
emacs-a38313e1060b24ac303e6d6f67d53f2c9635eb44.zip
(completion-boundaries): New function.
(completion--some): Delay errors. (complete-with-action, completion-table-with-context): Handle `boundaries'. (completion--try-word-completion): Avoid partial-completion when the user hasn't entered anything yet. (minibuffer-local-map, minibuffer-local-filename-completion-map) (minibuffer-local-must-match-map, minibuffer-local-completion-map) (minibuffer-local-must-match-filename-map, minibuffer-local-ns-map): Setup default keybindings. (completion--embedded-envvar-re): New var. (completion--embedded-envvar-table): Use it. Handle `boundaries' case. (completion--file-name-table): Handle `boundaries' case. (completion-pcm--pattern->regex): Avoid pathological backtracking. (completion-pcm--all-completions): Add a `prefix' arg. (completion-pcm--find-all-completions): New function. (completion-pcm-all-completions, completion-pcm-try-completion): Use it.
-rw-r--r--lisp/ChangeLog35
-rw-r--r--lisp/minibuffer.el401
2 files changed, 332 insertions, 104 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index e98d6f93852..562877e2527 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,16 +1,33 @@
12008-05-20 Stefan Monnier <monnier@iro.umontreal.ca> 12008-05-20 Stefan Monnier <monnier@iro.umontreal.ca>
2 2
3 * minibuffer.el (completion-boundaries): New function.
4 (completion--some): Delay errors.
5 (complete-with-action, completion-table-with-context):
6 Handle `boundaries' case.
7 (completion--try-word-completion): Avoid partial-completion
8 when the user hasn't entered anything yet.
9 (minibuffer-local-map, minibuffer-local-filename-completion-map)
10 (minibuffer-local-must-match-map, minibuffer-local-completion-map)
11 (minibuffer-local-must-match-filename-map, minibuffer-local-ns-map):
12 Setup default keybindings.
13 (completion--embedded-envvar-re): New var.
14 (completion--embedded-envvar-table): Use it. Handle `boundaries' case.
15 (completion--file-name-table): Handle `boundaries' case.
16 (completion-pcm--pattern->regex): Avoid pathological backtracking.
17 (completion-pcm--all-completions): Add a `prefix' arg.
18 (completion-pcm--find-all-completions): New function.
19 (completion-pcm-all-completions, completion-pcm-try-completion):
20 Use it.
21
3 * icomplete.el (icomplete-completions): Don't use `predicate' with 22 * icomplete.el (icomplete-completions): Don't use `predicate' with
4 a table of a different type than `candidates'. 23 a table of a different type than `candidates'.
5 24
62008-05-20 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de> 252008-05-20 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de>
7 26
8 * proced.el (proced-goal-header-re): Renamed from 27 * proced.el (proced-goal-column): Rename from proced-procname-column.
9 proced-procname-column-regexp. 28 (proced-goal-header-re): Rename from proced-procname-column-regexp.
10 (proced-goal-column): Renamed from proced-procname-column. 29 (proced-move-to-goal-column): Rename from proced-move-to-procname.
11 (proced-move-to-goal-column): Renamed from 30 (proced-header-face, proced-header-regexp): Remove.
12 proced-move-to-procname.
13 (proced-header-face, proced-header-regexp): Removed.
14 (proced-font-lock-keywords): Remove proced-header-face. 31 (proced-font-lock-keywords): Remove proced-header-face.
15 (proced-header-alist, proced-sorting-schemes-re): New variables. 32 (proced-header-alist, proced-sorting-schemes-re): New variables.
16 (proced): Rename Proced buffer to *Proced*. 33 (proced): Rename Proced buffer to *Proced*.
@@ -18,9 +35,9 @@
18 (proced-do-mark, proced-do-mark-all, proced-toggle-marks) 35 (proced-do-mark, proced-do-mark-all, proced-toggle-marks)
19 (proced-hide-processes): Do not treat first line as special. 36 (proced-hide-processes): Do not treat first line as special.
20 (proced-header-space): New function. 37 (proced-header-space): New function.
21 (proced-update): Use header-line-format. Initialize 38 (proced-update): Use header-line-format.
22 proced-header-alist and proced-sorting-schemes-re. Set 39 Initialize proced-header-alist and proced-sorting-schemes-re.
23 proced-goal-column. Include proced-command in mode-name. 40 Set proced-goal-column. Include proced-command in mode-name.
24 (proced-send-signal): Use header-line-format for *Marked 41 (proced-send-signal): Use header-line-format for *Marked
25 Processes* buffer. 42 Processes* buffer.
26 (proced-sort): Restrict minibuffer completion to applicable 43 (proced-sort): Restrict minibuffer completion to applicable
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index de69f5337e7..5e176637618 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -21,11 +21,32 @@
21 21
22;;; Commentary: 22;;; Commentary:
23 23
24;; Names starting with "minibuffer--" are for functions and variables that 24;; Names with "--" are for functions and variables that are meant to be for
25;; are meant to be for internal use only. 25;; internal use only.
26
27;; Functional completion tables have an extended calling conventions:
28;; - If completion-all-completions-with-base-size is set, then all-completions
29;; should return the base-size in the last cdr.
30;; - The `action' can be (additionally to nil, t, and lambda) of the form
31;; (boundaries . POS) in which case it should return (boundaries START . END).
32;; Any other return value should be ignored (so we ignore values returned
33;; from completion tables that don't know about this new `action' form).
34;; See `completion-boundaries'.
35
36;;; Bugs:
37
38;; - completion-ignored-extensions is ignored by partial-completion because
39;; pcm merges the `all' output to synthesize a `try' output and
40;; read-file-name-internal's `all' output doesn't obey
41;; completion-ignored-extensions.
42;; - choose-completion can't automatically figure out the boundaries
43;; corresponding to the displayed completions. `base-size' gives the left
44;; boundary, but not the righthand one. So we need to add
45;; completion-extra-size (and also completion-no-auto-exit).
26 46
27;;; Todo: 47;;; Todo:
28 48
49;; - add support for ** to pcm.
29;; - Make read-file-name-predicate obsolete. 50;; - Make read-file-name-predicate obsolete.
30;; - New command minibuffer-force-complete that chooses one of all-completions. 51;; - New command minibuffer-force-complete that chooses one of all-completions.
31;; - Add vc-file-name-completion-table to read-file-name-internal. 52;; - Add vc-file-name-completion-table to read-file-name-internal.
@@ -43,14 +64,37 @@ element in the returned list of completions. See `completion-base-size'.")
43 64
44;;; Completion table manipulation 65;;; Completion table manipulation
45 66
67;; New completion-table operation.
68(defun completion-boundaries (string table pred pos)
69 "Return the boundaries of the completions returned by TABLE at POS.
70STRING is the string on which completion will be performed.
71The result is of the form (START . END) and gives the start and end position
72corresponding to the substring of STRING that can be completed by one
73of the elements returned by
74\(all-completions (substring STRING 0 POS) TABLE PRED).
75I.e. START is the same as the `completion-base-size'.
76E.g. for simple completion tables, the result is always (0 . (length STRING))
77and for file names the result is the substring around POS delimited by
78the closest directory separators."
79 (let ((boundaries (if (functionp table)
80 (funcall table string pred (cons 'boundaries pos)))))
81 (if (not (eq (car-safe boundaries) 'boundaries))
82 (setq boundaries nil))
83 (cons (or (cadr boundaries) 0)
84 (or (cddr boundaries) (length string)))))
85
46(defun completion--some (fun xs) 86(defun completion--some (fun xs)
47 "Apply FUN to each element of XS in turn. 87 "Apply FUN to each element of XS in turn.
48Return the first non-nil returned value. 88Return the first non-nil returned value.
49Like CL's `some'." 89Like CL's `some'."
50 (let (res) 90 (let ((firsterror nil)
91 res)
51 (while (and (not res) xs) 92 (while (and (not res) xs)
52 (setq res (funcall fun (pop xs)))) 93 (condition-case err
53 res)) 94 (setq res (funcall fun (pop xs)))
95 (error (unless firsterror (setq firsterror err)) nil)))
96 (or res
97 (if firsterror (signal (car firsterror) (cdr firsterror))))))
54 98
55(defun apply-partially (fun &rest args) 99(defun apply-partially (fun &rest args)
56 "Do a \"curried\" partial application of FUN to ARGS. 100 "Do a \"curried\" partial application of FUN to ARGS.
@@ -66,13 +110,17 @@ STRING is the string to complete.
66TABLE is the completion table, which should not be a function. 110TABLE is the completion table, which should not be a function.
67PRED is a completion predicate. 111PRED is a completion predicate.
68ACTION can be one of nil, t or `lambda'." 112ACTION can be one of nil, t or `lambda'."
69 ;; (assert (not (functionp table))) 113 (cond
70 (funcall 114 ((functionp table) (funcall table string pred action))
71 (cond 115 ((eq (car-safe action) 'boundaries)
72 ((null action) 'try-completion) 116 (cons 'boundaries (completion-boundaries string table pred (cdr action))))
73 ((eq action t) 'all-completions) 117 (t
74 (t 'test-completion)) 118 (funcall
75 string table pred)) 119 (cond
120 ((null action) 'try-completion)
121 ((eq action t) 'all-completions)
122 (t 'test-completion))
123 string table pred))))
76 124
77(defun completion-table-dynamic (fun) 125(defun completion-table-dynamic (fun)
78 "Use function FUN as a dynamic completion table. 126 "Use function FUN as a dynamic completion table.
@@ -112,8 +160,7 @@ You should give VAR a non-nil `risky-local-variable' property."
112 160
113(defun completion-table-with-context (prefix table string pred action) 161(defun completion-table-with-context (prefix table string pred action)
114 ;; TODO: add `suffix' maybe? 162 ;; TODO: add `suffix' maybe?
115 ;; Notice that `pred' is not a predicate when called from read-file-name 163 ;; Notice that `pred' may not be a function in some abusive cases.
116 ;; or Info-read-node-name-2.
117 (when (functionp pred) 164 (when (functionp pred)
118 (setq pred 165 (setq pred
119 (lexical-let ((pred pred)) 166 (lexical-let ((pred pred))
@@ -129,18 +176,23 @@ You should give VAR a non-nil `risky-local-variable' property."
129 (t ;Lists and alists. 176 (t ;Lists and alists.
130 (lambda (s) 177 (lambda (s)
131 (funcall pred (concat prefix (if (consp s) (car s) s))))))))) 178 (funcall pred (concat prefix (if (consp s) (car s) s)))))))))
132 (let ((comp (complete-with-action action table string pred))) 179 (if (eq (car-safe action) 'boundaries)
133 (cond 180 (let* ((len (length prefix))
134 ;; In case of try-completion, add the prefix. 181 (bound (completion-boundaries string table pred
135 ((stringp comp) (concat prefix comp)) 182 (- (cdr action) len))))
136 ;; In case of non-empty all-completions, 183 (list* 'boundaries (+ (car bound) len) (+ (cdr bound) len)))
137 ;; add the prefix size to the base-size. 184 (let ((comp (complete-with-action action table string pred)))
138 ((consp comp) 185 (cond
139 (let ((last (last comp))) 186 ;; In case of try-completion, add the prefix.
140 (when completion-all-completions-with-base-size 187 ((stringp comp) (concat prefix comp))
141 (setcdr last (+ (or (cdr last) 0) (length prefix)))) 188 ;; In case of non-empty all-completions,
142 comp)) 189 ;; add the prefix size to the base-size.
143 (t comp)))) 190 ((consp comp)
191 (let ((last (last comp)))
192 (when completion-all-completions-with-base-size
193 (setcdr last (+ (or (cdr last) 0) (length prefix))))
194 comp))
195 (t comp)))))
144 196
145(defun completion-table-with-terminator (terminator table string pred action) 197(defun completion-table-with-terminator (terminator table string pred action)
146 (cond 198 (cond
@@ -152,7 +204,18 @@ You should give VAR a non-nil `risky-local-variable' property."
152 (eq (try-completion comp table pred) t)) 204 (eq (try-completion comp table pred) t))
153 (concat comp terminator) 205 (concat comp terminator)
154 comp)))) 206 comp))))
155 ((eq action t) (all-completions string table pred)) 207 ((eq action t)
208 ;; FIXME: We generally want the `try' and `all' behaviors to be
209 ;; consistent so pcm can merge the `all' output to get the `try' output,
210 ;; but that sometimes clashes with the need for `all' output to look
211 ;; good in *Completions*.
212 ;; (let* ((all (all-completions string table pred))
213 ;; (last (last all))
214 ;; (base-size (cdr last)))
215 ;; (when all
216 ;; (setcdr all nil)
217 ;; (nconc (mapcar (lambda (s) (concat s terminator)) all) base-size)))
218 (all-completions string table pred))
156 ;; completion-table-with-terminator is always used for 219 ;; completion-table-with-terminator is always used for
157 ;; "sub-completions" so it's only called if the terminator is missing, 220 ;; "sub-completions" so it's only called if the terminator is missing,
158 ;; in which case `test-completion' should return nil. 221 ;; in which case `test-completion' should return nil.
@@ -297,10 +360,10 @@ Only the elements of table that satisfy predicate PRED are considered.
297POINT is the position of point within STRING. 360POINT is the position of point within STRING.
298The return value is a list of completions and may contain the base-size 361The return value is a list of completions and may contain the base-size
299in the last `cdr'." 362in the last `cdr'."
300 ;; The property `completion-styles' indicates that this functional
301 ;; completion-table claims to take care of completion styles itself.
302 ;; [I.e. It will most likely call us back at some point. ]
303 (let ((completion-all-completions-with-base-size t)) 363 (let ((completion-all-completions-with-base-size t))
364 ;; The property `completion-styles' indicates that this functional
365 ;; completion-table claims to take care of completion styles itself.
366 ;; [I.e. It will most likely call us back at some point. ]
304 (if (and (symbolp table) (get table 'completion-styles)) 367 (if (and (symbolp table) (get table 'completion-styles))
305 ;; Extended semantics for functional completion-tables: 368 ;; Extended semantics for functional completion-tables:
306 ;; They accept a 4th argument `point' and when called with action=t 369 ;; They accept a 4th argument `point' and when called with action=t
@@ -417,19 +480,22 @@ scroll the window of possible completions."
417 nil) 480 nil)
418 481
419 (case (completion--do-completion) 482 (case (completion--do-completion)
420 (0 nil) 483 (#b000 nil)
421 (1 (goto-char (field-end)) 484 (#b001 (goto-char (field-end))
422 (minibuffer-message "Sole completion") 485 (minibuffer-message "Sole completion")
423 t) 486 t)
424 (3 (goto-char (field-end)) 487 (#b011 (goto-char (field-end))
425 (minibuffer-message "Complete, but not unique") 488 (minibuffer-message "Complete, but not unique")
426 t) 489 t)
427 (t t))))) 490 (t t)))))
428 491
429(defun minibuffer-complete-and-exit () 492(defun minibuffer-complete-and-exit ()
430 "If the minibuffer contents is a valid completion then exit. 493 "If the minibuffer contents is a valid completion then exit.
431Otherwise try to complete it. If completion leads to a valid completion, 494Otherwise try to complete it. If completion leads to a valid completion,
432a repetition of this command will exit." 495a repetition of this command will exit.
496If `minibuffer-completion-confirm' is equal to `confirm', then do not
497try to complete, but simply ask for confirmation and accept any
498input if confirmed."
433 (interactive) 499 (interactive)
434 (let ((beg (field-beginning)) 500 (let ((beg (field-beginning))
435 (end (field-end))) 501 (end (field-end)))
@@ -468,11 +534,11 @@ a repetition of this command will exit."
468 (case (condition-case nil 534 (case (condition-case nil
469 (completion--do-completion) 535 (completion--do-completion)
470 (error 1)) 536 (error 1))
471 ((1 3) (exit-minibuffer)) 537 ((#b001 #b011) (exit-minibuffer))
472 (7 (if (not minibuffer-completion-confirm) 538 (#b111 (if (not minibuffer-completion-confirm)
473 (exit-minibuffer) 539 (exit-minibuffer)
474 (minibuffer-message "Confirm") 540 (minibuffer-message "Confirm")
475 nil)) 541 nil))
476 (t nil)))))) 542 (t nil))))))
477 543
478(defun completion--try-word-completion (string table predicate point) 544(defun completion--try-word-completion (string table predicate point)
@@ -486,6 +552,14 @@ a repetition of this command will exit."
486 (let ((exts '(" " "-")) 552 (let ((exts '(" " "-"))
487 (before (substring string 0 point)) 553 (before (substring string 0 point))
488 (after (substring string point)) 554 (after (substring string point))
555 ;; If the user hasn't entered any text yet, then she
556 ;; presumably hits SPC to see the *completions*, but
557 ;; partial-completion will often find a " " or a "-" to match.
558 ;; So disable partial-completion in that situation.
559 (completion-styles
560 (or (and (equal string "")
561 (remove 'partial-completion completion-styles))
562 completion-styles))
489 tem) 563 tem)
490 (while (and exts (not (consp tem))) 564 (while (and exts (not (consp tem)))
491 (setq tem (completion-try-completion 565 (setq tem (completion-try-completion
@@ -561,14 +635,14 @@ is added, provided that matches some possible completion.
561Return nil if there is no valid completion, else t." 635Return nil if there is no valid completion, else t."
562 (interactive) 636 (interactive)
563 (case (completion--do-completion 'completion--try-word-completion) 637 (case (completion--do-completion 'completion--try-word-completion)
564 (0 nil) 638 (#b000 nil)
565 (1 (goto-char (field-end)) 639 (#b001 (goto-char (field-end))
566 (minibuffer-message "Sole completion") 640 (minibuffer-message "Sole completion")
567 t) 641 t)
568 (3 (goto-char (field-end)) 642 (#b011 (goto-char (field-end))
569 (minibuffer-message "Complete, but not unique") 643 (minibuffer-message "Complete, but not unique")
570 t) 644 t)
571 (t t))) 645 (t t)))
572 646
573(defun completion--insert-strings (strings) 647(defun completion--insert-strings (strings)
574 "Insert a list of STRINGS into the current buffer. 648 "Insert a list of STRINGS into the current buffer.
@@ -778,6 +852,34 @@ specified by COMMON-SUBSTRING."
778 (ding)) 852 (ding))
779 (exit-minibuffer)) 853 (exit-minibuffer))
780 854
855;;; Key bindings.
856
857(let ((map minibuffer-local-map))
858 (define-key map "\C-g" 'abort-recursive-edit)
859 (define-key map "\r" 'exit-minibuffer)
860 (define-key map "\n" 'exit-minibuffer))
861
862(let ((map minibuffer-local-completion-map))
863 (define-key map "\t" 'minibuffer-complete)
864 (define-key map " " 'minibuffer-complete-word)
865 (define-key map "?" 'minibuffer-completion-help))
866
867(let ((map minibuffer-local-must-match-map))
868 (define-key map "\r" 'minibuffer-complete-and-exit)
869 (define-key map "\n" 'minibuffer-complete-and-exit))
870
871(let ((map minibuffer-local-filename-completion-map))
872 (define-key map " " nil))
873(let ((map minibuffer-local-must-match-filename-map))
874 (define-key map " " nil))
875
876(let ((map minibuffer-local-ns-map))
877 (define-key map " " 'exit-minibuffer)
878 (define-key map "\t" 'exit-minibuffer)
879 (define-key map "?" 'self-insert-and-exit))
880
881;;; Completion tables.
882
781(defun minibuffer--double-dollars (str) 883(defun minibuffer--double-dollars (str)
782 (replace-regexp-in-string "\\$" "$$" str)) 884 (replace-regexp-in-string "\\$" "$$" str))
783 885
@@ -786,24 +888,45 @@ specified by COMMON-SUBSTRING."
786 (substring enventry 0 (string-match "=" enventry))) 888 (substring enventry 0 (string-match "=" enventry)))
787 process-environment)) 889 process-environment))
788 890
891(defconst completion--embedded-envvar-re
892 (concat "\\(?:^\\|[^$]\\(?:\\$\\$\\)*\\)"
893 "$\\([[:alnum:]_]*\\|{\\([^}]*\\)\\)\\'"))
894
789(defun completion--embedded-envvar-table (string pred action) 895(defun completion--embedded-envvar-table (string pred action)
790 (when (string-match (concat "\\(?:^\\|[^$]\\(?:\\$\\$\\)*\\)" 896 (if (eq (car-safe action) 'boundaries)
791 "$\\([[:alnum:]_]*\\|{\\([^}]*\\)\\)\\'") 897 ;; Compute the boundaries of the subfield to which this
792 string) 898 ;; completion applies.
793 (let* ((beg (or (match-beginning 2) (match-beginning 1))) 899 (let* ((pos (cdr action))
794 (table (completion--make-envvar-table)) 900 (suffix (substring string pos)))
795 (prefix (substring string 0 beg))) 901 (if (string-match completion--embedded-envvar-re
796 (if (eq (aref string (1- beg)) ?{) 902 (substring string 0 pos))
797 (setq table (apply-partially 'completion-table-with-terminator 903 (list* 'boundaries (or (match-beginning 2) (match-beginning 1))
798 "}" table))) 904 (when (string-match "[^[:alnum:]_]" suffix)
799 (completion-table-with-context prefix table 905 (+ pos (match-beginning 0))))))
800 (substring string beg) 906 (when (string-match completion--embedded-envvar-re string)
801 pred action)))) 907 (let* ((beg (or (match-beginning 2) (match-beginning 1)))
908 (table (completion--make-envvar-table))
909 (prefix (substring string 0 beg)))
910 (if (eq (aref string (1- beg)) ?{)
911 (setq table (apply-partially 'completion-table-with-terminator
912 "}" table)))
913 (completion-table-with-context
914 prefix table (substring string beg) pred action)))))
802 915
803(defun completion--file-name-table (string pred action) 916(defun completion--file-name-table (string pred action)
804 "Internal subroutine for `read-file-name'. Do not call this." 917 "Internal subroutine for `read-file-name'. Do not call this."
805 (if (and (zerop (length string)) (eq 'lambda action)) 918 (cond
806 nil ; FIXME: why? 919 ((and (zerop (length string)) (eq 'lambda action))
920 nil) ; FIXME: why?
921 ((eq (car-safe action) 'boundaries)
922 ;; FIXME: Actually, this is not always right in the presence of
923 ;; envvars, but there's not much we can do, I think.
924 (let ((start (length (file-name-directory
925 (substring string 0 (cdr action)))))
926 (end (string-match "/" string (cdr action))))
927 (list* 'boundaries start end)))
928
929 (t
807 (let* ((dir (if (stringp pred) 930 (let* ((dir (if (stringp pred)
808 ;; It used to be that `pred' was abused to pass `dir' 931 ;; It used to be that `pred' was abused to pass `dir'
809 ;; as an argument. 932 ;; as an argument.
@@ -834,8 +957,8 @@ specified by COMMON-SUBSTRING."
834 957
835 ((eq action t) 958 ((eq action t)
836 (let ((all (file-name-all-completions name realdir)) 959 (let ((all (file-name-all-completions name realdir))
837 ;; Actually, this is not always right in the presence of 960 ;; FIXME: Actually, this is not always right in the presence
838 ;; envvars, but there's not much we can do, I think. 961 ;; of envvars, but there's not much we can do, I think.
839 (base-size (length (file-name-directory string)))) 962 (base-size (length (file-name-directory string))))
840 963
841 ;; Check the predicate, if necessary. 964 ;; Check the predicate, if necessary.
@@ -857,14 +980,13 @@ specified by COMMON-SUBSTRING."
857 980
858 (if (and completion-all-completions-with-base-size (consp all)) 981 (if (and completion-all-completions-with-base-size (consp all))
859 ;; Add base-size, but only if the list is non-empty. 982 ;; Add base-size, but only if the list is non-empty.
860 (nconc all base-size)) 983 (nconc all base-size)
861 984 all)))
862 all))
863 985
864 (t 986 (t
865 ;; Only other case actually used is ACTION = lambda. 987 ;; Only other case actually used is ACTION = lambda.
866 (let ((default-directory dir)) 988 (let ((default-directory dir))
867 (funcall (or read-file-name-predicate 'file-exists-p) str))))))) 989 (funcall (or read-file-name-predicate 'file-exists-p) str))))))))
868 990
869(defalias 'read-file-name-internal 991(defalias 'read-file-name-internal
870 (completion-table-in-turn 'completion--embedded-envvar-table 992 (completion-table-in-turn 'completion--embedded-envvar-table
@@ -1130,13 +1252,13 @@ expression (not containing character ranges like `a-z')."
1130(defun completion-pcm--pattern-trivial-p (pattern) 1252(defun completion-pcm--pattern-trivial-p (pattern)
1131 (and (stringp (car pattern)) (null (cdr pattern)))) 1253 (and (stringp (car pattern)) (null (cdr pattern))))
1132 1254
1133(defun completion-pcm--string->pattern (basestr &optional point) 1255(defun completion-pcm--string->pattern (string &optional point)
1134 "Split BASESTR into a pattern. 1256 "Split STRING into a pattern.
1135A pattern is a list where each element is either a string 1257A pattern is a list where each element is either a string
1136or a symbol chosen among `any', `star', `point'." 1258or a symbol chosen among `any', `star', `point'."
1137 (if (and point (< point (length basestr))) 1259 (if (and point (< point (length string)))
1138 (let ((prefix (substring basestr 0 point)) 1260 (let ((prefix (substring string 0 point))
1139 (suffix (substring basestr point))) 1261 (suffix (substring string point)))
1140 (append (completion-pcm--string->pattern prefix) 1262 (append (completion-pcm--string->pattern prefix)
1141 '(point) 1263 '(point)
1142 (completion-pcm--string->pattern suffix))) 1264 (completion-pcm--string->pattern suffix)))
@@ -1144,9 +1266,9 @@ or a symbol chosen among `any', `star', `point'."
1144 (p 0) 1266 (p 0)
1145 (p0 0)) 1267 (p0 0))
1146 1268
1147 (while (setq p (string-match completion-pcm--delim-wild-regex basestr p)) 1269 (while (setq p (string-match completion-pcm--delim-wild-regex string p))
1148 (push (substring basestr p0 p) pattern) 1270 (push (substring string p0 p) pattern)
1149 (if (eq (aref basestr p) ?*) 1271 (if (eq (aref string p) ?*)
1150 (progn 1272 (progn
1151 (push 'star pattern) 1273 (push 'star pattern)
1152 (setq p0 (1+ p))) 1274 (setq p0 (1+ p)))
@@ -1156,27 +1278,36 @@ or a symbol chosen among `any', `star', `point'."
1156 1278
1157 ;; An empty string might be erroneously added at the beginning. 1279 ;; An empty string might be erroneously added at the beginning.
1158 ;; It should be avoided properly, but it's so easy to remove it here. 1280 ;; It should be avoided properly, but it's so easy to remove it here.
1159 (delete "" (nreverse (cons (substring basestr p0) pattern)))))) 1281 (delete "" (nreverse (cons (substring string p0) pattern))))))
1160 1282
1161(defun completion-pcm--pattern->regex (pattern &optional group) 1283(defun completion-pcm--pattern->regex (pattern &optional group)
1284 (let ((re
1162 (concat "\\`" 1285 (concat "\\`"
1163 (mapconcat 1286 (mapconcat
1164 (lambda (x) 1287 (lambda (x)
1165 (case x 1288 (case x
1166 ((star any point) (if (if (consp group) (memq x group) group) 1289 ((star any point)
1290 (if (if (consp group) (memq x group) group)
1167 "\\(.*?\\)" ".*?")) 1291 "\\(.*?\\)" ".*?"))
1168 (t (regexp-quote x)))) 1292 (t (regexp-quote x))))
1169 pattern 1293 pattern
1170 ""))) 1294 ""))))
1295 ;; Avoid pathological backtracking.
1296 (while (string-match "\\.\\*\\?\\(?:\\\\[()]\\)*\\(\\.\\*\\?\\)" re)
1297 (setq re (replace-match "" t t re 1)))
1298 re))
1171 1299
1172(defun completion-pcm--all-completions (pattern table pred) 1300(defun completion-pcm--all-completions (prefix pattern table pred)
1173 "Find all completions for PATTERN in TABLE obeying PRED. 1301 "Find all completions for PATTERN in TABLE obeying PRED.
1174PATTERN is as returned by `completion-pcm--string->pattern'." 1302PATTERN is as returned by `completion-pcm--string->pattern'."
1175 ;; Find an initial list of possible completions. 1303 ;; Find an initial list of possible completions.
1176 (if (completion-pcm--pattern-trivial-p pattern) 1304 (if (completion-pcm--pattern-trivial-p pattern)
1177 1305
1178 ;; Minibuffer contains no delimiters -- simple case! 1306 ;; Minibuffer contains no delimiters -- simple case!
1179 (all-completions (car pattern) table pred) 1307 (let* ((all (all-completions (concat prefix (car pattern)) table pred))
1308 (last (last all)))
1309 (if last (setcdr last nil))
1310 all)
1180 1311
1181 ;; Use all-completions to do an initial cull. This is a big win, 1312 ;; Use all-completions to do an initial cull. This is a big win,
1182 ;; since all-completions is written in C! 1313 ;; since all-completions is written in C!
@@ -1184,11 +1315,14 @@ PATTERN is as returned by `completion-pcm--string->pattern'."
1184 (regex (completion-pcm--pattern->regex pattern)) 1315 (regex (completion-pcm--pattern->regex pattern))
1185 (completion-regexp-list (cons regex completion-regexp-list)) 1316 (completion-regexp-list (cons regex completion-regexp-list))
1186 (compl (all-completions 1317 (compl (all-completions
1187 (if (stringp (car pattern)) (car pattern) "") 1318 (concat prefix (if (stringp (car pattern)) (car pattern) ""))
1188 table pred)) 1319 table pred))
1189 (last (last compl))) 1320 (last (last compl)))
1190 ;; FIXME: If `base-size' is not 0, we have a problem :-( 1321 (when last
1191 (if last (setcdr last nil)) 1322 (if (and (numberp (cdr last)) (/= (cdr last) (length prefix)))
1323 (message "Inconsistent base-size returned by completion table %s"
1324 table))
1325 (setcdr last nil))
1192 (if (not (functionp table)) 1326 (if (not (functionp table))
1193 ;; The internal functions already obeyed completion-regexp-list. 1327 ;; The internal functions already obeyed completion-regexp-list.
1194 compl 1328 compl
@@ -1224,11 +1358,85 @@ PATTERN is as returned by `completion-pcm--string->pattern'."
1224 completions) 1358 completions)
1225 base-size)))) 1359 base-size))))
1226 1360
1361(defun completion-pcm--find-all-completions (string table pred point)
1362 (let* ((bounds (completion-boundaries string table pred point))
1363 (prefix (substring string 0 (car bounds)))
1364 (suffix (substring string (cdr bounds)))
1365 (origstring string)
1366 firsterror)
1367 (setq string (substring string (car bounds) (cdr bounds)))
1368 (let* ((pattern (completion-pcm--string->pattern
1369 string (- point (car bounds))))
1370 (all (condition-case err
1371 (completion-pcm--all-completions prefix pattern table pred)
1372 (error (unless firsterror (setq firsterror err)) nil))))
1373 (when (and (null all)
1374 (> (car bounds) 0)
1375 (null (ignore-errors (try-completion prefix table pred))))
1376 ;; The prefix has no completions at all, so we should try and fix
1377 ;; that first.
1378 (let ((substring (substring prefix 0 -1)))
1379 (destructuring-bind (subpat suball subprefix subsuffix)
1380 (completion-pcm--find-all-completions
1381 substring table pred (length substring))
1382 (let ((sep (aref prefix (1- (length prefix))))
1383 ;; Text that goes between the new submatches and the
1384 ;; completion substring.
1385 (between nil))
1386 ;; Eliminate submatches that don't end with the separator.
1387 (dolist (submatch (prog1 suball (setq suball ())))
1388 (when (eq sep (aref submatch (1- (length submatch))))
1389 (push submatch suball)))
1390 (when suball
1391 ;; Update the boundaries and corresponding pattern.
1392 ;; We assume that all submatches result in the same boundaries
1393 ;; since we wouldn't know how to merge them otherwise anyway.
1394 (let* ((newstring (concat subprefix (car suball) string suffix))
1395 (newpoint (+ point (- (length newstring)
1396 (length origstring))))
1397 (newbounds (completion-boundaries
1398 newstring table pred newpoint))
1399 (newsubstring
1400 (substring newstring (car newbounds) (cdr newbounds))))
1401 (unless (or (equal newsubstring string)
1402 ;; Refuse new boundaries if they step over
1403 ;; the submatch.
1404 (< (car newbounds)
1405 (+ (length subprefix) (length (car suball)))))
1406 ;; The new completed prefix does change the boundaries
1407 ;; of the completed substring.
1408 (setq suffix (substring newstring (cdr newbounds)))
1409 (setq string newsubstring)
1410 (setq between (substring newstring
1411 (+ (length subprefix)
1412 (length (car suball)))
1413 (car newbounds)))
1414 (setq pattern (completion-pcm--string->pattern
1415 string (- newpoint (car bounds)))))
1416 (dolist (submatch suball)
1417 (setq all (nconc (mapcar
1418 (lambda (s) (concat submatch between s))
1419 (completion-pcm--all-completions
1420 (concat subprefix submatch between)
1421 pattern table pred))
1422 all)))
1423 (unless all
1424 ;; Even though we found expansions in the prefix, none
1425 ;; leads to a valid completion.
1426 ;; Let's keep the expansions, tho.
1427 (dolist (submatch suball)
1428 (push (concat submatch between newsubstring) all)))))
1429 (setq pattern (append subpat (list 'any (string sep))
1430 (if between (list between)) pattern))
1431 (setq prefix subprefix)))))
1432 (if (and (null all) firsterror)
1433 (signal (car firsterror) (cdr firsterror))
1434 (list pattern all prefix suffix)))))
1435
1227(defun completion-pcm-all-completions (string table pred point) 1436(defun completion-pcm-all-completions (string table pred point)
1228 (let ((pattern (completion-pcm--string->pattern string point))) 1437 (destructuring-bind (pattern all &optional prefix suffix)
1229 (completion-pcm--hilit-commonality 1438 (completion-pcm--find-all-completions string table pred point)
1230 pattern 1439 (completion-pcm--hilit-commonality pattern all)))
1231 (completion-pcm--all-completions pattern table pred))))
1232 1440
1233(defun completion-pcm--merge-completions (strs pattern) 1441(defun completion-pcm--merge-completions (strs pattern)
1234 "Extract the commonality in STRS, with the help of PATTERN." 1442 "Extract the commonality in STRS, with the help of PATTERN."
@@ -1289,8 +1497,8 @@ PATTERN is as returned by `completion-pcm--string->pattern'."
1289 "")) 1497 ""))
1290 1498
1291(defun completion-pcm-try-completion (string table pred point) 1499(defun completion-pcm-try-completion (string table pred point)
1292 (let* ((pattern (completion-pcm--string->pattern string point)) 1500 (destructuring-bind (pattern all prefix suffix)
1293 (all (completion-pcm--all-completions pattern table pred))) 1501 (completion-pcm--find-all-completions string table pred point)
1294 (when all 1502 (when all
1295 (let* ((mergedpat (completion-pcm--merge-completions all pattern)) 1503 (let* ((mergedpat (completion-pcm--merge-completions all pattern))
1296 ;; `mergedpat' is in reverse order. Place new point (by 1504 ;; `mergedpat' is in reverse order. Place new point (by
@@ -1303,7 +1511,10 @@ PATTERN is as returned by `completion-pcm--string->pattern'."
1303 (newpos (length (completion-pcm--pattern->string pointpat))) 1511 (newpos (length (completion-pcm--pattern->string pointpat)))
1304 ;; Do it afterwards because it changes `pointpat' by sideeffect. 1512 ;; Do it afterwards because it changes `pointpat' by sideeffect.
1305 (merged (completion-pcm--pattern->string (nreverse mergedpat)))) 1513 (merged (completion-pcm--pattern->string (nreverse mergedpat))))
1306 (cons merged newpos))))) 1514 (if (and (> (length merged) 0) (> (length suffix) 0)
1515 (eq (aref merged (1- (length merged))) (aref suffix 0)))
1516 (setq suffix (substring suffix 1)))
1517 (cons (concat prefix merged suffix) (+ newpos (length prefix)))))))
1307 1518
1308 1519
1309(provide 'minibuffer) 1520(provide 'minibuffer)