Subject: Re: bug#77312: [PATCH] Add uniquify-get-unique-names

From: Spencer Baugh <[email-masked]>
Date: Tue, 10 Jun 2025 13:03:53 -0400

Daniel Mendler <[email-masked]> writes:
> Spencer Baugh via "Bug reports for GNU Emacs, the Swiss army knife of
> text editors" <[email-masked]> writes:
>
>> Daniel Mendler <[email-masked]> writes:
>>
>>> Dmitry Gutov <[email-masked]> writes:
>>>
>>>> Hey Daniel!
>>>>
>>>> On 07/06/2025 11:11, Daniel Mendler wrote:
>>>>> Would it be possible to attach the buffer object or the original buffer
>>>>> name to the completion candidate string as text property? This would
>>>>> make it possible to attach annotations via Marginalia or to execute
>>>>> buffer actions via Embark. Otherwise I don't see a possibility to access
>>>>> the original buffer, since they are only present in the `unique-names`
>>>>> alist local variable.
>>>>
>>>> That makes sense. Just call the property 'buffer'?
>>>
>>> That would work. I prefer a more specific property name to ease
>>> grepping/debugging. Also see below regarding the consing.
>>>
>>>> I wonder if it would make sense to alter the calling convention for
>>>> uniquify-get-unique-names itself to return a list of propertized strings
>>>> instead. project--read-project-buffer can do the conversion (copy each string
>>>> and attach the property), but it's just extra consing.
>>>
>>> I haven't checked if the current function is already working hard to
>>> avoid unnecessary allocations. If yes, it would be wasteful to add extra
>>> string allocations.
>>>
>>> In order to avoid them, we could only attach the property if the buffer
>>> name has really changed, such that no strings have to be copied. The
>>> property could be called `uniquify-orig-buffer-name`. If the property is
>>> present, it holds the original buffer name, if it is not present the
>>> string itself is the original buffer name.
>>
>> All else being equal, I think changing uniquify-get-unique-names to
>> return a list of strings which have the original buffer names as a
>> property is a reasonable and easy thing to do.  uniquify.el is generally
>> pretty allocation heavy, so I wouldn't worry about the excess
>> allocations, just stick the property on all the returned strings.
>
> Okay.

Er, sorry, crucial typo/miscommunication here: I think
uniquify-get-unique-names should return a list of strings, each of which
has a text property containing the original *buffer*.  Not the original
buffer name - the buffer itself.  That would just be slightly more
efficient.

>
>> Some unnecessary speculation about alternatives to the text property
>> approach follows:
>>
>> One alternative to the text property approach is to have the alist
>> returned by uniquify-get-unique-names be let-bound in some special
>> variable around the call to completing-read.  Then Embark/Marginalia
>> could look up strings in that alist to figure out the underlying buffer
>> that a string is referring to.
>
> Yes, this would work too. Or more ideally set a local variable in the
> minibuffer setup hook, since then buffer unification can be detected by
> checking if the variable is non-nil.

Ah right, because otherwise a recursive edit could cause problems... so
a local variable set in the minibuffer setup hook would indeed be
bettter.

>>>> Unless some more new callers are going to prefer the current convention.
>>>
>>> Both would be fine for me. Generally I think it is nice to push
>>> functionality to the lower level API, as long as the functionality is
>>> generic enough.
>>>
>>> Btw, would you be interested in having `uniquify-get-unique-names' in
>>> Compat, such that you avoid the fboundp check? project.el would have to
>>> depend on Compat for that, but that's essentially free on Emacs 30 and
>>> newer.
>>
>> I think adding uniquify-get-unique-names to compat might be difficult
>> because it depends on non-trivial changes to the rest of the code in
>> uniquify.el.
>
> That's unfortunate. I have not looked in detail at it, but if the effort
> is disproportionate, and half of uniquify.el would need to be
> replicated, then we cannot port it back as part of Compat.

Yep.  Maybe about 120 lines would need to be replicated.