Subject: bug#55205: 28.1.50; completion--replace illegally mutates completion candidates

From: Stefan Monnier <[email-masked]>
Date: Tue, 03 May 2022 08:55:37 -0400

Lars Ingebrigtsen [2022-05-03 12:13:36] wrote:
> Stefan Monnier <[email-masked]> writes:
>> The strings used for completions are the "identity" of each completion.
>> so if there are two distinct completions, they should have
>> distinct strings.  I don't see what's artificial about it.
>
> The "are" there is doing a lot of work here.  :-)

Yes, but that's the underlying design of the system.

> In my use case, the stringly representation is not the identity of
> the selection.

And that's the core of your problem.

>> Somehow the user (and the code) needs to be able to distinguish between
>> the various identically named movies.  You do that with a poster image
>> and I'm suggesting that this poster image should be covering some
>> "unique" identification information.  I.e. something like:
>>
>>     (concat movie-name (propertize movie-id 'display movie-poster))
>
> And that is the artificiality of it.  If you're on a web page listing
> different items, and they have the same name, you don't see the web
> designers putting made-up irrelevant characters into the link text --
> they keep the identifying stuff hidden in the links.

I think this goes to the core of the difference between the web's design
and Emacs's design, where we like to make everything reflected
explicitly as text rather than hidden somewhere internal.

It makes some things a bit more ugly sometimes, but it does tend to
repay in the long run.

>> The rest of the discussion made me realize that maybe I misunderstood
>> your question.  Are you talking about the stripping that takes places
>> *during completion* (e.g. when clicking in *Completions*) or are you
>> talking about the stripping that takes place just before returning the
>> value of `completing-read`?  Some other?
>
> I don't remember any more -- I only know that the text properties are
> stripped at some point.

Well, I think we should preserve the properties a much as possible on
the way from the completion data to the actual completion place
(typically the minibuffer) so as to preserve fonts, colors, images, etc
when applicable.

But w.r.t propagating text properties from the minibuffer's content to
the returned value of `completing-read` I'm not sure that's a good idea,
for the reason Daniel explained: it would encourage people to abuse them
in the way you want to abuse the design, which would then make it
unusable for some completion UIs.

> But I still have no idea why we're stripping text properties in the
> first place, so could you please explain that?

It depends where.  In `completion--replace` it's explained in the
comment:

    ;; The properties on `newtext' include things like the
    ;; `completions-first-difference' face, which we don't want to
    ;; include upon insertion.

-- Stefan