Subject: bug#77718: 31.0.50; completion styles substring and flex are broken

From: Spencer Baugh <[email-masked]>
Date: Wed, 16 Apr 2025 13:10:42 -0400

Stefan Monnier <[email-masked]> writes:
>>> Why?  `substitute-in-file-name` presumably already takes care of that:
>>>
>>>     (substitute-in-file-name "/foo/$NOTAVAR/bar")
>>>     => "/foo/$NOTAVAR/bar"
>>
>> To support completing file names that look like environment variables,
>> without the need to quote $ by duplicating it.
>
> I don't understand: the example I show above suggests you can do that
> without doing anything special.

That only works for completing file names that contain $ and which
*aren't* currently environment variables.

My code supports completing on ~/$HOME/foo where "$HOME" is the literal
name of a directory.

> [ Also, I'm not sure it's worth the trouble anyway: dollars in file names
>   are fairly rare, so having to double them in those rare cases where they
>   occur is not a big deal.  In any case, it seems orthogonal to the
>   problem at hand.  ]

That's fair - so you think it might be OK to, basically, not support
completion on file names containing substrings like "$HOME"?  That could
make things simpler, if we think that's acceptable.

>>>> Tests are updated: we no longer duplicate $s in file names,
>>>> since that's not necessary.
>>> AFAIK it is still needed for the (null action) case.
>> Why would that be?  I believe quoting $ should no longer be necessary.
>
> Say I have a file
>
>     ~/tmp/foo$HOME.txt
>
> and I do
>
>     C-x C-f ~/tmp/foo TAB
>
> AFAIK it needs to complete to
>
>     ~/tmp/foo$$HOME.txt
>
> otherwise the file name returned by `read-file-name` will be
>
>     ~/tmp/foo/home/monnier.txt

Ah, I see.  I didn't realize that read-file-name calls
substitute-in-file-name on the result; so a file name containing
literally "$HOME" would be erroneously expanded by my code, right now.
I'll add some tests for this case in the next version of my patch.

This TAB behavior doesn't help if I manually type $HOME though, right?
The $ is only automatically duplicated if you tab-complete.  So, if the
user manually types foo$HOME.txt then $HOME would be incorrectly
expanded.

So here's one idea: Since this only works if I tab-complete, that means
it only works for files which actually exist.  So, instead, I could have
read-file-name check if the file (e.g. "~/tmp/foo$HOME.txt") exists
before expanding environment variables; if the file exists, don't expand
environment variables.  This avoids the need to duplicate $s.

Do you think that might suffice?