Subject: bug#41531: 28.0.50; proper Eldoc async support

From: João Távora <[email-masked]>
Date: Wed, 03 Jun 2020 19:56:46 +0100

Hello again gang,

As you might have seen in emacs-diffs, I have pushed a new
scratch/eldoc-async branch to the Savannah repo.  If you don't have this
repo setup you can find the commits here in the meantime:

   https://github.com/emacs-mirror/emacs/tree/scratch/eldoc-async

The code, which touches mostly lisp/emacs-lisp/eldoc.el contains the
logical continuation of the improvements I started building two weeks
ago.

When applied, these improvements result in a substantial reduction of
Eglot's documentation handling code.  Yes, Andrii, that means all our
hand-crafted, hard work of doc handling functions is soon gone,
including the awkward eglot-put-doc-in-help-buffer,
eglot-auto-display-help-buffer and the *eglot-help* buffer.

Feels sad but also good, because deleted code is good code.  And it's
not in vain because your feedback and testing was fundamental here.  And
the good news is that the logic problems about blinking and giving
priority to some docs is gone.

There are 6 commits in total, that build on top of each other.  In
reverse order

    10834f20ec * lisp/emacs-lisp/eldoc.el (Version): Bump to 1.1.0
    fe93e5b9d5 Make eldoc-print-current-symbol-info a command
    0612bb7ab5 Introduce eldoc-prefer-doc-buffer defcustom
    40d45067ba Overhaul and handle (most of) eldoc-echo-area-use-multiline-p in Eldoc itself
    600b9c0a71 New eldoc-documentation-eager value for eldoc-documentation-function
    cde8a6ab98 Better handle asynchronously produced eldoc docstrings

And the new version of Eglot that makes uses of this eldoc is here.

    https://github.com/joaotavora/eglot/tree/scratch/work-with-new-eldoc

It's important to note that Eldoc remains backward-compatible to all its
previous users.

In eldoc.el, things build on top of existing work, which includes the
reasonably new eldoc-documentation-functions (plural).  Earlier, I
thought of this variable somewhat useless, but it's really not.  In
fact, it's exactly what Eglot, SLY and other modes are after.  Even
emacs-lisp-mode itself could benefit as it's often the case that one
loses the documentation for a special variable just because one happen
to be inside a function call, or vice versa.
eldoc-documentation-functions allows us to split up these two competing
sources of documentation, so thank you Mark, or whomever had this great
idea.

An orthogonal question is how to display the documentation we gather
from multiple sources.  That is handled by eldoc-documentation-function
(singular), another variable I had underestimated.  In my changes, I
have added a third option to the two already existing ones.

  :type '(radio (function-item eldoc-documentation-default)
                (function-item eldoc-documentation-compose)
                (function-item eldoc-documentation-eager)
                (function :tag "Other function"))
  :version "28.1")

Eglot defaults to eldoc-documentation-eager, which simulates its
previous behavior.  I suggest you see the docstring for each.
Certainly we can have more strategies to combine documentation sources.

Another important development is that now that the display is
centralized, the formatiing can also be.  Thus a big part of
eldoc-echo-area-use-multiline-p can be easily honoured in eldoc.el
itself.

But the most complex changes pertain to async backends, such as Eglot's
and some (but not all) of SLY.  This is also covered.

On this point, it is also extremely super-important to note that even
though I have NOT used "futures" or "promises" in these patches, the
very same things can be achieved with them, give or take some code here
and there and some head-wrapping around different debugging techniques.
I have NOT focused on the particular async programming technique: I just
used the simplest and most commonly used in Emacs.

Finally, there is a bit of future-proof unused API.  Backends can call
the documentation-reporting callback with keyword arguments, such as
`:hint`.  But they're not really used yet for anything yet.  Some more
sophisticated text formatting in the *eldoc doc* buffer, including
renaming it like Eglot used to do to its *Eglot doc* buffer, is a
possibility.

Another possibility yet, also left unexplored, is for Flymake diagnostic
messages at point to be reported as independent documentation sources.
This is a frequent complain about Eglot.  But in fact I think it should
be Flymake-mode itself that adds some function to
eldoc-documentation-functions.

João