unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
To: "João Távora" <joaotavora@gmail.com>
Cc: 42149@debbugs.gnu.org, Stefan Monnier <monnier@iro.umontreal.ca>
Subject: bug#42149: Substring and flex completion ignore implicit trailing ‘any’
Date: Wed, 09 Sep 2020 12:17:34 +0200	[thread overview]
Message-ID: <fv2zojlfhji79d.fsf@gmail.com> (raw)
In-Reply-To: <CALDnm50Cwo+zw2T8X4RSRbO42RZEJmn9rPa_-rCpw79AP9-Fyg@mail.gmail.com> ("João Távora"'s message of "Tue, 8 Sep 2020 12:32:31 +0100")

[-- Attachment #1: Type: text/plain, Size: 242 bytes --]

Hi João, hi Stefan,

Please find attached a patch that fixes this issue and optimizes the
scoring in PCM completion a bit.  As far as I can tell, this works fine
and can be merged, but please have a look and do some testing yourself.


[-- Attachment #2: Fix (and optimize) scoring in PCM completion --]
[-- Type: text/x-diff, Size: 5686 bytes --]

From 8699e72f92524da8041f63949cf29858caded4a5 Mon Sep 17 00:00:00 2001
From: Dario Gjorgjevski <dario.gjorgjevski@gmail.com>
Date: Wed, 9 Sep 2020 12:10:52 +0200
Subject: [PATCH] Fix (and optimize) scoring in PCM completion
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

* lisp/minibuffer.el (completion-pcm--hilit-commonality): Fix scoring
to also include the last part of the query string.  This was
especially evident for single-character query strings, e.g.,
‘(completion-flex-all-completions "1" '("1" "foo1") nil 1)’ would
match both "1" and "foo1" with a completion-score of 0.  This
adjustment makes the completion-score of "1" be 1 and of "foo1" by
0.25.  See also bug#42149.  Furthermore, some optimizations are done.
---
 lisp/minibuffer.el | 78 ++++++++++++++++++++++------------------------
 1 file changed, 37 insertions(+), 41 deletions(-)

diff --git a/lisp/minibuffer.el b/lisp/minibuffer.el
index 62a33f3e2d..7fa132f3c5 100644
--- a/lisp/minibuffer.el
+++ b/lisp/minibuffer.el
@@ -3191,17 +3191,20 @@ one-letter-long matches).")
   (when completions
     (let* ((re (completion-pcm--pattern->regex pattern 'group))
            (point-idx (completion-pcm--pattern-point-idx pattern))
-           (case-fold-search completion-ignore-case))
+           (case-fold-search completion-ignore-case)
+           (score-numerator (float (apply #'+ (mapcar (lambda (part)
+                                                        (if (stringp part)
+                                                            (length part)
+                                                          0))
+                                                      pattern)))))
       (mapcar
        (lambda (str)
-	 ;; Don't modify the string itself.
+         ;; Don't modify the string itself.
          (setq str (copy-sequence str))
          (unless (string-match re str)
            (error "Internal error: %s does not match %s" re str))
          (let* ((pos (if point-idx (match-beginning point-idx) (match-end 0)))
                 (md (match-data))
-                (start (pop md))
-                (end (pop md))
                 (len (length str))
                 ;; To understand how this works, consider these bad
                 ;; ascii(tm) diagrams showing how the pattern "foo"
@@ -3237,47 +3240,40 @@ one-letter-long matches).")
                 ;;    (SUM_across_i(hole_i_contrib) + 1) * len
                 ;;
                 ;; , where "len" is the string's length.
-                (score-numerator 0)
-                (score-denominator 0)
-                (last-b 0)
-                (update-score
-                 (lambda (a b)
-                   "Update score variables given match range (A B)."
-                   (setq
-                    score-numerator   (+ score-numerator (- b a)))
-                   (unless (or (= a last-b)
-                               (zerop last-b)
-                               (= a (length str)))
-                     (setq
-                      score-denominator (+ score-denominator
-                                           1
-                                           (expt (- a last-b 1)
-                                                 (/ 1.0
-                                                    flex-score-match-tightness)))))
-                   (setq
-                    last-b              b))))
-           (funcall update-score start start)
+                (full-match-start (pop md))
+                (full-match-end (pop md))
+                (leading-hole-start (pop md))
+                (leading-hole-end (pop md))
+                (match-start leading-hole-end)
+                (score-denominator 0))
            (while md
-             (funcall update-score start (car md))
-             (add-face-text-property
-              start (pop md)
-              'completions-common-part
-              nil str)
-             (setq start (pop md)))
-           (funcall update-score len len)
+             (let ((hole-start (pop md))
+                   (hole-end (pop md)))
+               (add-face-text-property
+                match-start hole-start
+                'completions-common-part
+                nil str)
+               (unless (= hole-start hole-end)
+                 (setq
+                  score-denominator (+ score-denominator
+                                       1
+                                       (expt
+                                        (- hole-end hole-start 1)
+                                        (/ 1.0 flex-score-match-tightness)))))
+               (setq match-start hole-end)))
            (add-face-text-property
-            start end
+            match-start full-match-end
             'completions-common-part
             nil str)
-           (if (> (length str) pos)
-               (add-face-text-property
-                pos (1+ pos)
-                'completions-first-difference
-                nil str))
-           (unless (zerop (length str))
-             (put-text-property
-              0 1 'completion-score
-              (/ score-numerator (* len (1+ score-denominator)) 1.0) str)))
+           (when (> len pos)
+             (add-face-text-property
+              pos (1+ pos)
+              'completions-first-difference
+              nil str))
+           (put-text-property
+            0 1
+            'completion-score
+            (/ score-numerator (* len (1+ score-denominator))) str))
          str)
        completions))))
 
