Subject: bug#73234: 30.0.91; completion-preview-mode doesn't trigger for case-insensitive capf

From: Morgan Willcock <[email-masked]>
Date: Sat, 14 Sep 2024 21:46:08 +0100

Eshel Yaron <[email-masked]> writes:

>>> We could display the completion preview also when you type a prefix that
>>> differs from a candidate prefix only in case (and in fact we already do,
>>> when completion-ignore-case is non-nil), but the question is what to do
>>> when you accept/insert this completion.  Namely, changing the prefix
>>> from "tes" to "Tes" when you accept the completion suggestion adds
>>> complications both in terms of implementation and in terms of UX, and
>>> I'm not sure that this added complexity would be justified.
>>
>> My expectation was that a "completion preview" is using exactly the same
>> criteria as the default completion mechanism,
>
> This expectation is (at least presently) not warranted.  Completion
> Preview mode draws from the same pool of completions as
> completion-at-point (it uses the same completion-at-point-functions),
> but as a different frontend it makes different use of these completions.
> Namely, Completion Preview mode is for prefix completion.  This is the
> purpose of this feature.  We can discuss generalizing Completion Preview
> mode to incorporate other kinds (or styles) of completion, that does
> require some non-trivial considerations, though.
>
> In the benefit of other users, could you please share what led you to
> have this expectation?  Perhaps we can improve the documentation to
> avoid such confusions.

It was just the name.  I assumed it to be a preview of the same
completions which are in normal use, rather than a separate mechanism.

>> and would indicate when a completion was available to use.
>
> That it does, for prefix completions.

There are gaps in my knowledge here, but is there something about a
prefix completion which means that it has to force a case-sensitive
match, or is there something else about the preview interface which
imposes the restriction?

If the completion at point function is case-insensitive at which point
in the process is that case-insensitivity being lost?

>> The difference in the behaviour also means completion-preview-mode
>> cannot reliably be used as the entry-point (by repeatedly calling
>> completion-preview-complete) for the completion interface.
>
> That's not the goal of this command, so that's OK, I think :)

Yes, I appreciate that the aim is just to show the preview, but it does
actually function as an entry point if the input produces multiple
matches.

(It works less well with the default completion interface because it is
fairly easy to leave the completion buffer open, but the default
behaviour of Corfu aligns with it quite well because the Corfu frame
automatically closes.)

> Completion Preview mode is not intended to replace completion-at-point,
> you can use C-M-i with the preview enabled, and get the same results
> that would without it.

I think my main point is that I wouldn't necessarily know to press C-M-i
because of the lack of preview.

>>> Do you have, or know of, a concrete use case with a completion table
>>> that behaves like your test-completion-at-point-function?
>>
>> I think it would be rare to see one explicitly set to be
>> case-insensitive, but I found the issue because I use a Cape capf
>> transformer to wrap an existing capf backend:
>>
>> https://elpa.gnu.org/packages/doc/cape.html#Capf-transformers
>>
>> It is feasible to do that for any language where the syntax is
>> case-insensitive.
>
> If case is not important, and you're fine with completing "tes" in your
> example to "testSymbol", then setting completion-ignore-case to non-nil
> should get you there, IIUC.

I found out the hard way that completion-ignore-case isn't something
that can be set as buffer-local:

https://lists.gnu.org/archive/html/emacs-devel/2024-03/msg00302.html

I wouldn't want to set case-insensitivity globally.

> Another option, if case is insignificant, is to use a completion table
> that adopts the case of the input and returns completion candidates
> adjusted accordingly, instead of ignoring the case of the input and
> returning candidates that match up to case differences.  We do something
> like that in ispell-completion-at-point, for example, and it works well
> with Completion Preview mode.

Do you mean this would need changes to the completion at point function
rather than to completion-preview-mode?

>> Here is an example of it being done:
>>
>> https://git.sr.ht/~mew/kixtart-mode/tree/v1.3.2/item/doc/kixtart-mode.texi#L804
>>
>> (I wrote this mode and its manual, but anyone using cape-capf-case-fold
>> is likely to see the same problem.)
>
> Thanks, but this points to example code in the documentation of a
> package I'm not familiar with, so it's hard to discern its significance.
> (The manual looks really nice BTW!)

I don't think there are any restrictions on where cape-capf-case-fold
can be used, but fundamentally the only goal is to insert the completion
in the same form that it was returned from the completion at point
function, but not require the user to match the case.

Or to put it another way, because completion-ignore-case cannot be
buffer-local, cape-capf-case-fold is the only feasible way I've seen to
make a case-insensitive language easier to complete.

> If my suggestions above don't help with your use case, would you like to
> try and propose a patch that does?

I would be willing to give it a go, but I think I am missing some fairly
critical knowledge about why the same completion at point function is in
use but the match result is different.

Thank you for the quick and detailed reply,
Morgan

-- 
Morgan Willcock