diff options
| author | Stefan Monnier | 2012-04-25 14:42:15 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-04-25 14:42:15 -0400 |
| commit | 79c4eeb45046eca02bd4a5daad1b673eb48377a1 (patch) | |
| tree | 0c53c432ebbf22f3a1ae19476ad410d13a34f72a | |
| parent | ef24141c3621b7f283a9ae653473109ee7164e2b (diff) | |
| download | emacs-79c4eeb45046eca02bd4a5daad1b673eb48377a1.tar.gz emacs-79c4eeb45046eca02bd4a5daad1b673eb48377a1.zip | |
* lisp/minibuffer.el: Use completion-table-with-quoting for read-file-name.
(minibuffer--double-dollars): Preserve properties.
(completion--sifn-requote): New function.
(completion--file-name-table): Rewrite using it and c-t-with-quoting.
| -rw-r--r-- | lisp/ChangeLog | 5 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 83 |
2 files changed, 39 insertions, 49 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0eb1293f2ac..8a21f5966c7 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,10 @@ | |||
| 1 | 2012-04-25 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2012-04-25 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * minibuffer.el: Use completion-table-with-quoting for read-file-name. | ||
| 4 | (minibuffer--double-dollars): Preserve properties. | ||
| 5 | (completion--sifn-requote): New function. | ||
| 6 | (completion--file-name-table): Rewrite using it and c-t-with-quoting. | ||
| 7 | |||
| 3 | * minibuffer.el: Add support for completion of quoted/escaped data. | 8 | * minibuffer.el: Add support for completion of quoted/escaped data. |
| 4 | (completion-table-with-quoting, completion-table-subvert): New funs. | 9 | (completion-table-with-quoting, completion-table-subvert): New funs. |
| 5 | (completion--twq-try, completion--twq-all): New functions. | 10 | (completion--twq-try, completion--twq-all): New functions. |
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 3f2bbd7999c..b1e9ccbdba8 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el | |||
| @@ -1976,7 +1976,10 @@ This is only used when the minibuffer area has no active minibuffer.") | |||
| 1976 | ;;; Completion tables. | 1976 | ;;; Completion tables. |
| 1977 | 1977 | ||
| 1978 | (defun minibuffer--double-dollars (str) | 1978 | (defun minibuffer--double-dollars (str) |
| 1979 | (replace-regexp-in-string "\\$" "$$" str)) | 1979 | ;; Reuse the actual "$" from the string to preserve any text-property it |
| 1980 | ;; might have, such as `face'. | ||
| 1981 | (replace-regexp-in-string "\\$" (lambda (dollar) (concat dollar dollar)) | ||
| 1982 | str)) | ||
| 1980 | 1983 | ||
| 1981 | (defun completion--make-envvar-table () | 1984 | (defun completion--make-envvar-table () |
| 1982 | (mapcar (lambda (enventry) | 1985 | (mapcar (lambda (enventry) |
| @@ -2102,58 +2105,40 @@ same as `substitute-in-file-name'." | |||
| 2102 | (make-obsolete-variable 'read-file-name-predicate | 2105 | (make-obsolete-variable 'read-file-name-predicate |
| 2103 | "use the regular PRED argument" "23.2") | 2106 | "use the regular PRED argument" "23.2") |
| 2104 | 2107 | ||
| 2105 | (defun completion--file-name-table (string pred action) | 2108 | (defun completion--sifn-requote (upos qstr) |
| 2109 | (let ((qpos 0)) | ||
| 2110 | (while (and (> upos 0) | ||
| 2111 | (string-match "\\$\\(\\$\\|\\([[:alnum:]_]+\\|{[^}]*}\\)\\)?" | ||
| 2112 | qstr qpos)) | ||
| 2113 | (cond | ||
| 2114 | ((>= (- (match-beginning 0) qpos) upos) ; UPOS is before current match. | ||
| 2115 | (setq qpos (+ qpos upos)) | ||
| 2116 | (setq upos 0)) | ||
| 2117 | ((not (match-end 1)) ;A sole $: probably an error. | ||
| 2118 | (setq upos (- upos (- (match-end 0) qpos))) | ||
| 2119 | (setq qpos (match-end 0))) | ||
| 2120 | (t | ||
| 2121 | (setq upos (- upos (- (match-beginning 0) qpos))) | ||
| 2122 | (setq qpos (match-end 0)) | ||
| 2123 | (setq upos (- upos (length (substitute-in-file-name | ||
| 2124 | (match-string 0 qstr)))))))) | ||
| 2125 | ;; If `upos' is negative, it's because it's within the expansion of an | ||
| 2126 | ;; envvar, i.e. there is no exactly matching qpos, so we just use the next | ||
| 2127 | ;; available qpos right after the envvar. | ||
| 2128 | (cons (if (>= upos 0) (+ qpos upos) qpos) | ||
| 2129 | #'minibuffer--double-dollars))) | ||
| 2130 | |||
| 2131 | (defalias 'completion--file-name-table | ||
| 2132 | (completion-table-with-quoting #'completion-file-name-table | ||
| 2133 | #'substitute-in-file-name | ||
| 2134 | #'completion--sifn-requote) | ||
| 2106 | "Internal subroutine for `read-file-name'. Do not call this. | 2135 | "Internal subroutine for `read-file-name'. Do not call this. |
| 2107 | This is a completion table for file names, like `completion-file-name-table' | 2136 | This is a completion table for file names, like `completion-file-name-table' |
| 2108 | except that it passes the file name through `substitute-in-file-name'." | 2137 | except that it passes the file name through `substitute-in-file-name'.") |
| 2109 | (cond | ||
| 2110 | ((eq (car-safe action) 'boundaries) | ||
| 2111 | ;; For the boundaries, we can't really delegate to | ||
| 2112 | ;; substitute-in-file-name+completion-file-name-table and then fix | ||
| 2113 | ;; them up (as we do for the other actions), because it would | ||
| 2114 | ;; require us to track the relationship between `str' and | ||
| 2115 | ;; `string', which is difficult. And in any case, if | ||
| 2116 | ;; substitute-in-file-name turns "fo-$TO-ba" into "fo-o/b-ba", | ||
| 2117 | ;; there's no way for us to return proper boundaries info, because | ||
| 2118 | ;; the boundary is not (yet) in `string'. | ||
| 2119 | ;; | ||
| 2120 | ;; FIXME: Actually there is a way to return correct boundaries | ||
| 2121 | ;; info, at the condition of modifying the all-completions | ||
| 2122 | ;; return accordingly. But for now, let's not bother. | ||
| 2123 | (completion-file-name-table string pred action)) | ||
| 2124 | |||
| 2125 | (t | ||
| 2126 | (let* ((default-directory | ||
| 2127 | (if (stringp pred) | ||
| 2128 | ;; It used to be that `pred' was abused to pass `dir' | ||
| 2129 | ;; as an argument. | ||
| 2130 | (prog1 (file-name-as-directory (expand-file-name pred)) | ||
| 2131 | (setq pred nil)) | ||
| 2132 | default-directory)) | ||
| 2133 | (str (condition-case nil | ||
| 2134 | (substitute-in-file-name string) | ||
| 2135 | (error string))) | ||
| 2136 | (comp (completion-file-name-table | ||
| 2137 | str | ||
| 2138 | (with-no-warnings (or pred read-file-name-predicate)) | ||
| 2139 | action))) | ||
| 2140 | |||
| 2141 | (cond | ||
| 2142 | ((stringp comp) | ||
| 2143 | ;; Requote the $s before returning the completion. | ||
| 2144 | (minibuffer--double-dollars comp)) | ||
| 2145 | ((and (null action) comp | ||
| 2146 | ;; Requote the $s before checking for changes. | ||
| 2147 | (setq str (minibuffer--double-dollars str)) | ||
| 2148 | (not (string-equal string str))) | ||
| 2149 | ;; If there's no real completion, but substitute-in-file-name | ||
| 2150 | ;; changed the string, then return the new string. | ||
| 2151 | str) | ||
| 2152 | (t comp)))))) | ||
| 2153 | 2138 | ||
| 2154 | (defalias 'read-file-name-internal | 2139 | (defalias 'read-file-name-internal |
| 2155 | (completion-table-in-turn 'completion--embedded-envvar-table | 2140 | (completion-table-in-turn #'completion--embedded-envvar-table |
| 2156 | 'completion--file-name-table) | 2141 | #'completion--file-name-table) |
| 2157 | "Internal subroutine for `read-file-name'. Do not call this.") | 2142 | "Internal subroutine for `read-file-name'. Do not call this.") |
| 2158 | 2143 | ||
| 2159 | (defvar read-file-name-function 'read-file-name-default | 2144 | (defvar read-file-name-function 'read-file-name-default |