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

From: Eshel Yaron <[email-masked]>
Date: Sun, 15 Sep 2024 08:40:02 +0200

Hi,

Morgan Willcock <[email-masked]> writes:

> 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?

Prefix completion does not force case-sensitivity.  However, in
Completion Preview mode we only show (preview) the suffix.  Since we
only suggest a suffix, the completion preview cannot convey to you, the
user, suggested alternations for the prefix, such as case alternations.
This is in contrast with e.g. the *Completions* buffer where you see a
list of whole completion candidates.  So the preview is inherently all
about adding text, not changing existing text.

We can conceive of a way to indicate suggested changes to the existing
prefix, probably with an overlay.  I think that's an interesting idea to
explore, but it would make Completion Preview mode more complex (both in
terms of implementation, and more importantly, from a user's
perspective).  So we'll only do it if enables an important use case.

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

completion-preview--try-table is where we first filter appropriate
completion candidates.

[...]

>> 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.

I'll take a closer look at that discussion, but I'm pretty sure you can
in fact set completion-ignore-case buffer-locally.  It works as expected
in my quick tests, and it's done in other places in Emacs already :|

>> 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?

Yes.  Basically, use a different wrapper instead of completion-table-case-fold.

[...]

>> 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.

Great.  The "matches" (the return value of the completion functions) are
the same.  We post-process them, including filtering them, differently,
since we present them differently (we only display the suffix, etc.).
Check out completion-preview--try-table in particular, and feel free to
ask if you find anything unclear.  Admittedly, the documentation of some
of these internal functions could be a bit more detailed :)

Best,

Eshel