diff options
| author | Stefan Monnier | 2012-04-25 14:40:42 -0400 |
|---|---|---|
| committer | Stefan Monnier | 2012-04-25 14:40:42 -0400 |
| commit | ef24141c3621b7f283a9ae653473109ee7164e2b (patch) | |
| tree | 2001eab049f93eb3a37ec81d1dde48da74fe550e | |
| parent | daf75653c2f1301332eb6c8af830050794ae0877 (diff) | |
| download | emacs-ef24141c3621b7f283a9ae653473109ee7164e2b.tar.gz emacs-ef24141c3621b7f283a9ae653473109ee7164e2b.zip | |
* lisp/minibuffer.el: Add support for completion of quoted/escaped data.
(completion-table-with-quoting, completion-table-subvert): New funs.
(completion--twq-try, completion--twq-all): New functions.
(completion--nth-completion): New function.
(completion-try-completion, completion-all-completions): Use it.
| -rw-r--r-- | etc/NEWS | 8 | ||||
| -rw-r--r-- | lisp/ChangeLog | 61 | ||||
| -rw-r--r-- | lisp/minibuffer.el | 282 |
3 files changed, 294 insertions, 57 deletions
| @@ -169,6 +169,14 @@ still be supported for Emacs 24.x. | |||
| 169 | 169 | ||
| 170 | 170 | ||
| 171 | * Lisp changes in Emacs 24.2 | 171 | * Lisp changes in Emacs 24.2 |
| 172 | |||
| 173 | ** Completion | ||
| 174 | |||
| 175 | *** New function `completion-table-with-quoting' to handle completion | ||
| 176 | in the presence of quoting, such as file completion in shell buffers. | ||
| 177 | |||
| 178 | *** New function `completion-table-subvert' to use an existing completion | ||
| 179 | table, but with a different prefix. | ||
| 172 | 180 | ||
| 173 | * Changes in Emacs 24.2 on non-free operating systems | 181 | * Changes in Emacs 24.2 on non-free operating systems |
| 174 | 182 | ||
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 81313efc69b..0eb1293f2ac 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2012-04-25 Stefan Monnier <monnier@iro.umontreal.ca> | ||
| 2 | |||
| 3 | * minibuffer.el: Add support for completion of quoted/escaped data. | ||
| 4 | (completion-table-with-quoting, completion-table-subvert): New funs. | ||
| 5 | (completion--twq-try, completion--twq-all): New functions. | ||
| 6 | (completion--nth-completion): New function. | ||
| 7 | (completion-try-completion, completion-all-completions): Use it. | ||
| 8 | |||
| 1 | 2012-04-25 Chong Yidong <cyd@gnu.org> | 9 | 2012-04-25 Chong Yidong <cyd@gnu.org> |
| 2 | 10 | ||
| 3 | * vc/diff-mode.el (diff-setup-whitespace): New function. | 11 | * vc/diff-mode.el (diff-setup-whitespace): New function. |
| @@ -16,32 +24,31 @@ | |||
| 16 | 24 | ||
| 17 | 2012-04-25 Alex Harsanyi <AlexHarsanyi@gmail.com> | 25 | 2012-04-25 Alex Harsanyi <AlexHarsanyi@gmail.com> |
| 18 | 26 | ||
| 19 | Sync with soap-client repository. Support SOAP simpleType. (Bug#10331) | 27 | Sync with soap-client repository. Support SOAP simpleType (Bug#10331). |
| 20 | 28 | ||
| 21 | * soap-client.el (soap-resolve-references-for-sequence-type) | 29 | * soap-client.el (soap-resolve-references-for-sequence-type) |
| 22 | (soap-resolve-references-for-array-type): hack to prevent self | 30 | (soap-resolve-references-for-array-type): Hack to prevent self |
| 23 | references, see Bug#9. | 31 | references, see Bug#9. |
| 24 | (soap-parse-envelope): report the contents of the 'detail' node | 32 | (soap-parse-envelope): Report the contents of the 'detail' node |
| 25 | when receiving a fault reply. | 33 | when receiving a fault reply. |
| 26 | (soap-parse-envelope): report the contents of the entire 'detail' | 34 | (soap-parse-envelope): Report the contents of the entire 'detail' node. |
| 27 | node. | ||
| 28 | 35 | ||
| 29 | * soap-inspect.el (soap-sample-value-for-simple-type) | 36 | * soap-inspect.el (soap-sample-value-for-simple-type) |
| 30 | (soap-inspect-simple-type): new function | 37 | (soap-inspect-simple-type): New function. |
| 31 | 38 | ||
| 32 | * soap-client.el (soap-simple-type): new struct | 39 | * soap-client.el (soap-simple-type): New struct. |
| 33 | (soap-default-xsd-types, soap-default-soapenc-types) | 40 | (soap-default-xsd-types, soap-default-soapenc-types) |
| 34 | (soap-decode-basic-type, soap-encode-basic-type): support | 41 | (soap-decode-basic-type, soap-encode-basic-type): |
| 35 | unsignedInt and double basic types | 42 | support unsignedInt and double basic types. |
| 36 | (soap-resolve-references-for-simple-type) | 43 | (soap-resolve-references-for-simple-type) |
| 37 | (soap-parse-simple-type, soap-encode-simple-type): new function | 44 | (soap-parse-simple-type, soap-encode-simple-type): New function. |
| 38 | (soap-parse-schema): parse xsd:simpleType declarations | 45 | (soap-parse-schema): Parse xsd:simpleType declarations. |
| 39 | 46 | ||
| 40 | * soap-client.el (soap-default-xsd-types) | 47 | * soap-client.el (soap-default-xsd-types) |
| 41 | (soap-default-soapenc-types): add integer, byte and anyURI types | 48 | (soap-default-soapenc-types): Add integer, byte and anyURI types. |
| 42 | (soap-parse-complex-type-complex-content): use `soap-wk2l' to find | 49 | (soap-parse-complex-type-complex-content): Use `soap-wk2l' to find |
| 43 | the local name of "soapenc:Array" | 50 | the local name of "soapenc:Array". |
| 44 | (soap-decode-basic-type, soap-encode-basic-type): support encoding | 51 | (soap-decode-basic-type, soap-encode-basic-type): Support encoding |
| 45 | decoding integer, byte and anyURI xsd types. | 52 | decoding integer, byte and anyURI xsd types. |
| 46 | 53 | ||
| 47 | 2012-04-25 Chong Yidong <cyd@gnu.org> | 54 | 2012-04-25 Chong Yidong <cyd@gnu.org> |
| @@ -161,8 +168,8 @@ | |||
| 161 | 168 | ||
| 162 | * ispell.el (ispell-insert-word) Remove unneeded function using | 169 | * ispell.el (ispell-insert-word) Remove unneeded function using |
| 163 | obsolete `translation-table-for-input'. | 170 | obsolete `translation-table-for-input'. |
| 164 | (ispell-word, ispell-process-line, ispell-complete-word): Use | 171 | (ispell-word, ispell-process-line, ispell-complete-word): |
| 165 | plain `insert' instead of removed `ispell-insert-word'. | 172 | Use plain `insert' instead of removed `ispell-insert-word'. |
| 166 | 173 | ||
| 167 | 2012-04-22 Chong Yidong <cyd@gnu.org> | 174 | 2012-04-22 Chong Yidong <cyd@gnu.org> |
| 168 | 175 | ||
| @@ -180,8 +187,8 @@ | |||
| 180 | Move functions from C to Lisp. Make non-blocking method calls | 187 | Move functions from C to Lisp. Make non-blocking method calls |
| 181 | the default. Implement further D-Bus standard interfaces. | 188 | the default. Implement further D-Bus standard interfaces. |
| 182 | 189 | ||
| 183 | * net/dbus.el (dbus-message-internal): Declare function. Remove | 190 | * net/dbus.el (dbus-message-internal): Declare function. |
| 184 | unneeded function declarations. | 191 | Remove unneeded function declarations. |
| 185 | (defvar dbus-message-type-invalid, dbus-message-type-method-call) | 192 | (defvar dbus-message-type-invalid, dbus-message-type-method-call) |
| 186 | (dbus-message-type-method-return, dbus-message-type-error) | 193 | (dbus-message-type-method-return, dbus-message-type-error) |
| 187 | (dbus-message-type-signal): Declare variables. Remove local | 194 | (dbus-message-type-signal): Declare variables. Remove local |
| @@ -197,8 +204,8 @@ | |||
| 197 | (dbus-register-signal, dbus-register-method): New defuns, moved | 204 | (dbus-register-signal, dbus-register-method): New defuns, moved |
| 198 | from dbusbind.c | 205 | from dbusbind.c |
| 199 | (dbus-call-method-handler, dbus-setenv) | 206 | (dbus-call-method-handler, dbus-setenv) |
| 200 | (dbus-get-all-managed-objects, dbus-managed-objects-handler): New | 207 | (dbus-get-all-managed-objects, dbus-managed-objects-handler): |
| 201 | defuns. | 208 | New defuns. |
| 202 | (dbus-call-method-non-blocking): Make it an obsolete function. | 209 | (dbus-call-method-non-blocking): Make it an obsolete function. |
| 203 | (dbus-unregister-object, dbus-unregister-service) | 210 | (dbus-unregister-object, dbus-unregister-service) |
| 204 | (dbus-handle-event, dbus-register-property) | 211 | (dbus-handle-event, dbus-register-property) |
| @@ -323,8 +330,8 @@ | |||
| 323 | 330 | ||
| 324 | 2012-04-20 Chong Yidong <cyd@gnu.org> | 331 | 2012-04-20 Chong Yidong <cyd@gnu.org> |
| 325 | 332 | ||
| 326 | * progmodes/gdb-mi.el (gdb-inferior-io--maybe-delete-pty): New | 333 | * progmodes/gdb-mi.el (gdb-inferior-io--maybe-delete-pty): |
| 327 | function to call delete-process on the gdb-inferior buffer's pty. | 334 | New function to call delete-process on the gdb-inferior buffer's pty. |
| 328 | (gdb-reset): Use it, instead of relying on kill-buffer to kill the | 335 | (gdb-reset): Use it, instead of relying on kill-buffer to kill the |
| 329 | pty process (Bug#11273). | 336 | pty process (Bug#11273). |
| 330 | (gdb-update): New arg to suppress talking to the gdb process. | 337 | (gdb-update): New arg to suppress talking to the gdb process. |
| @@ -355,8 +362,8 @@ | |||
| 355 | (c-comment-indent, c-scan-conditionals, c-indent-defun) | 362 | (c-comment-indent, c-scan-conditionals, c-indent-defun) |
| 356 | (c-context-line-break): Bind case-fold-search to nil. | 363 | (c-context-line-break): Bind case-fold-search to nil. |
| 357 | 364 | ||
| 358 | * progmodes/cc-mode.el (c-font-lock-fontify-region): Bind | 365 | * progmodes/cc-mode.el (c-font-lock-fontify-region): |
| 359 | case-fold-search to nil. | 366 | Bind case-fold-search to nil. |
| 360 | 367 | ||
| 361 | 2012-04-20 Chong Yidong <cyd@gnu.org> | 368 | 2012-04-20 Chong Yidong <cyd@gnu.org> |
| 362 | 369 | ||
| @@ -1107,8 +1114,8 @@ | |||
| 1107 | 1114 | ||
| 1108 | 2012-03-30 AgustÃn MartÃn Domingo <agustin.martin@hispalinux.es> | 1115 | 2012-03-30 AgustÃn MartÃn Domingo <agustin.martin@hispalinux.es> |
| 1109 | 1116 | ||
| 1110 | * ispell.el (ispell-get-extended-character-mode): Disable | 1117 | * ispell.el (ispell-get-extended-character-mode): |
| 1111 | extended-char-mode for hunspell. hunspell does not support it | 1118 | Disable extended-char-mode for hunspell. hunspell does not support it |
| 1112 | and treats ~word as ordinary words in pipe mode. | 1119 | and treats ~word as ordinary words in pipe mode. |
| 1113 | 1120 | ||
| 1114 | 2012-03-30 Glenn Morris <rgm@gnu.org> | 1121 | 2012-03-30 Glenn Morris <rgm@gnu.org> |
diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 5a990f6ab35..3f2bbd7999c 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el | |||
| @@ -45,17 +45,6 @@ | |||
| 45 | ;; corresponding to the displayed completions because we only | 45 | ;; corresponding to the displayed completions because we only |
| 46 | ;; provide the start info but not the end info in | 46 | ;; provide the start info but not the end info in |
| 47 | ;; completion-base-position. | 47 | ;; completion-base-position. |
| 48 | ;; - quoting is problematic. E.g. the double-dollar quoting used in | ||
| 49 | ;; substitute-in-file-name (and hence read-file-name-internal) bumps | ||
| 50 | ;; into various bugs: | ||
| 51 | ;; - choose-completion doesn't know how to quote the text it inserts. | ||
| 52 | ;; E.g. it fails to double the dollars in file-name completion, or | ||
| 53 | ;; to backslash-escape spaces and other chars in comint completion. | ||
| 54 | ;; - when completing ~/tmp/fo$$o, the highlighting in *Completions* | ||
| 55 | ;; is off by one position. | ||
| 56 | ;; - all code like PCM which relies on all-completions to match | ||
| 57 | ;; its argument gets confused because all-completions returns unquoted | ||
| 58 | ;; texts (as desired for *Completions* output). | ||
| 59 | ;; - C-x C-f ~/*/sr ? should not list "~/./src". | 48 | ;; - C-x C-f ~/*/sr ? should not list "~/./src". |
| 60 | ;; - minibuffer-force-complete completes ~/src/emacs/t<!>/lisp/minibuffer.el | 49 | ;; - minibuffer-force-complete completes ~/src/emacs/t<!>/lisp/minibuffer.el |
| 61 | ;; to ~/src/emacs/trunk/ and throws away lisp/minibuffer.el. | 50 | ;; to ~/src/emacs/trunk/ and throws away lisp/minibuffer.el. |
| @@ -66,12 +55,9 @@ | |||
| 66 | ;; - Make things like icomplete-mode or lightning-completion work with | 55 | ;; - Make things like icomplete-mode or lightning-completion work with |
| 67 | ;; completion-in-region-mode. | 56 | ;; completion-in-region-mode. |
| 68 | ;; - extend `metadata': | 57 | ;; - extend `metadata': |
| 69 | ;; - quoting/unquoting (so we can complete files names with envvars | ||
| 70 | ;; and backslashes, and all-completion can list names without | ||
| 71 | ;; quoting backslashes and dollars). | ||
| 72 | ;; - indicate how to turn all-completion's output into | 58 | ;; - indicate how to turn all-completion's output into |
| 73 | ;; try-completion's output: e.g. completion-ignored-extensions. | 59 | ;; try-completion's output: e.g. completion-ignored-extensions. |
| 74 | ;; maybe that could be merged with the "quote" operation above. | 60 | ;; maybe that could be merged with the "quote" operation. |
| 75 | ;; - indicate that `all-completions' doesn't do prefix-completion | 61 | ;; - indicate that `all-completions' doesn't do prefix-completion |
| 76 | ;; but just returns some list that relates in some other way to | 62 | ;; but just returns some list that relates in some other way to |
| 77 | ;; the provided string (as is the case in filecache.el), in which | 63 | ;; the provided string (as is the case in filecache.el), in which |
| @@ -224,6 +210,42 @@ case sensitive instead." | |||
| 224 | (let ((completion-ignore-case (not dont-fold))) | 210 | (let ((completion-ignore-case (not dont-fold))) |
| 225 | (complete-with-action action table string pred)))) | 211 | (complete-with-action action table string pred)))) |
| 226 | 212 | ||
| 213 | (defun completion-table-subvert (table s1 s2) | ||
| 214 | "Completion table that replaces the prefix S1 with S2 in STRING. | ||
| 215 | The result is a completion table which completes strings of the | ||
| 216 | form (concat S1 S) in the same way as TABLE completes strings of | ||
| 217 | the form (concat S2 S)." | ||
| 218 | (lambda (string pred action) | ||
| 219 | (let* ((str (if (eq t (compare-strings string 0 (length s1) s1 nil nil | ||
| 220 | completion-ignore-case)) | ||
| 221 | (concat s2 (substring string (length s1))))) | ||
| 222 | (res (if str (complete-with-action action table str pred)))) | ||
| 223 | (when res | ||
| 224 | (cond | ||
| 225 | ((eq (car-safe action) 'boundaries) | ||
| 226 | (let ((beg (or (and (eq (car-safe res) 'boundaries) (cadr res)) 0))) | ||
| 227 | (list* 'boundaries | ||
| 228 | (max (length s1) | ||
| 229 | (+ beg (- (length s1) (length s2)))) | ||
| 230 | (and (eq (car-safe res) 'boundaries) (cddr res))))) | ||
| 231 | ((stringp res) | ||
| 232 | (if (eq t (compare-strings res 0 (length s2) s2 nil nil | ||
| 233 | completion-ignore-case)) | ||
| 234 | (concat s1 (substring res (length s2))))) | ||
| 235 | ((eq action t) | ||
| 236 | (let ((bounds (completion-boundaries str table pred ""))) | ||
| 237 | (if (>= (car bounds) (length s2)) | ||
| 238 | res | ||
| 239 | (let ((re (concat "\\`" | ||
| 240 | (regexp-quote (substring s2 (car bounds)))))) | ||
| 241 | (delq nil | ||
| 242 | (mapcar (lambda (c) | ||
| 243 | (if (string-match re c) | ||
| 244 | (substring c (match-end 0)))) | ||
| 245 | res)))))) | ||
| 246 | ;; E.g. action=nil and it's the only completion. | ||
| 247 | (res)))))) | ||
| 248 | |||
| 227 | (defun completion-table-with-context (prefix table string pred action) | 249 | (defun completion-table-with-context (prefix table string pred action) |
| 228 | ;; TODO: add `suffix' maybe? | 250 | ;; TODO: add `suffix' maybe? |
| 229 | (let ((pred | 251 | (let ((pred |
| @@ -347,6 +369,186 @@ Note: TABLE needs to be a proper completion table which obeys predicates." | |||
| 347 | (complete-with-action action table string pred)) | 369 | (complete-with-action action table string pred)) |
| 348 | tables))) | 370 | tables))) |
| 349 | 371 | ||
| 372 | (defun completion-table-with-quoting (table unquote requote) | ||
| 373 | ;; A difficult part of completion-with-quoting is to map positions in the | ||
| 374 | ;; quoted string to equivalent positions in the unquoted string and | ||
| 375 | ;; vice-versa. There is no efficient and reliable algorithm that works for | ||
| 376 | ;; arbitrary quote and unquote functions. | ||
| 377 | ;; So to map from quoted positions to unquoted positions, we simply assume | ||
| 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 | ||
| 380 | ;; back to quoted positions. | ||
| 381 | "Return a new completion table operating on quoted text. | ||
| 382 | TABLE operates on the unquoted text. | ||
| 383 | UNQUOTE is a function that takes a string and returns a new unquoted string. | ||
| 384 | REQUOTE is a function of 2 args (UPOS QSTR) where | ||
| 385 | QSTR is a string entered by the user (and hence indicating | ||
| 386 | the user's preferred form of quoting); and | ||
| 387 | UPOS is a position within the unquoted form of QSTR. | ||
| 388 | REQUOTE should return a pair (QPOS . QFUN) such that QPOS is the | ||
| 389 | position corresponding to UPOS but in QSTR, and QFUN is a function | ||
| 390 | of one argument (a string) which returns that argument appropriately quoted | ||
| 391 | for use at QPOS." | ||
| 392 | ;; FIXME: One problem with the current setup is that `qfun' doesn't know if | ||
| 393 | ;; its argument is "the end of the completion", so if the quoting used double | ||
| 394 | ;; quotes (for example), we end up completing "fo" to "foobar and throwing | ||
| 395 | ;; away the closing double quote. | ||
| 396 | (lambda (string pred action) | ||
| 397 | (cond | ||
| 398 | ((eq action 'metadata) | ||
| 399 | (append (completion-metadata string table pred) | ||
| 400 | '((completion--unquote-requote . t)))) | ||
| 401 | |||
| 402 | ((eq action 'lambda) ;;test-completion | ||
| 403 | (let ((ustring (funcall unquote string))) | ||
| 404 | (test-completion ustring table pred))) | ||
| 405 | |||
| 406 | ((eq (car-safe action) 'boundaries) | ||
| 407 | (let* ((ustring (funcall unquote string)) | ||
| 408 | (qsuffix (cdr action)) | ||
| 409 | (ufull (if (zerop (length qsuffix)) ustring | ||
| 410 | (funcall unquote (concat string qsuffix)))) | ||
| 411 | (_ (assert (string-prefix-p ustring ufull))) | ||
| 412 | (usuffix (substring ufull (length ustring))) | ||
| 413 | (boundaries (completion-boundaries ustring table pred usuffix)) | ||
| 414 | (qlboundary (car (funcall requote (car boundaries) string))) | ||
| 415 | (qrboundary (if (zerop (cdr boundaries)) 0 ;Common case. | ||
| 416 | (let* ((urfullboundary | ||
| 417 | (+ (cdr boundaries) (length ustring)))) | ||
| 418 | (- (car (funcall requote urfullboundary | ||
| 419 | (concat string qsuffix))) | ||
| 420 | (length string)))))) | ||
| 421 | (list* 'boundaries qlboundary qrboundary))) | ||
| 422 | |||
| 423 | ((eq action nil) ;;try-completion | ||
| 424 | (let* ((ustring (funcall unquote string)) | ||
| 425 | (completion (try-completion ustring table pred))) | ||
| 426 | ;; Most forms of quoting allow several ways to quote the same string. | ||
| 427 | ;; So here we could simply requote `completion' in a kind of | ||
| 428 | ;; "canonical" quoted form without paying attention to the way | ||
| 429 | ;; `string' was quoted. But since we have to solve the more complex | ||
| 430 | ;; problems of "pay attention to the original quoting" for | ||
| 431 | ;; all-completions, we may as well use it here, since it provides | ||
| 432 | ;; a nicer behavior. | ||
| 433 | (if (not (stringp completion)) completion | ||
| 434 | (car (completion--twq-try | ||
| 435 | string ustring completion 0 unquote requote))))) | ||
| 436 | |||
| 437 | ((eq action t) ;;all-completions | ||
| 438 | ;; When all-completions is used for completion-try/all-completions | ||
| 439 | ;; (e.g. for `pcm' style), we can't do the job properly here because | ||
| 440 | ;; the caller will match our output against some pattern derived from | ||
| 441 | ;; the user's (quoted) input, and we don't have access to that | ||
| 442 | ;; pattern, so we can't know how to requote our output so that it | ||
| 443 | ;; matches the quoting used in the pattern. It is to fix this | ||
| 444 | ;; fundamental problem that we have to introduce the new | ||
| 445 | ;; unquote-requote method so that completion-try/all-completions can | ||
| 446 | ;; pass the unquoted string to the style functions. | ||
| 447 | (pcase-let* | ||
| 448 | ((ustring (funcall unquote string)) | ||
| 449 | (completions (all-completions ustring table pred)) | ||
| 450 | (boundary (car (completion-boundaries ustring table pred "")))) | ||
| 451 | (completion--twq-all | ||
| 452 | string ustring completions boundary unquote requote))) | ||
| 453 | |||
| 454 | ((eq action 'completion--unquote) | ||
| 455 | (let ((ustring (funcall unquote string)) | ||
| 456 | (uprefix (funcall unquote (substring string 0 pred)))) | ||
| 457 | ;; We presume (more or less) that `concat' and `unquote' commute. | ||
| 458 | (assert (string-prefix-p uprefix ustring)) | ||
| 459 | (list ustring table (length uprefix) | ||
| 460 | (lambda (unquoted-result op) | ||
| 461 | (pcase op | ||
| 462 | (`1 ;;try | ||
| 463 | (if (not (stringp (car-safe unquoted-result))) | ||
| 464 | unquoted-result | ||
| 465 | (completion--twq-try | ||
| 466 | string ustring | ||
| 467 | (car unquoted-result) (cdr unquoted-result) | ||
| 468 | unquote requote))) | ||
| 469 | (`2 ;;all | ||
| 470 | (let* ((last (last unquoted-result)) | ||
| 471 | (base (or (cdr last) 0))) | ||
| 472 | (when last | ||
| 473 | (setcdr last nil) | ||
| 474 | (completion--twq-all string ustring | ||
| 475 | unquoted-result base | ||
| 476 | unquote requote)))))))))))) | ||
| 477 | |||
| 478 | (defun completion--twq-try (string ustring completion point | ||
| 479 | unquote requote) | ||
| 480 | ;; Basically two case: either the new result is | ||
| 481 | ;; - commonprefix1 <point> morecommonprefix <qpos> suffix | ||
| 482 | ;; - commonprefix <qpos> newprefix <point> suffix | ||
| 483 | (pcase-let* | ||
| 484 | ((prefix (fill-common-string-prefix ustring completion)) | ||
| 485 | (suffix (substring completion (max point (length prefix)))) | ||
| 486 | (`(,qpos . ,qfun) (funcall requote (length prefix) string)) | ||
| 487 | (qstr1 (if (> point (length prefix)) | ||
| 488 | (funcall qfun (substring completion (length prefix) point)))) | ||
| 489 | (qsuffix (funcall qfun suffix)) | ||
| 490 | (qstring (concat (substring string 0 qpos) qstr1 qsuffix)) | ||
| 491 | (qpoint | ||
| 492 | (cond | ||
| 493 | ((zerop point) 0) | ||
| 494 | ((> point (length prefix)) (+ qpos (length qstr1))) | ||
| 495 | (t (car (funcall requote point string)))))) | ||
| 496 | ;; Make sure `requote' worked. | ||
| 497 | (assert (equal (funcall unquote qstring) completion)) | ||
| 498 | (cons qstring qpoint))) | ||
| 499 | |||
| 500 | (defun completion--twq-all (string ustring completions boundary | ||
| 501 | unquote requote) | ||
| 502 | (when completions | ||
| 503 | (pcase-let* | ||
| 504 | ((prefix | ||
| 505 | (let ((completion-regexp-list nil)) | ||
| 506 | (try-completion "" (cons (substring ustring boundary) | ||
| 507 | completions)))) | ||
| 508 | (`(,qfullpos . ,qfun) | ||
| 509 | (funcall requote (+ boundary (length prefix)) string)) | ||
| 510 | (qfullprefix (substring string 0 qfullpos)) | ||
| 511 | (_ (assert (let ((uboundarystr (substring ustring 0 boundary))) | ||
| 512 | (equal (funcall unquote qfullprefix) | ||
| 513 | (concat uboundarystr prefix))))) | ||
| 514 | (qboundary (car (funcall requote boundary string))) | ||
| 515 | (_ (assert (<= qboundary qfullpos))) | ||
| 516 | ;; FIXME: this split/quote/concat business messes up the carefully | ||
| 517 | ;; placed completions-common-part and completions-first-difference | ||
| 518 | ;; faces. We could try within the mapcar loop to search for the | ||
| 519 | ;; boundaries of those faces, pass them to `requote' to find their | ||
| 520 | ;; equivalent positions in the quoted output and re-add the faces: | ||
| 521 | ;; this might actually lead to correct results but would be | ||
| 522 | ;; pretty expensive. | ||
| 523 | ;; The better solution is to not quote the *Completions* display, | ||
| 524 | ;; which nicely circumvents the problem. The solution I used here | ||
| 525 | ;; instead is to hope that `qfun' preserves the text-properties and | ||
| 526 | ;; presume that the `first-difference' is not within the `prefix'; | ||
| 527 | ;; this presumption is not always true, but at least in practice it is | ||
| 528 | ;; true in most cases. | ||
| 529 | (qprefix (propertize (substring qfullprefix qboundary) | ||
| 530 | 'face 'completions-common-part))) | ||
| 531 | |||
| 532 | ;; Here we choose to quote all elements returned, but a better option | ||
| 533 | ;; would be to return unquoted elements together with a function to | ||
| 534 | ;; requote them, so that *Completions* can show nicer unquoted values | ||
| 535 | ;; which only get quoted when needed by choose-completion. | ||
| 536 | (nconc | ||
| 537 | (mapcar (lambda (completion) | ||
| 538 | (assert (string-prefix-p prefix completion)) | ||
| 539 | (let* ((new (substring completion (length prefix))) | ||
| 540 | (qnew (funcall qfun new)) | ||
| 541 | (qcompletion (concat qprefix qnew))) | ||
| 542 | (assert | ||
| 543 | (equal (funcall unquote | ||
| 544 | (concat (substring string 0 qboundary) | ||
| 545 | qcompletion)) | ||
| 546 | (concat (substring ustring 0 boundary) | ||
| 547 | completion))) | ||
| 548 | qcompletion)) | ||
| 549 | completions) | ||
| 550 | qboundary)))) | ||
| 551 | |||
| 350 | ;; (defmacro complete-in-turn (a b) `(completion-table-in-turn ,a ,b)) | 552 | ;; (defmacro complete-in-turn (a b) `(completion-table-in-turn ,a ,b)) |
| 351 | ;; (defmacro dynamic-completion-table (fun) `(completion-table-dynamic ,fun)) | 553 | ;; (defmacro dynamic-completion-table (fun) `(completion-table-dynamic ,fun)) |
| 352 | (define-obsolete-function-alias | 554 | (define-obsolete-function-alias |
| @@ -535,21 +737,47 @@ completing buffer and file names, respectively." | |||
| 535 | (delete-dups (append (cdr over) (copy-sequence completion-styles))) | 737 | (delete-dups (append (cdr over) (copy-sequence completion-styles))) |
| 536 | completion-styles))) | 738 | completion-styles))) |
| 537 | 739 | ||
| 740 | (defun completion--nth-completion (n string table pred point metadata) | ||
| 741 | "Call the Nth method of completion styles." | ||
| 742 | (unless metadata | ||
| 743 | (setq metadata | ||
| 744 | (completion-metadata (substring string 0 point) table pred))) | ||
| 745 | ;; We provide special support for quoting/unquoting here because it cannot | ||
| 746 | ;; reliably be done within the normal completion-table routines: Completion | ||
| 747 | ;; styles such as `substring' or `partial-completion' need to match the | ||
| 748 | ;; output of all-completions with the user's input, and since most/all | ||
| 749 | ;; quoting mechanisms allow several equivalent quoted forms, the | ||
| 750 | ;; completion-style can't do this matching (e.g. `substring' doesn't know | ||
| 751 | ;; that "\a\b\e" is a valid (quoted) substring of "label"). | ||
| 752 | ;; The quote/unquote function needs to come from the completion table (rather | ||
| 753 | ;; than from completion-extra-properties) because it may apply only to some | ||
| 754 | ;; part of the string (e.g. substitute-in-file-name). | ||
| 755 | (let ((requote | ||
| 756 | (when (completion-metadata-get metadata 'completion--unquote-requote) | ||
| 757 | (let ((new (funcall table string point 'completion--unquote))) | ||
| 758 | (setq string (pop new)) | ||
| 759 | (setq table (pop new)) | ||
| 760 | (setq point (pop new)) | ||
| 761 | (pop new)))) | ||
| 762 | (result | ||
| 763 | (completion--some (lambda (style) | ||
| 764 | (funcall (nth n (assq style | ||
| 765 | completion-styles-alist)) | ||
| 766 | string table pred point)) | ||
| 767 | (completion--styles metadata)))) | ||
| 768 | (if requote | ||
| 769 | (funcall requote result n) | ||
| 770 | result))) | ||
| 771 | |||
| 538 | (defun completion-try-completion (string table pred point &optional metadata) | 772 | (defun completion-try-completion (string table pred point &optional metadata) |
| 539 | "Try to complete STRING using completion table TABLE. | 773 | "Try to complete STRING using completion table TABLE. |
| 540 | Only the elements of table that satisfy predicate PRED are considered. | 774 | Only the elements of table that satisfy predicate PRED are considered. |
| 541 | POINT is the position of point within STRING. | 775 | POINT is the position of point within STRING. |
| 542 | The return value can be either nil to indicate that there is no completion, | 776 | The return value can be either nil to indicate that there is no completion, |
| 543 | t to indicate that STRING is the only possible completion, | 777 | t to indicate that STRING is the only possible completion, |
| 544 | or a pair (STRING . NEWPOINT) of the completed result string together with | 778 | or a pair (NEWSTRING . NEWPOINT) of the completed result string together with |
| 545 | a new position for point." | 779 | a new position for point." |
| 546 | (completion--some (lambda (style) | 780 | (completion--nth-completion 1 string table pred point metadata)) |
| 547 | (funcall (nth 1 (assq style completion-styles-alist)) | ||
| 548 | string table pred point)) | ||
| 549 | (completion--styles (or metadata | ||
| 550 | (completion-metadata | ||
| 551 | (substring string 0 point) | ||
| 552 | table pred))))) | ||
| 553 | 781 | ||
| 554 | (defun completion-all-completions (string table pred point &optional metadata) | 782 | (defun completion-all-completions (string table pred point &optional metadata) |
| 555 | "List the possible completions of STRING in completion table TABLE. | 783 | "List the possible completions of STRING in completion table TABLE. |
| @@ -559,13 +787,7 @@ The return value is a list of completions and may contain the base-size | |||
| 559 | in the last `cdr'." | 787 | in the last `cdr'." |
| 560 | ;; FIXME: We need to additionally return the info needed for the | 788 | ;; FIXME: We need to additionally return the info needed for the |
| 561 | ;; second part of completion-base-position. | 789 | ;; second part of completion-base-position. |
| 562 | (completion--some (lambda (style) | 790 | (completion--nth-completion 2 string table pred point metadata)) |
| 563 | (funcall (nth 2 (assq style completion-styles-alist)) | ||
| 564 | string table pred point)) | ||
| 565 | (completion--styles (or metadata | ||
| 566 | (completion-metadata | ||
| 567 | (substring string 0 point) | ||
| 568 | table pred))))) | ||
| 569 | 791 | ||
| 570 | (defun minibuffer--bitset (modified completions exact) | 792 | (defun minibuffer--bitset (modified completions exact) |
| 571 | (logior (if modified 4 0) | 793 | (logior (if modified 4 0) |