Subject: Re: bug#41531: 27.0.91; Better handle asynchronous eldoc backends

From: João Távora <[email-masked]>
Date: Wed, 03 Jun 2020 21:36:42 +0100

Stefan Monnier <[email-masked]> writes:

>>>> +  "<WORLD CLASS DOCSTRING>"
>> Ahem.
>>>> +  "<WORLD CLASS DOCSTRING>"
>> Ahem hem  :-)
>
> Not sure what you mean ;-)
>
>>>   "Special hook run to get the documentation string at point.
>>> Each function is called with no argument and should return either nil
>>> or an `eldoc-future` object that should have its `value` set as soon
>>> as possible via `eldoc-future-set-value` (it can be set before
>>> returning the future or at a later time).
>>> This value should be a string, typically occupying only a single line.
>> Sometimes clients want to return more than one value, i.e. set more than
>> one value.
>
> You mean a single call could return first a function signature and
> a while later a docstring?

No, that's not what I mean.  Those should be two different members of
eldoc-documentation-functions (plural).  I meant producing metadata
about the string just returned.  Much like string properties, I suppose,
but not specifically attached to regions of the string.

> The infrastructure so far only accepts strings as far as I know, so
> until that is changed the question seems moot.

Very soon that might change, but yes.

>> The callback strategy makes it easy because there are lambda lists of
>> all shapes and sizes.
> It's trivial to use a list to bring the number back down to 1, so it's
> not much of a difference.

Yes, I agree, but it's IMO easier to read (funcall cb :foo 42 :baz 23)
than (set-value fut (list :foo 42 :baz 23)).

>> How does the future approach handle this?
>> Do clients return structured lists of things?
>
> If we want to extend it that way, that would be the natural thing to do,
> I guess.  Tho without knowing what the different elements represent
> (i.e. some kind of semantic information about that list), I'm not sure
> what the callback can do with it other than presume that all elements
> are strings and concatenate them.

See my most recent patches, there are many ways to handle differently
formated and differently timed reports.

>>> In case the function ends up finding no information it is allowed
>>> not to `eldoc-future-set-value` at all."
>> This is problematic.  In the eldoc-documentation-compose situation we
>> need to wait for every backend to reply before composing.
>
> We definitely don't want to wait: if a backend responds quickly we
> should show that info immediately, and update the info if/when another
> backend gives additional info.

That depends.  Depends on the strategy.  I don't take
eldoc-documentation-compose to mean that, for example.  But we could
easily have eldoc-documentation-compose-wait and
eldoc-documentation-compose-eager.

> OTOH indeed for the non-composing situation, we'd need to know that the
> 1st backend finished unsuccessfully before being able to use the
> second backend.  So I guess you're right: we shouldn't allow backends to
> drop requests :-(

I also don't take eldoc-documentation-default to mean that.  I take it
to mean: focus on the first guy that promised he would produce
something.

But we could indeed have a "focus on the first guy that actually
produced something".

>>> each `eldoc-documentation-function` which chooses its own callback
>>> rather than being chosen by their caller.
>> For this to work, i.e. to be able to handle multiple responses, I think
>> it has to be set by their caller, i.e. eldoc-print-current-symbol-info:
>> that's the central "hub" that maintains information about how many
>> backends have responded and how many haven't.
>
> I don't think this structure can work well: the "hub" needs to work
> differently for compose than for "return first".

Yes, of course it works differently.  How "well" is another question,
whose details I don't fuilly understand.  In the last patches I showed
it works decently well, i.e. I don't see anything wrong with it.  I
implemented eldoc-documentation-default, eldoc-documentation-compose,
and something eldoc-documentation-eager which is like "default" but will
show the first one, and potentially replace with a slower, but more
important one.  These were all done "in the hub", without lots of code.
I'm fairly confident other strategies can be implemented "in the hub"
easily.

In fact, a much better name for eldoc-documentation-function (singular)
is eldoc-documentation-strategy, not least because it relieves us from
this silly singular/plural confusion.

João