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: martin rudalics
Subject: bug#43609: 28.0.50; eldoc-documentation-function
Date: Wed, 30 Sep 2020 19:33:16 +0200

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

Citing again the Emacs 27 doc-string for 'eldoc-documentation-function'

  Function to call to return doc string.
  The function of no args should return a one-line string for displaying
  doc about a function etc.  appropriate to the context around point.
  It should return nil if there’s no doc appropriate for the context.
  Typically doc is returned if point is on a function-like name or in its
  arg list.

  The result is used as is, so the function must explicitly handle
  the variables ‘eldoc-argument-case’ and ‘eldoc-echo-area-use-multiline-p’,
  and the face ‘eldoc-highlight-function-argument’, if they are to have any
  effect.

so if it did not work for the modes you cite, the doc-string should have
warned about that fact earlier.  While this is certainly not your fault,
changing the semantics of that variable for elisp-mode with the argument
that it did not work for other modes was not a user-friendly step.

Personally I use eldoc for two major modes only: 'emacs-lisp-mode' and
'c-mode' (in a crippled way via 'c-eldoc' but here nobody ever bothered
to write an 'eldoc-documentation-function' function for one of the two
major languages used to implement Emacs).  And as far as the former is
concerned, I now cannot use even 'elisp-eldoc-documentation-function'
directly either because you changed its return value too.

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

At the time "el" in eldoc stood for elisp it was.  But many things
changed since then, admittedly.

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

I think we should do that and provide it as compatibility layer for
people like me who need it.

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

Definitely.

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

If we can provide an option for that, yes.

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

I'd prefer a list of strings.

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

I explained that above.  I attach a copy of eldoc-tooltip.el here (I
have two other packages to display tooltips either in a separate window
or in the header line but I have not used them for years).  As mentioned
above, I use eldoc for elisp and c only.  For the former I currently use

    (cond
     ((fboundp 'eldoc-tooltip-mode)
      (when (fboundp 'global-eldoc-mode)
        (global-eldoc-mode -1))
      (eldoc-tooltip-mode 1))

because eldoc-tooltip-mode was written some time before
'global-eldoc-mode' was added.

> 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")))
>

Works without problems for elisp-mode.  Many thanks.

Now for c-mode I use

      (set (make-local-variable 'eldoc-documentation-function)
           'c-eldoc-print-current-symbol-info)

What can I do here? The same?

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

OK.  I will look into that later.

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

My other interlocutor here was Dmitry Gutov.  Please refer to him with
his name.  And I highly appreciate the fact that he was the only person
to answer my bug report within a day or two.

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

I'll do that.

Many thanks, martin

Attachment: eldoc-tooltip.el
Description: Text Data


reply via email to

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