aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2011-05-31 18:40:30 -0300
committerStefan Monnier2011-05-31 18:40:30 -0300
commit30a235016ebe8326593b16ed42daeeaa4dead526 (patch)
tree83d273354080c337be857278eb4567e7bce99fd5
parent5a94384bca430c6cd8161d1825e14639c2a5a7e3 (diff)
downloademacs-30a235016ebe8326593b16ed42daeeaa4dead526.tar.gz
emacs-30a235016ebe8326593b16ed42daeeaa4dead526.zip
* lisp/minibuffer.el (complete-with-action): Return nil for the metadata and
boundaries of non-functional tables. (completion-table-dynamic): Return nil for the metadata. (completion-table-with-terminator): Add default case, using complete-with-action. (completion--metadata): New function. (completion-all-sorted-completions, minibuffer-completion-help): Use it to try and avoid pathological performance problems. (completion--embedded-envvar-table): Return `category' metadata.
-rw-r--r--lisp/ChangeLog12
-rw-r--r--lisp/minibuffer.el99
2 files changed, 72 insertions, 39 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 384a30cb7cd..8f96a838cc5 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,15 @@
12011-05-31 Stefan Monnier <monnier@iro.umontreal.ca>
2
3 * minibuffer.el (complete-with-action): Return nil for the metadata and
4 boundaries of non-functional tables.
5 (completion-table-dynamic): Return nil for the metadata.
6 (completion-table-with-terminator): Add default case, using
7 complete-with-action.
8 (completion--metadata): New function.
9 (completion-all-sorted-completions, minibuffer-completion-help): Use it
10 to try and avoid pathological performance problems.
11 (completion--embedded-envvar-table): Return `category' metadata.
12
12011-05-31 Lars Magne Ingebrigtsen <larsi@gnus.org> 132011-05-31 Lars Magne Ingebrigtsen <larsi@gnus.org>
2 14
3 * subr.el (process-alive-p): New tiny convenience function. 15 * subr.el (process-alive-p): New tiny convenience function.
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 0f96f7905eb..972c65f62e3 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -26,11 +26,15 @@
26;; internal use only. 26;; internal use only.
27 27
28;; Functional completion tables have an extended calling conventions: 28;; Functional completion tables have an extended calling conventions:
29;; - The `action' can be (additionally to nil, t, and lambda) of the form 29;; The `action' can be (additionally to nil, t, and lambda) of the form
30;; (boundaries . SUFFIX) in which case it should return 30;; - (boundaries . SUFFIX) in which case it should return
31;; (boundaries START . END). See `completion-boundaries'. 31;; (boundaries START . END). See `completion-boundaries'.
32;; Any other return value should be ignored (so we ignore values returned 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). 33;; from completion tables that don't know about this new `action' form).
34;; - `metadata' in which case it should return (metadata . ALIST) where
35;; ALIST is the metadata of this table. See `completion-metadata'.
36;; Any other return value should be ignored (so we ignore values returned
37;; from completion tables that don't know about this new `action' form).
34 38
35;;; Bugs: 39;;; Bugs:
36 40
@@ -107,7 +111,8 @@ E.g. for simple completion tables, the result is always (0 . (length SUFFIX))
107and for file names the result is the positions delimited by 111and for file names the result is the positions delimited by
108the closest directory separators." 112the closest directory separators."
109 (let ((boundaries (if (functionp table) 113 (let ((boundaries (if (functionp table)
110 (funcall table string pred (cons 'boundaries suffix))))) 114 (funcall table string pred
115 (cons 'boundaries suffix)))))
111 (if (not (eq (car-safe boundaries) 'boundaries)) 116 (if (not (eq (car-safe boundaries) 'boundaries))
112 (setq boundaries nil)) 117 (setq boundaries nil))
113 (cons (or (cadr boundaries) 0) 118 (cons (or (cadr boundaries) 0)
@@ -125,7 +130,8 @@ This metadata is an alist. Currently understood keys are:
125 Takes one argument (COMPLETIONS) and should return a new list 130 Takes one argument (COMPLETIONS) and should return a new list
126 of completions. Can operate destructively. 131 of completions. Can operate destructively.
127- `cycle-sort-function': function to sort entries when cycling. 132- `cycle-sort-function': function to sort entries when cycling.
128 Works like `display-sort-function'." 133 Works like `display-sort-function'.
134The metadata of a completion table should be constant between two boundaries."
129 (let ((metadata (if (functionp table) 135 (let ((metadata (if (functionp table)
130 (funcall table string pred 'metadata)))) 136 (funcall table string pred 'metadata))))
131 (if (eq (car-safe metadata) 'metadata) 137 (if (eq (car-safe metadata) 'metadata)
@@ -160,8 +166,8 @@ PRED is a completion predicate.
160ACTION can be one of nil, t or `lambda'." 166ACTION can be one of nil, t or `lambda'."
161 (cond 167 (cond
162 ((functionp table) (funcall table string pred action)) 168 ((functionp table) (funcall table string pred action))
163 ((eq (car-safe action) 'boundaries) 169 ((eq (car-safe action) 'boundaries) nil)
164 (cons 'boundaries (completion-boundaries string table pred (cdr action)))) 170 ((eq action 'metadata) nil)
165 (t 171 (t
166 (funcall 172 (funcall
167 (cond 173 (cond
@@ -182,7 +188,7 @@ The result of the `completion-table-dynamic' form is a function
182that can be used as the COLLECTION argument to `try-completion' and 188that can be used as the COLLECTION argument to `try-completion' and
183`all-completions'. See Info node `(elisp)Programmed Completion'." 189`all-completions'. See Info node `(elisp)Programmed Completion'."
184 (lambda (string pred action) 190 (lambda (string pred action)
185 (if (eq (car-safe action) 'boundaries) 191 (if (or (eq (car-safe action) 'boundaries) (eq action 'metadata))
186 ;; `fun' is not supposed to return another function but a plain old 192 ;; `fun' is not supposed to return another function but a plain old
187 ;; completion table, whose boundaries are always trivial. 193 ;; completion table, whose boundaries are always trivial.
188 nil 194 nil
@@ -287,18 +293,18 @@ instead of a string, a function that takes the completion and returns the
287 (funcall terminator comp) 293 (funcall terminator comp)
288 (concat comp terminator)) 294 (concat comp terminator))
289 comp)))) 295 comp))))
290 ((eq action t) 296 ;; completion-table-with-terminator is always used for
297 ;; "sub-completions" so it's only called if the terminator is missing,
298 ;; in which case `test-completion' should return nil.
299 ((eq action 'lambda) nil)
300 (t
291 ;; FIXME: We generally want the `try' and `all' behaviors to be 301 ;; FIXME: We generally want the `try' and `all' behaviors to be
292 ;; consistent so pcm can merge the `all' output to get the `try' output, 302 ;; consistent so pcm can merge the `all' output to get the `try' output,
293 ;; but that sometimes clashes with the need for `all' output to look 303 ;; but that sometimes clashes with the need for `all' output to look
294 ;; good in *Completions*. 304 ;; good in *Completions*.
295 ;; (mapcar (lambda (s) (concat s terminator)) 305 ;; (mapcar (lambda (s) (concat s terminator))
296 ;; (all-completions string table pred)))) 306 ;; (all-completions string table pred))))
297 (all-completions string table pred)) 307 (complete-with-action action table string pred))))
298 ;; completion-table-with-terminator is always used for
299 ;; "sub-completions" so it's only called if the terminator is missing,
300 ;; in which case `test-completion' should return nil.
301 ((eq action 'lambda) nil)))
302 308
303(defun completion-table-with-predicate (table pred1 strict string pred2 action) 309(defun completion-table-with-predicate (table pred1 strict string pred2 action)
304 "Make a completion table equivalent to TABLE but filtered through PRED1. 310 "Make a completion table equivalent to TABLE but filtered through PRED1.
@@ -769,22 +775,33 @@ scroll the window of possible completions."
769 (setq completion-cycling nil) 775 (setq completion-cycling nil)
770 (setq completion-all-sorted-completions nil)) 776 (setq completion-all-sorted-completions nil))
771 777
778(defun completion--metadata (string base md-at-point table pred)
779 ;; Like completion-metadata, but for the specific case of getting the
780 ;; metadata at `base', which tends to trigger pathological behavior for old
781 ;; completion tables which don't understand `metadata'.
782 (let ((bounds (completion-boundaries string table pred "")))
783 (if (eq (car bounds) base) md-at-point
784 (completion-metadata (substring string 0 base) table pred))))
785
772(defun completion-all-sorted-completions () 786(defun completion-all-sorted-completions ()
773 (or completion-all-sorted-completions 787 (or completion-all-sorted-completions
774 (let* ((start (field-beginning)) 788 (let* ((start (field-beginning))
775 (end (field-end)) 789 (end (field-end))
776 (string (buffer-substring start end)) 790 (string (buffer-substring start end))
791 (md (completion--field-metadata start))
777 (all (completion-all-completions 792 (all (completion-all-completions
778 string 793 string
779 minibuffer-completion-table 794 minibuffer-completion-table
780 minibuffer-completion-predicate 795 minibuffer-completion-predicate
781 (- (point) start) 796 (- (point) start)
782 (completion--field-metadata start))) 797 md))
783 (last (last all)) 798 (last (last all))
784 (base-size (or (cdr last) 0)) 799 (base-size (or (cdr last) 0))
785 (all-md (completion-metadata (substring string 0 base-size) 800 (all-md (completion--metadata (buffer-substring-no-properties
786 minibuffer-completion-table 801 start (point))
787 minibuffer-completion-predicate)) 802 base-size md
803 minibuffer-completion-table
804 minibuffer-completion-predicate))
788 (sort-fun (completion-metadata-get all-md 'cycle-sort-function))) 805 (sort-fun (completion-metadata-get all-md 'cycle-sort-function)))
789 (when last 806 (when last
790 (setcdr last nil) 807 (setcdr last nil)
@@ -1272,12 +1289,13 @@ variables.")
1272 (let* ((start (field-beginning)) 1289 (let* ((start (field-beginning))
1273 (end (field-end)) 1290 (end (field-end))
1274 (string (field-string)) 1291 (string (field-string))
1292 (md (completion--field-metadata start))
1275 (completions (completion-all-completions 1293 (completions (completion-all-completions
1276 string 1294 string
1277 minibuffer-completion-table 1295 minibuffer-completion-table
1278 minibuffer-completion-predicate 1296 minibuffer-completion-predicate
1279 (- (point) (field-beginning)) 1297 (- (point) (field-beginning))
1280 (completion--field-metadata start)))) 1298 md)))
1281 (message nil) 1299 (message nil)
1282 (if (or (null completions) 1300 (if (or (null completions)
1283 (and (not (consp (cdr completions))) 1301 (and (not (consp (cdr completions)))
@@ -1293,12 +1311,11 @@ variables.")
1293 (let* ((last (last completions)) 1311 (let* ((last (last completions))
1294 (base-size (cdr last)) 1312 (base-size (cdr last))
1295 (prefix (unless (zerop base-size) (substring string 0 base-size))) 1313 (prefix (unless (zerop base-size) (substring string 0 base-size)))
1296 ;; FIXME: This function is for the output of all-completions, 1314 (all-md (completion--metadata (buffer-substring-no-properties
1297 ;; not completion-all-completions. Often it's the same, but 1315 start (point))
1298 ;; not always. 1316 base-size md
1299 (all-md (completion-metadata (substring string 0 base-size) 1317 minibuffer-completion-table
1300 minibuffer-completion-table 1318 minibuffer-completion-predicate))
1301 minibuffer-completion-predicate))
1302 (afun (or (completion-metadata-get all-md 'annotation-function) 1319 (afun (or (completion-metadata-get all-md 'annotation-function)
1303 (plist-get completion-extra-properties 1320 (plist-get completion-extra-properties
1304 :annotation-function) 1321 :annotation-function)
@@ -1673,8 +1690,8 @@ same as `substitute-in-file-name'."
1673 ;; other table that provides the "main" completion. Let the 1690 ;; other table that provides the "main" completion. Let the
1674 ;; other table handle the test-completion case. 1691 ;; other table handle the test-completion case.
1675 nil) 1692 nil)
1676 ((eq (car-safe action) 'boundaries) 1693 ((or (eq (car-safe action) 'boundaries) (eq action 'metadata))
1677 ;; Only return boundaries if there's something to complete, 1694 ;; Only return boundaries/metadata if there's something to complete,
1678 ;; since otherwise when we're used in 1695 ;; since otherwise when we're used in
1679 ;; completion-table-in-turn, we could return boundaries and 1696 ;; completion-table-in-turn, we could return boundaries and
1680 ;; let some subsequent table return a list of completions. 1697 ;; let some subsequent table return a list of completions.
@@ -1684,11 +1701,13 @@ same as `substitute-in-file-name'."
1684 (when (try-completion (substring string beg) table nil) 1701 (when (try-completion (substring string beg) table nil)
1685 ;; Compute the boundaries of the subfield to which this 1702 ;; Compute the boundaries of the subfield to which this
1686 ;; completion applies. 1703 ;; completion applies.
1687 (let ((suffix (cdr action))) 1704 (if (eq action 'metadata)
1688 (list* 'boundaries 1705 '(metadata (category . environment-variable))
1689 (or (match-beginning 2) (match-beginning 1)) 1706 (let ((suffix (cdr action)))
1690 (when (string-match "[^[:alnum:]_]" suffix) 1707 (list* 'boundaries
1691 (match-beginning 0)))))) 1708 (or (match-beginning 2) (match-beginning 1))
1709 (when (string-match "[^[:alnum:]_]" suffix)
1710 (match-beginning 0)))))))
1692 (t 1711 (t
1693 (if (eq (aref string (1- beg)) ?{) 1712 (if (eq (aref string (1- beg)) ?{)
1694 (setq table (apply-partially 'completion-table-with-terminator 1713 (setq table (apply-partially 'completion-table-with-terminator
@@ -2299,7 +2318,8 @@ PATTERN is as returned by `completion-pcm--string->pattern'."
2299 (case-fold-search completion-ignore-case) 2318 (case-fold-search completion-ignore-case)
2300 (completion-regexp-list (cons regex completion-regexp-list)) 2319 (completion-regexp-list (cons regex completion-regexp-list))
2301 (compl (all-completions 2320 (compl (all-completions
2302 (concat prefix (if (stringp (car pattern)) (car pattern) "")) 2321 (concat prefix
2322 (if (stringp (car pattern)) (car pattern) ""))
2303 table pred))) 2323 table pred)))
2304 (if (not (functionp table)) 2324 (if (not (functionp table))
2305 ;; The internal functions already obeyed completion-regexp-list. 2325 ;; The internal functions already obeyed completion-regexp-list.
@@ -2397,13 +2417,14 @@ filter out additional entries (because TABLE migth not obey PRED)."
2397 (- (length newbeforepoint) 2417 (- (length newbeforepoint)
2398 (car newbounds))))) 2418 (car newbounds)))))
2399 (dolist (submatch suball) 2419 (dolist (submatch suball)
2400 (setq all (nconc (mapcar 2420 (setq all (nconc
2401 (lambda (s) (concat submatch between s)) 2421 (mapcar
2402 (funcall filter 2422 (lambda (s) (concat submatch between s))
2403 (completion-pcm--all-completions 2423 (funcall filter
2404 (concat subprefix submatch between) 2424 (completion-pcm--all-completions
2405 pattern table pred))) 2425 (concat subprefix submatch between)
2406 all))) 2426 pattern table pred)))
2427 all)))
2407 ;; FIXME: This can come in handy for try-completion, 2428 ;; FIXME: This can come in handy for try-completion,
2408 ;; but isn't right for all-completions, since it lists 2429 ;; but isn't right for all-completions, since it lists
2409 ;; invalid completions. 2430 ;; invalid completions.