Subject: bug#42149: Substring and flex completion ignore implicit trailing ‘any’

From: Dario Gjorgjevski <[email-masked]>
Date: Tue, 08 Sep 2020 13:12:51 +0200

> Is this is vanilla emacs, or are you using some icomplete-mode or
> fido-mode?
> I.e. can you post the entire Emacs -Q recipe?

It is really simple to reproduce.

0. Run ‘emacs -Q’ in a directory with two files: “1” and “foo1”.
1. Enable fido-mode.
2. C-x C-f 1 RET.

Emacs will open “foo1” even though I would expect it to open “1” as that
is an exact match.  But, I really think this is a pointless discussion.

The issue *is not caused by fido-mode* but by the mechanism of substring
(and therefore, flex) completion.  You can also trigger it without
fido-mode by invoking minibuffer-force-complete-and-exit.

    (completion-flex-all-completions "1" '("1" "11" "1122") nil 1)
    (completion-substring-all-completions "1" '("1" "11" "1122") nil 1)

Both return completely the nonsensical result of

    (#("1"
       0 1 (face completions-common-part completion-score 0.0))
     #("11"
       0 1 (face completions-common-part completion-score 0.0)
       1 2 (face completions-first-difference))
     #("1122"
       0 1 (face completions-common-part completion-score 0.0)
       1 2 (face completions-first-difference))
     . 0)

(Why are all the completion-score values 0?)  Applying the attached
patch changes the result to

    (#("1"
       0 1 (face completions-common-part completion-score 1.0))
     #("11"
       0 1 (face completions-common-part completion-score 0.5)
       1 2 (face completions-first-difference))
     #("1122"
       0 1 (face completions-common-part completion-score 0.25)
       1 2 (face completions-first-difference))
     . 0)

which I hope you would agree makes a lot more sense.

> M-j instead of RET in these one-letter completion cases. Or even C-u
> M-j, if that doesn't work.

Sure, but my muscle memory opposes that.

Best regards,
Dario

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 6deb1eb077..cfcf0fdccb 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -3581,6 +3581,7 @@ that is non-nil."
                    (if transform-pattern-fn
                        (funcall transform-pattern-fn pattern)
                      pattern)))
+	 (pattern (append pattern '(any))) ; explicit trailing ‘any’
          (all (completion-pcm--all-completions prefix pattern table pred)))
     (list all pattern prefix suffix (car bounds))))

-- 
[email-masked] :: +49 1525 8666837
%   gpg --keyserver 'hkps://hkps.pool.sks-keyservers.net' \
\`>     --recv-keys '744A4F0B4F1C9371'