-- 
2.17.1


[-- Attachment #3: Type: text/plain, Size: 173 bytes --]


Best regards,
Dario

-- 
dario.gjorgjevski@gmail.com :: +49 1525 8666837
%   gpg --keyserver 'hkps://hkps.pool.sks-keyservers.net' \
\`>     --recv-keys '744A4F0B4F1C9371'

  reply	other threads:[~2020-09-09 10:17 UTC|newest]

Thread overview: 53+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-07-01 10:40 bug#42149: Substring and flex completion ignore implicit trailing ‘any’ Dario Gjorgjevski
2020-07-01 10:58 ` João Távora
2020-07-01 11:03 ` João Távora
2020-07-01 11:10   ` Dario Gjorgjevski
2020-09-08  9:05     ` Dario Gjorgjevski
2020-09-08  9:30       ` João Távora
2020-09-08  9:44         ` Dario Gjorgjevski
2020-09-08 10:08           ` João Távora
2020-09-08 11:12             ` Dario Gjorgjevski
2020-09-08 11:22               ` João Távora
2020-09-08 11:30                 ` Dario Gjorgjevski
2020-09-08 11:32                   ` João Távora
2020-09-09 10:17                     ` Dario Gjorgjevski [this message]
2020-09-09 11:38                       ` Dario Gjorgjevski
2020-09-09 13:13                         ` Stefan Monnier
2020-09-10 11:26                           ` Dario Gjorgjevski
2020-10-14  8:22                             ` Dario Gjorgjevski
2020-10-14  8:39                               ` João Távora
2020-10-14  9:01                                 ` Dario Gjorgjevski
2020-10-15 14:25                                   ` Dario Gjorgjevski
2020-11-20 20:39                                     ` Dario Gjorgjevski
2020-11-20 21:27                                       ` João Távora
2020-11-25  0:01                                         ` João Távora
2020-11-25  8:22                                           ` Dario Gjorgjevski
2020-11-25 12:22                                             ` João Távora
2020-11-25 13:27                                               ` Dario Gjorgjevski
2020-12-23  9:41                                                 ` Dario Gjorgjevski
2020-12-27 20:08                                                   ` João Távora
2020-12-27 20:23                                                     ` João Távora
2020-12-27 21:20                                                     ` Stefan Monnier
2020-12-28  9:30                                                       ` João Távora
2020-12-28 16:03                                                         ` Stefan Monnier
2020-12-28 16:58                                                           ` João Távora
2020-12-28 16:07                                                         ` Stefan Monnier
2020-12-28 17:04                                                           ` João Távora
2020-12-27 21:45                                     ` Stefan Monnier
2020-12-28  9:38                                       ` João Távora
2020-12-28 10:22                                         ` Dario Gjorgjevski
2020-12-28 11:34                                           ` João Távora
2020-12-28 11:48                                             ` Dario Gjorgjevski
2020-12-28 12:57                                               ` João Távora
2020-12-28 10:17                                       ` Dario Gjorgjevski
2020-12-28 16:26                                         ` Stefan Monnier
2020-12-28 17:16                                           ` João Távora
2020-12-28 19:48                                             ` Dario Gjorgjevski
2020-12-28 20:00                                               ` Stefan Monnier
2020-12-28 23:20                                                 ` João Távora
2020-12-29 13:27                                                   ` João Távora
2021-05-13  9:24                                                   ` Lars Ingebrigtsen
2021-05-13 14:31                                                     ` João Távora
2021-05-13 15:41                                                       ` Dario Gjorgjevski
2021-05-13 16:04                                                         ` João Távora
2021-05-16 13:51                                                           ` Lars Ingebrigtsen

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=fv2zojlfhji79d.fsf@gmail.com \
    --to=dario.gjorgjevski@gmail.com \
    --cc=42149@debbugs.gnu.org \
    --cc=joaotavora@gmail.com \
    --cc=monnier@iro.umontreal.ca \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).