diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el index b5060614841..2dd5e09f8bb 100644 --- a/lisp/minibuffer.el +++ b/lisp/minibuffer.el @@ -4586,38 +4586,35 @@ the same set of elements." (cond ((null (cdr strs)) (list (car strs))) (t - (let ((re (completion-pcm--pattern->regex pattern 'group)) + (let ((re (concat + (completion-pcm--pattern->regex pattern 'group) + ;; The implicit trailing `any' is greedy. + "\\([^z-a]*\\)")) (ccs ())) ;Chopped completions. - ;; First chop each string into the parts corresponding to each - ;; non-constant element of `pattern', using regexp-matching. + ;; First match each string against PATTERN as a regex and extract + ;; the text matched by each wildcard. (let ((case-fold-search completion-ignore-case)) (dolist (str strs) (unless (string-match re str) (error "Internal error: %s doesn't match %s" str re)) (let ((chopped ()) - (last 0) (i 1) next) - (while (setq next (match-end i)) - (push (substring str last next) chopped) - (setq last next) + (while (setq next (match-string i str)) + (push next chopped) (setq i (1+ i))) - ;; Add the text corresponding to the implicit trailing `any'. - (push (substring str last) chopped) (push (nreverse chopped) ccs)))) - ;; Then for each of those non-constant elements, extract the - ;; commonality between them. + ;; Then for each of those wildcards, extract the commonality between them. (let ((res ()) - (fixed "") ;; Accumulate each stretch of wildcards, and process them as a unit. (wildcards ())) ;; Make the implicit trailing `any' explicit. (dolist (elem (append pattern '(any))) (if (stringp elem) (progn - (setq fixed (concat fixed elem)) + (push elem res) (setq wildcards nil)) (let ((comps ())) (push elem wildcards) @@ -4628,18 +4625,13 @@ the same set of elements." ;; different capitalizations in different parts. ;; In practice, it doesn't seem to make any difference. (setq ccs (nreverse ccs)) - ;; FIXED is a prefix of all of COMPS. Try to grow that prefix. - (let* ((prefix (try-completion fixed comps)) - (unique (or (and (eq prefix t) (setq prefix fixed)) + (let* ((prefix (try-completion "" comps)) + (unique (or (and (eq prefix t) (setq prefix "")) (and (stringp prefix) ;; If PREFIX is equal to all of COMPS, ;; then PREFIX is a unique completion. (seq-every-p - ;; PREFIX is still a prefix of all of - ;; COMPS, so if COMP is the same length, - ;; they're equal. - (lambda (comp) - (= (length prefix) (length comp))) + (lambda (comp) (= (length prefix) (length comp))) comps))))) ;; If there's only one completion, `elem' is not useful ;; any more: it can only match the empty string. @@ -4654,7 +4646,7 @@ the same set of elements." ;; `prefix' only wants to include the fixed part before the ;; wildcard, not the result of growing that fixed part. (when (seq-some (lambda (elem) (eq elem 'prefix)) wildcards) - (setq prefix fixed)) + (setq prefix "")) (push prefix res) ;; Push all the wildcards in this stretch, to preserve `point' and ;; `star' wildcards before ELEM. @@ -4678,8 +4670,7 @@ the same set of elements." (unless (equal suffix "") (push suffix res)))) ;; We pushed these wildcards on RES, so we're done with them. - (setq wildcards nil)) - (setq fixed ""))))) + (setq wildcards nil)))))) ;; We return it in reverse order. res)))))