Subject: bug#74617: 30.0.92; ffap-menu always displays the *Completions* buffer

From: Daniel Mendler <[email-masked]>
Date: Sat, 30 Nov 2024 17:25:07 +0100

Eli Zaretskii <[email-masked]> writes:

>> From: Daniel Mendler <[email-masked]>
>> Cc: [email-masked],  [email-masked]
>> Date: Sat, 30 Nov 2024 10:40:05 +0100
>> 
>> Eli Zaretskii <[email-masked]> writes:
>> > Alternatively, we could consider the cases where more than one
>> > completion list is shown a bug in the mode which shows the completions
>> > even though the application already did.  IOW, instead of considering
>> > this a problem of the command the user invokes, consider this a bug in
>> > the non-default completion UI currently in effect.  It is basically a
>> > flaw in the design of those completion UIs.
>> 
>> I see it differently. The problem is in the tmm and ffap commands which
>> lead to a mixture of completion UIs. Even if another completion UI is in
>> effect, the default completion UI is called by tmm and ffap, bypassing
>> the `completing-read' abstraction.
>
> I don't understand: ffap-menu calls completing-read, so what
> abstraction does it bypass, and how?

It also calls `minibuffer-completion-help' which belongs to the default
completion UI but not strictly to the abstract `completing-read' API.
Unfortunately the API boundaries are not clearly defined. In principle
one could separate the generic `completing-read' code from the default
completion UI code. This could help keeping the complexity of the
completion code in check. Right now the default completion UI code is
scattered across minibuffer.el and simple.el. 

>> It is not the responsibility of
>> alternative completion UIs to work around this.
>
> Work around what?

Hiding the *Completions* buffer. It should not be shown in the first
place if the user replaced the `completing-read-function' with something
else by turning on the mode of an alternative UI.

>> >> Another alternative to auto detection could be that the completion table
>> >> communicates to `completing-read' via metadata that immediate candidate
>> >> display is desired. The completion UI could then act accordingly.
>> >> Default completion would call `minibuffer-completion-help' and Icomplete
>> >> could update immediately, ignoring `icomplete-compute-delay'.
>> >
>> > This sounds too indirect to me, it could cause unintended adverse
>> > consequences, especially in nested scenarios.
>> 
>> By using the completion metadata as part of the completion table, the
>> effect on nested scenarios is explicitly avoided. Problems with nesting
>> only occur if a variable is let-bound around `completing-read'.
>
> You assume that the completion table is never passed to inner levels?
> Is that assumption solid?

Yes, as far as I can tell. Completion can work well in recursive
minibuffers, such that the inner completion session does not interfere
with the outer session. Stefan even changed the scope of the
`minibuffer-completion-table' variables a while ago, such that it is
only bound buffer-locally in the minibuffer. Earlier it was let-bound
around the `read-from-minibuffer' call. (Of course it is still possible
to access the completion table by reading the buffer local variable from
the minibuffer directly, but this doesn't happen accidentally.)