diff options
author | Stefan Monnier <monnier@iro.umontreal.ca> | 2014-05-04 21:46:47 -0400 |
---|---|---|
committer | Stefan Monnier <monnier@iro.umontreal.ca> | 2014-05-04 21:46:47 -0400 |
commit | dccb0688651388531f00de3c8b365cdabcf54aa2 (patch) | |
tree | 35be3aa76e628b3cf939b7aa17b6218ac3bbab86 | |
parent | 61febcb6e32860575316b8a539a2e9f13f70e3c2 (diff) | |
download | emacs-dccb0688651388531f00de3c8b365cdabcf54aa2.tar.gz |
* lisp/minibuffer.el (completion-table-with-quoting) <completion--unquote>:
Make sure the new point we return is within the new string.
Fixes: debbugs:17239
-rw-r--r-- | lisp/ChangeLog | 5 | ||||
-rw-r--r-- | lisp/minibuffer.el | 35 |
2 files changed, 35 insertions, 5 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index e1a0ee66dd7..bef5f1ba71f 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,8 @@ +2014-05-05 Stefan Monnier <monnier@iro.umontreal.ca> + + * minibuffer.el (completion-table-with-quoting) <completion--unquote>: + Make sure the new point we return is within the new string (bug#17239). + 2014-05-03 Eli Zaretskii <eliz@gnu.org> * mail/rmailsum.el (rmail-new-summary-1): Fix a typo in a comment. diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index 9dd4ef9fe04..87ba8a22e64 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -519,11 +519,35 @@ for use at QPOS." completions)) ((eq action 'completion--unquote) - (let ((ustring (funcall unquote string)) - (uprefix (funcall unquote (substring string 0 pred)))) - ;; We presume (more or less) that `concat' and `unquote' commute. - (cl-assert (string-prefix-p uprefix ustring)) - (list ustring table (length uprefix) + ;; PRED is really a POINT in STRING. + ;; We should return a new set (STRING TABLE POINT REQUOTE) + ;; where STRING is a new (unquoted) STRING to match against the new TABLE + ;; using a new POINT inside it, and REQUOTE is a requoting function which + ;; should reverse the unquoting, (i.e. it receives the completion result + ;; of using the new TABLE and should turn it into the corresponding + ;; quoted result). + (let* ((qpos pred) + (ustring (funcall unquote string)) + (uprefix (funcall unquote (substring string 0 qpos))) + ;; FIXME: we really should pass `qpos' to `unuote' and have that + ;; function give us the corresponding `uqpos'. But for now we + ;; presume (more or less) that `concat' and `unquote' commute. + (uqpos (if (string-prefix-p uprefix ustring) + ;; Yay!! They do seem to commute! + (length uprefix) + ;; They don't commute this time! :-( + ;; Maybe qpos is in some text that disappears in the + ;; ustring (bug#17239). Let's try a second chance guess. + (let ((usuffix (funcall unquote (substring string qpos)))) + (if (string-suffix-p usuffix ustring) + ;; Yay!! They still "commute" in a sense! + (- (length ustring) (length usuffix)) + ;; Still no luck! Let's just choose *some* position + ;; within ustring. + (/ (+ (min (length uprefix) (length ustring)) + (max (- (length ustring) (length usuffix)) 0)) + 2)))))) + (list ustring table uqpos (lambda (unquoted-result op) (pcase op (1 ;;try @@ -853,6 +877,7 @@ completing buffer and file names, respectively." (setq string (pop new)) (setq table (pop new)) (setq point (pop new)) + (cl-assert (<= point (length string))) (pop new)))) (result (completion--some (lambda (style) |