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

From: João Távora <[email-masked]>
Date: Mon, 28 Dec 2020 12:57:10 +0000

Dario Gjorgjevski <[email-masked]> writes:

>> For now, I believe the original problem that started this bug report,
>> which dealt with flex and substring completion, is fixed by my patch.
>> Your failed user experience of typing "R" to perform "M-x R" should now
>> be correct, as far as I can tell.
>
> Sorry, but the branch bug-42149-funny-pcm-completion-scores doesn’t fix
> any of that problem.
>
>   (completion-flex-all-completions "R" '("R" "something-else-with-an-R")
>                                    nil 1)
>
> Will make both "R" and "something-else-with-an-R" get a completion-score
> of 0, which is definitely not helping anything.

You're right.  I was a little too eager, and reported results on a
version that had another fix built it (a fix that is also simple and
reasonable, but which I haven't shown since it conses a little bit).

Anyway, the patch after my sig should fix it.  I'll push it later with
better comments, but it correctly identifies the presence or absence of
a trailing 'any in terms of the match-data, and corrects accordingly, in
terms of scoring.

It also fixes another one (I don't know which) of your tests.  Now only
two tests fail:

F completion-pcm-test-5
F completion-substring-test-4

I think we should focus on the meaning of these tests from here on.

Thanks,
João

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 4c912b5a34..eec0b3e09e 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -3263,9 +3263,9 @@ completion-pcm--hilit-commonality
            (error "Internal error: %s does not match %s" re str))
          (let* ((pos (if point-idx (match-beginning point-idx) (match-end 0)))
                 (md (cddr (match-data)))
+                (match-end (cadr (match-data)))
                 (start 0)
-                (len (length str))
-                (end len)
+                (end (length str))
                 ;; To understand how this works, consider these bad
                 ;; ascii(tm) diagrams showing how the pattern "foo"
                 ;; flex-matches "fabrobazo", "fbarbazoo" and
@@ -3326,6 +3326,8 @@ completion-pcm--hilit-commonality
               'completions-common-part
               nil str)
              (setq start (pop md)))
+           (unless (= start match-end) ; ... which is t if we have trailing 'any
+             (funcall update-score start match-end))
            (add-face-text-property
             start end
             'completions-common-part
@@ -3338,7 +3340,7 @@ completion-pcm--hilit-commonality
            (unless (zerop (length str))
              (put-text-property
               0 1 'completion-score
-              (/ score-numerator (* len (1+ score-denominator)) 1.0) str)))
+              (/ score-numerator (* end (1+ score-denominator)) 1.0) str)))
          str)
        completions))))