Subject: Re: bug#77054: Completion highlighting applied outside completion-lazy-hilit-fn

From: Eli Zaretskii <[email-masked]>
Date: Thu, 20 Mar 2025 14:19:54 +0200

> From: João Guerra <[email-masked]>
> Date: Wed, 19 Mar 2025 16:12:02 +0100
> Cc: [email-masked]
> 
> ```
> (setopt completion-styles '(flex)
>         file-name-shadow-properties `(invisible t
> ,@file-name-shadow-properties))
> (setq completion-lazy-hilit t)
> (defun completion--hilit-from-re (string regexp &optional point-idx)
>   "Bogus fontification that only fontifies the last character of STRING."
>   (message "lazy %s" completion-lazy-hilit)
>   (let ((last (1- (length string))))
>     (add-face-text-property last (1+ last) 'completions-common-part t string))
>   string)
> (icomplete-mode t)
> ```
> 
> See the attached picture for the outcome (if that doesn't work here's
> an alternative url
> https://drive.proton.me/urls/ZMMW1D9S2R#EXEwlTnWeCHy). You'll notice
> that my fontification function has run, fontifying the last character.
> However, additional characters are fontified, meaning there's
> fontification happening elsewhere (the culprit indicated in the
> original bug report). It could be the case that the frontend decided
> to do additional fontification, but that's not the case (except for
> the first candidate).
> 
> My expectation as a user or package maintainer is that no
> fontification will be performed by Emacs if I am using lazy
> highlighting. However, that's not the case in *specific* situations as
> I am trying to show in this bug report.
> 
> > At least according to the docstrings I wrote at the time, and which I suggest reading.
> 
> Neither docstring directly discusses whether additional fontification
> can be performed by Emacs when using lazy highlighting, so my
> assumption would be no.

The doc string says (in Emacs 30.1):

  completion-lazy-hilit-fn is a variable defined in ‘minibuffer.el’.

  Its value is nil

  Fontification function set by lazy-highlighting completions styles.
  When a given style wants to enable support for ‘completion-lazy-hilit’
  (which see), that style should set this variable to a function of one
  argument.  It will be called with each completion candidate, a string, to
  be displayed to the user, and should destructively propertize these
  strings with the ‘face’ property.

The "should destructively propertize" part tells me that the function
should take care of removing the face properties present in the input
string where it doesn't want those fontifications.  By contrast, your
function calls add-text-properties, which only adds the face
properties to a single character, but does nothing with the face
properties of the rest of the string.

> If it helps, I can reframe this bug report as: if lazy highlighting is
> enabled, can Emacs perform additional fontification (outside the
> completion frontend and style)?

I believe the answer is YES; if you would like to _replace_ the
fontifications of the candidate, your function should remove the face
text properties from all the characters of the string, before adding
your fontifications.

> If the answer is yes, can we consider changing that behaviour? As I
> believe it constraints what packages can do.

Actually, I think the existing behavior leaves the packages more
freedom, because they can retain any of the existing fontifications as
they see fit.  Don't you agree?

Or what am I missing?