diff options
| author | Stefan Monnier | 2012-10-28 14:48:17 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-10-28 14:48:17 -0400 |
| commit | 86957a0cd3f273a83ce6584dcbaf513c2db429dc (patch) | |
| tree | 0966ccd69b87bbe74eef2a57f95c01ed7b5332e1 | |
| parent | 640bf8ad44027d37f917d0927e50c2dfea254917 (diff) | |
| download | emacs-86957a0cd3f273a83ce6584dcbaf513c2db429dc.tar.gz emacs-86957a0cd3f273a83ce6584dcbaf513c2db429dc.zip | |
* lisp/minibuffer.el (completion--sifn-requote): Rewrite to handle things
like Tramp's "/foo:~bar//baz" -> "/scpc:foo:/baz" mapping.
Fixes: debbugs:11714
| -rw-r--r-- | lisp/ChangeLog | 3 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 80 |
2 files changed, 42 insertions, 41 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index c52ed5e6e8b..74e63b140c4 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,5 +1,8 @@ | |||
| 1 | 2012-10-28 Stefan Monnier <monnier@iro.umontreal.ca> | 1 | 2012-10-28 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 2 | ||
| 3 | * minibuffer.el (completion--sifn-requote): Rewrite to handle things | ||
| 4 | like Tramp's "/foo:~bar//baz" -> "/scpc:foo:/baz" mapping (bug#11714). | ||
| 5 | |||
| 3 | * tmm.el (tmm-prompt): Use map-keymap (bug#12744). | 6 | * tmm.el (tmm-prompt): Use map-keymap (bug#12744). |
| 4 | 7 | ||
| 5 | 2012-10-27 Eli Zaretskii <eliz@gnu.org> | 8 | 2012-10-27 Eli Zaretskii <eliz@gnu.org> |
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 52c3a0ba659..420d8f9d0fd 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el | |||
| @@ -378,6 +378,8 @@ Note: TABLE needs to be a proper completion table which obeys predicates." | |||
| 378 | ;; that `concat' and `unquote' commute (which tends to be the case). | 378 | ;; that `concat' and `unquote' commute (which tends to be the case). |
| 379 | ;; And we ask `requote' to do the work of mapping from unquoted positions | 379 | ;; And we ask `requote' to do the work of mapping from unquoted positions |
| 380 | ;; back to quoted positions. | 380 | ;; back to quoted positions. |
| 381 | ;; FIXME: For some forms of "quoting" such as the truncation behavior of | ||
| 382 | ;; substitute-in-file-name, it would be desirable not to requote completely. | ||
| 381 | "Return a new completion table operating on quoted text. | 383 | "Return a new completion table operating on quoted text. |
| 382 | TABLE operates on the unquoted text. | 384 | TABLE operates on the unquoted text. |
| 383 | UNQUOTE is a function that takes a string and returns a new unquoted string. | 385 | UNQUOTE is a function that takes a string and returns a new unquoted string. |
| @@ -2161,53 +2163,49 @@ same as `substitute-in-file-name'." | |||
| 2161 | "use the regular PRED argument" "23.2") | 2163 | "use the regular PRED argument" "23.2") |
| 2162 | 2164 | ||
| 2163 | (defun completion--sifn-requote (upos qstr) | 2165 | (defun completion--sifn-requote (upos qstr) |
| 2164 | ;; We're looking for `qupos' such that: | 2166 | ;; We're looking for `qpos' such that: |
| 2165 | ;; (equal (substring (substitute-in-file-name qstr) 0 upos) | 2167 | ;; (equal (substring (substitute-in-file-name qstr) 0 upos) |
| 2166 | ;; (substitute-in-file-name (substring qstr 0 qupos))) | 2168 | ;; (substitute-in-file-name (substring qstr 0 qpos))) |
| 2167 | ;; Big problem here: we have to reverse engineer substitute-in-file-name to | 2169 | ;; Big problem here: we have to reverse engineer substitute-in-file-name to |
| 2168 | ;; find the position corresponding to UPOS in QSTR, but | 2170 | ;; find the position corresponding to UPOS in QSTR, but |
| 2169 | ;; substitute-in-file-name can do anything, depending on file-name-handlers. | 2171 | ;; substitute-in-file-name can do anything, depending on file-name-handlers. |
| 2172 | ;; substitute-in-file-name does the following kind of things: | ||
| 2173 | ;; - expand env-var references. | ||
| 2174 | ;; - turn backslashes into slashes. | ||
| 2175 | ;; - truncate some prefix of the input. | ||
| 2176 | ;; - rewrite some prefix. | ||
| 2177 | ;; Some of these operations are written in external libraries and we'd rather | ||
| 2178 | ;; not hard code any assumptions here about what they actually do. IOW, we | ||
| 2179 | ;; want to treat substitute-in-file-name as a black box, as much as possible. | ||
| 2170 | ;; Kind of like in rfn-eshadow-update-overlay, only worse. | 2180 | ;; Kind of like in rfn-eshadow-update-overlay, only worse. |
| 2171 | ;; FIXME: example of thing we do not handle: Tramp's makes | 2181 | ;; Example of things we need to handle: |
| 2172 | ;; (substitute-in-file-name "/foo:~/bar//baz") -> "/scpc:foo:/baz". | 2182 | ;; - Tramp (substitute-in-file-name "/foo:~/bar//baz") => "/scpc:foo:/baz". |
| 2173 | ;; FIXME: One way to try and handle "all" cases is to require | 2183 | ;; - Cygwin (substitute-in-file-name "C:\bin") => "/usr/bin" |
| 2174 | ;; substitute-in-file-name to preserve text-properties, so we could | 2184 | ;; (substitute-in-file-name "C:\") => "/" |
| 2175 | ;; apply text-properties to the input string and then look for them in | 2185 | ;; (substitute-in-file-name "C:\bi") => "/bi" |
| 2176 | ;; the output to understand what comes from where. | 2186 | (let* ((ustr (substitute-in-file-name qstr)) |
| 2177 | (let ((qpos 0)) | 2187 | (uprefix (substring ustr 0 upos)) |
| 2178 | ;; Handle substitute-in-file-name's truncation behavior. | 2188 | qprefix) |
| 2179 | (let (tpos) | 2189 | ;; Main assumption: nothing after qpos should affect the text before upos, |
| 2180 | (while (and (string-match "[\\/][~/\\]" qstr qpos) | 2190 | ;; so we can work our way backward from the end of qstr, one character |
| 2181 | ;; Hopefully our regexp covers all truncation cases. | 2191 | ;; at a time. |
| 2182 | ;; Also let's make sure sifn indeed truncates here. | 2192 | ;; Second assumptions: If qpos is far from the end this can be a bit slow, |
| 2193 | ;; so we speed it up by doing a first loop that skips a word at a time. | ||
| 2194 | ;; This word-sized loop is careful not to cut in the middle of env-vars. | ||
| 2195 | (while (let ((boundary (string-match "\\(\\$+{?\\)?\\w+\\W*\\'" qstr))) | ||
| 2196 | (and boundary | ||
| 2183 | (progn | 2197 | (progn |
| 2184 | (setq tpos (1+ (match-beginning 0))) | 2198 | (setq qprefix (substring qstr 0 boundary)) |
| 2185 | (equal (substitute-in-file-name qstr) | 2199 | (string-prefix-p uprefix |
| 2186 | (substitute-in-file-name (substring qstr tpos))))) | 2200 | (substitute-in-file-name qprefix))))) |
| 2187 | (setq qpos tpos))) | 2201 | (setq qstr qprefix)) |
| 2188 | ;; `upos' is relative to the position corresponding to `qpos' in | 2202 | (let ((qpos (length qstr))) |
| 2189 | ;; (substitute-in-file-name qstr), so as qpos moves forward, upos | 2203 | (while (and (> qpos 0) |
| 2190 | ;; gets smaller. | 2204 | (string-prefix-p uprefix |
| 2191 | (while (and (> upos 0) | 2205 | (substitute-in-file-name |
| 2192 | (string-match "\\$\\(\\$\\|\\([[:alnum:]_]+\\|{[^}]*}\\)\\)?" | 2206 | (substring qstr 0 (1- qpos))))) |
| 2193 | qstr qpos)) | 2207 | (setq qpos (1- qpos))) |
| 2194 | (cond | 2208 | (cons qpos #'minibuffer--double-dollars)))) |
| 2195 | ((>= (- (match-beginning 0) qpos) upos) ; UPOS is before current match. | ||
| 2196 | (setq qpos (+ qpos upos)) | ||
| 2197 | (setq upos 0)) | ||
| 2198 | ((not (match-end 1)) ;A sole $: probably an error. | ||
| 2199 | (setq upos (- upos (- (match-end 0) qpos))) | ||
| 2200 | (setq qpos (match-end 0))) | ||
| 2201 | (t | ||
| 2202 | (setq upos (- upos (- (match-beginning 0) qpos))) | ||
| 2203 | (setq qpos (match-end 0)) | ||
| 2204 | (setq upos (- upos (length (substitute-in-file-name | ||
| 2205 | (match-string 0 qstr)))))))) | ||
| 2206 | ;; If `upos' is negative, it's because it's within the expansion of an | ||
| 2207 | ;; envvar, i.e. there is no exactly matching qpos, so we just use the next | ||
| 2208 | ;; available qpos right after the envvar. | ||
| 2209 | (cons (if (>= upos 0) (+ qpos upos) qpos) | ||
| 2210 | #'minibuffer--double-dollars))) | ||
| 2211 | 2209 | ||
| 2212 | (defalias 'completion--file-name-table | 2210 | (defalias 'completion--file-name-table |
| 2213 | (completion-table-with-quoting #'completion-file-name-table | 2211 | (completion-table-with-quoting #'completion-file-name-table |