bug-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

bug#43609: 28.0.50; eldoc-documentation-function


From: João Távora
Subject: bug#43609: 28.0.50; eldoc-documentation-function
Date: Wed, 30 Sep 2020 15:37:01 +0100
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

martin rudalics <rudalics@gmx.at> writes:

> When with emacs -Q I put the following snippet into *scratch*
>
> (defun foo ()
>   (ignore))
>
> move point to somewhere on "foo" and do
>

Hi Martin, thanks for the bug report, which I only became aware of
today.  I apologize for the delay in answering.

> M-: (funcall eldoc-documentation-function)

You're not supposed to call the that function in your programs and
neither were you in Emacs 27, much in the same way you normally don't
call, say, adaptive-fill-function, add-log-file-name-function or many
others.  That you _could_ do it in your special circumstances was
incidental, though apparently useful for your third-party extension,
which I wasn't aware of.

Furthermore, calling eldoc-documentation-function directly in Emacs 27
simply doesn't work with a lot of major-modes/extensions that use
`eldoc-mode': ElPy, SLIME, SLY, Eldoc, and probably many others. If you
call the function directly in those modes, it will quite likely return
something other than the desired string, which will potentially appear
in the echo area only some time after.

That is becasue these modes (which all work in Emacs 26, 27 and master)
set eldoc-documentation-function to fetch their docstrings from
asynchronous sources.  Therefore, calling the function won't return the
immediate value you expect, since ElDoc in Emacs 27 doesn't have any
concept of "async".  It is true that in Elisp mode (and maybe some other
modes) you get away with it becasue it doesn't have asynchronous sources
(by default, at least, and mostly becasue it doesn't need to).  This is
why your technique worked, under very special conditions.

This is to clarify that the "direct call" protocol of Emacs 27's
eldoc.el was _never_ "a thing".  At any rate it was never something you
could rely on generally.

Anyway, eldoc-documentation-function is consulted by the Eldoc framework
to provide documentation of the thing at point.  The default value of
that variable has changed and it follows the "new" protocol.  The
documentation is telling you how to craft values that you assign to the
varible, not how your application should interpret them.

If you need a direct call, "give me the string" entry point to the
eldoc.el library, one can be added.  However, its semantics depends on
your use case:

- Do you want to have a return value handy for the docstrings that are
  immediately available from the sources that respond synchronously?

- Do you want to wait actively until all sources have reported back and
  then get a return value?  In this case, do you need a timeout?

- Independent of your choice above, or do you want to get the return
  value as list of strings?  Or as a single string, maybe concatenated
  and propertized, exactly the way it is display

But maybe we are putting the cart ahead of ourselves?  Would you mind
explaining exactly what you are trying to do?  I suppose it's:

> I am using a package that displays the string produced by that
> function in a tooltip near point.

Is this supposed to work only for Elisp mode or in general for every
mode that uses Eldoc, such as the ones I listed above?

If the former, you can probably do this (or some variation):

(defun martin ()
  "CAUTION: Only works in default Emacs Lisp mode or modes with all-sync
docstring generating functions.  If some functions calls the
callback afterwards, that result is discarded."
  (let (res)
    (run-hook-with-args 'eldoc-documentation-functions
                        (cl-function
                         (lambda (doc &key thing face &allow-other-keys)
                           (push (format "%s: %s"
                                         (propertize
                                          (format "%s" thing)
                                          'face face)
                                         doc)
                                 res))))
    (mapconcat #'identity res "\n")))

If the latter, I suggest you look at the code I have in the
scratch/eldoc-display-functions branch, which seems to match your
intentions/use case very closely.  The docstring of the new
eldoc-display-functions variable could be of use (let me know if it's
insuficcient).  This means your advanced tooltip-displaying technology
could now work with every Eldoc mode that uses the "new" protocol
(including, of course, Elisp mode).

As a side note, I would take the opinions of your other interlocutor
here so far with a grain of salt or two.  They're not always grounded in
reality.

Finally, I understand the documentation for the new ElDoc framework is
not very good yet: I will update it soon.  Again, I apologize for the
delay in answering this bug report, but I am extremely busy as of late.
Next time, if you can remember, please X-Debbugs-CC: me in your fresh
bug report on this matter, so that the message reaches me immediately.

Sincerely,
João





reply via email to

[Prev in Thread] Current Thread [Next in Thread]