diff options
| author | Stefan Monnier | 2008-05-20 17:03:30 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2008-05-20 17:03:30 +0000 |
| commit | a38313e1060b24ac303e6d6f67d53f2c9635eb44 (patch) | |
| tree | 00ec663805b59efd5d2d82893d88935bfcbab082 | |
| parent | eb152aa90b1fe5539028d66cfedb880e9d0a6b8f (diff) | |
| download | emacs-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/ChangeLog | 35 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 401 |
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 @@ | |||
| 1 | 2008-05-20 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2008-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 | ||
| 6 | 2008-05-20 Roland Winkler <Roland.Winkler@physik.uni-erlangen.de> | 25 | 2008-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. | ||
| 70 | STRING is the string on which completion will be performed. | ||
| 71 | The result is of the form (START . END) and gives the start and end position | ||
| 72 | corresponding to the substring of STRING that can be completed by one | ||
| 73 | of the elements returned by | ||
| 74 | \(all-completions (substring STRING 0 POS) TABLE PRED). | ||
| 75 | I.e. START is the same as the `completion-base-size'. | ||
| 76 | E.g. for simple completion tables, the result is always (0 . (length STRING)) | ||
| 77 | and for file names the result is the substring around POS delimited by | ||
| 78 | the 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. |
| 48 | Return the first non-nil returned value. | 88 | Return the first non-nil returned value. |
| 49 | Like CL's `some'." | 89 | Like 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. | |||
| 66 | TABLE is the completion table, which should not be a function. | 110 | TABLE is the completion table, which should not be a function. |
| 67 | PRED is a completion predicate. | 111 | PRED is a completion predicate. |
| 68 | ACTION can be one of nil, t or `lambda'." | 112 | ACTION 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. | |||
| 297 | POINT is the position of point within STRING. | 360 | POINT is the position of point within STRING. |
| 298 | The return value is a list of completions and may contain the base-size | 361 | The return value is a list of completions and may contain the base-size |
| 299 | in the last `cdr'." | 362 | in 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. |
| 431 | Otherwise try to complete it. If completion leads to a valid completion, | 494 | Otherwise try to complete it. If completion leads to a valid completion, |
| 432 | a repetition of this command will exit." | 495 | a repetition of this command will exit. |
| 496 | If `minibuffer-completion-confirm' is equal to `confirm', then do not | ||
| 497 | try to complete, but simply ask for confirmation and accept any | ||
| 498 | input 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. | |||
| 561 | Return nil if there is no valid completion, else t." | 635 | Return 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. |
| 1135 | A pattern is a list where each element is either a string | 1257 | A pattern is a list where each element is either a string |
| 1136 | or a symbol chosen among `any', `star', `point'." | 1258 | or 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. |
| 1174 | PATTERN is as returned by `completion-pcm--string->pattern'." | 1302 | PATTERN 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) |