GNU bug report logs - #47711
27.1; Deferred highlighting support in `completion-all-completions', `vertico--all-completions`

Previous Next

Package: emacs;

Reported by: Daniel Mendler <mail <at> daniel-mendler.de>

Date: Sun, 11 Apr 2021 20:52:01 UTC

Severity: normal

Found in version 27.1

Done: Daniel Mendler <mail <at> daniel-mendler.de>

Bug is archived. No further changes may be made.

Full log


View this message in rfc822 format

From: Stefan Monnier <monnier <at> iro.umontreal.ca>
To: João Távora <joaotavora <at> gmail.com>
Cc: Dmitry Gutov <dmitry <at> gutov.dev>, Eli Zaretskii <eliz <at> gnu.org>, 47711 <at> debbugs.gnu.org, Daniel Mendler <mail <at> daniel-mendler.de>
Subject: bug#47711: bug#48841: bug#47711: bug#48841: bug#47711: [PATCH VERSION 2] Add new `completion-filter-completions` API and deferred highlighting
Date: Wed, 25 Oct 2023 16:50:29 -0400
This sounds fairly reasonable: the worst-case breakage seems to be that
we may occasionally lose highlighting because the var was non-nil at the
wrong time.

Sidenote: since the hash-table uses `eq` we don't need to use `gensym`,
we can use something like `cons` instead, which is cheaper and doesn't
risk making its way into the `obarray`.

> +(defun completion-lazy-hilit (str)
> +  "Return a copy of completion STR that is `face'-propertized.
> +See documentation for variable `completion-lazy-hilit' for more
> +details."
> +  (completion--hilit-from-re
> +   (copy-sequence str)
> +   (gethash completion-lazy-hilit completion--lazy-hilit-table)))

Hmm... in order to get the right result you need to call
`completion-lazy-hilit` sometime after calling
`completion-all-completions` and before the next call to
`completion-all-completions` done with the same value of
`completion-lazy-hilit`, right?

So how important is it to use a hash-table rather than a variable
holding just "the info about the last call to
`completion-all-completions`"?

> +           last-md
> +           (score (lambda (str)
> +                    (unless (string-match re str)
> +                      (error "Internal error: %s does not match %s" re str))
> +                    (let* ((match-end (match-end 0))
> +                           (md (cddr (setq last-md (match-data t last-md)))))
> +                      (completion--flex-score-1 md match-end (length str))))))
> +      (cond (completion-lazy-hilit
> +             (puthash completion-lazy-hilit re completion--lazy-hilit-table)
> +             (mapc (lambda (str)
> +                     (put-text-property 0 1 'completion-score (funcall score str) str))
> +                   completions))
> +            (t
> +             (mapcar
> +              (lambda (str)
> +                (setq str (copy-sequence str))
> +                (put-text-property 0 1 'completion-score (funcall score str) str)
> +                (completion--hilit-from-re str re)
> +                str)
> +              completions)))))

How much more expensive is it to replace the 

    (mapc (lambda (str)
            (put-text-property 0 1 'completion-score (funcall score str) str))
          completions))

with something like

    (let ((tail `(completion-lazy-hilit (completion--hilit-from-re ,re))))
      (mapc (lambda (str)
              (add-text-properties
               0 1 `(completion-score ,(funcall score str) ,@tail) str))
            completions))

and then get rid of the hash-table altogether?
                 

        Stefan





This bug report was last modified 172 days ago.

Previous Next


GNU bug tracking system
Copyright (C) 1999 Darren O. Benham, 1997,2003 nCipher Corporation Ltd, 1994-97 Ian Jackson.