Subject: Re: bug#77124: [PATCH] Optionally display function docstring in eldoc

From: Elijah Gabe Pérez <[email-masked]>
Date: Thu, 20 Mar 2025 12:37:23 -0600

Eli Zaretskii <[email-masked]> writes:

>> From: Elijah Gabe Pérez <[email-masked]>
>> Date: Wed, 19 Mar 2025 12:32:15 -0600

>> This user option tell whether 'eldoc' should display elisp function docstring.
>> If set to 'short' only display a short docstring, otherwise if set to
>> 'full', display full docstring.
>> If set to nil do not show function docstring.

> Where will the doc string be shown?

> If in the echo-area, then what will happen when eldoc shows the info
> on the mode line instead?

I've fixed it to only show in the echo-area and not to mode-line.

Also I've moved it to a function instead modifying existing ones,
similar to ~elisp-eldoc-var-docstring-with-value~.

>> +(defcustom elisp-eldoc-show-function-docstring nil
>> +  "Show function docstring in `eldoc-mode'.
>> +If set to `short' only display a short docstring, otherwise if set to
>> +`full', display full docstring.

> This should explain what is the "short docstring".  Also, where the
> documentation is shown.

I've added it.

To explain:
Instead display this full docstring:

  Set each SYM to the value of its VAL.

  The symbols SYM are variables; they are literal (not evaluated).
  The values VAL are expressions; they are evaluated.
  Thus, (setq x (1+ y)) sets x to the value of (1+ y).
  The second VAL is not computed until after the first SYM is set, and so on;
  each VAL can use the new value of variables set earlier in the setq.
  The return value of the setq form is the value of the last VAL.

Only display it like this:

  Set each SYM to the value of its VAL.

> P.S. For the next version of the patch, please remember mentioning the
> bug number in the commit log message.

Sure.

>From 77591a6cc151718060af84f1e5684f1fcb932b5b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?El=C3=ADas=20Gabriel=20P=C3=A9rez?= <[email-masked]>
Date: Wed, 19 Mar 2025 12:01:22 -0600
Subject: [PATCH] Optionally display function docstring in eldoc

Allow display (optionally) function docstring in eldoc. (Bug#77124)
* etc/NEWS: Document changes.
* lisp/progmodes/elisp-mode.el
(elisp-eldoc-funcall-with-docstring-lenght): New user option.
(elisp-eldoc-funcall-with-docstring): New function.
---
 etc/NEWS                     | 11 ++++++++++
 lisp/progmodes/elisp-mode.el | 42 ++++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+)

diff --git a/etc/NEWS b/etc/NEWS
index 0797fc03217..44c2b36adc9 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -1900,6 +1900,17 @@ another pattern matching syntax that is different from that of 'pcase',
 which some users might find less cryptic.
 See the Info node "(elisp) cond* Macro" for details.
 
+---
+** New eldoc function 'elisp-eldoc-funcall-with-docstring'.
+This function includes the current function docstring in eldoc echo area
+and can be used as a more detailed alternative to 'elisp-eldoc-funcall'.
+
+** New user option 'elisp-eldoc-funcall-with-docstring-lenght'.
+This user option specifies how long function docstring must be displayed
+in 'elisp-eldoc-funcall-with-docstring'.  If set to 'short' only display
+cut docstring before period.  Otherwise if set to 'full', display full
+docstring.'
+
 ---
 ** New function 'shell-command-do-open'.
 This lets a Lisp program access the core functionality of the
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index a34f29bffea..22e300ea685 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -1845,6 +1845,48 @@ elisp-eldoc-funcall
                          'font-lock-function-name-face
                        'font-lock-keyword-face)))))
 
+(defcustom elisp-eldoc-funcall-with-docstring-lenght 'short
+  "Specify function docstring lenght in `elisp-eldoc-funcall-with-docstring'.
+If set to `short' only display docstring before period.,
+Otherwise if set to `full', display full docstring."
+  :type '(choice
+          (const :tag "Short" short)
+          (const :tag "Full" full))
+  :group 'elisp
+  :version 31)
+
+(defun elisp-eldoc-funcall-with-docstring (callback &rest _ignored)
+  "Document function call at point by calling CALLBACK.
+Intended for `eldoc-documentation-functions' (which see).
+Compared to `elisp-eldoc-funcall', this also includes the
+current function docstring, docstring lenght depends on
+`elisp-eldoc-funcall-with-docstring-lenght'."
+  (let* ((sym-info (elisp--fnsym-in-current-sexp))
+         (fn-sym (car sym-info))
+         (doc (when (fboundp fn-sym)
+                (propertize
+                 (cdr (help-split-fundoc
+                       (condition-case nil (documentation fn-sym t)
+                         (invalid-function nil))
+                       fn-sym))
+                 'face 'font-lock-doc-face))))
+    (when fn-sym
+      (funcall callback
+               (concat (apply #'elisp-get-fnsym-args-string sym-info)
+                       (when (and doc (not (minibufferp)))
+                         (concat
+                          "\n"
+                          (pcase elisp-eldoc-funcall-with-docstring-lenght
+                            ('full doc)
+                            ('short
+                             (save-match-data
+                               (when (string-match "\\." doc)
+                                 (concat "\n" (substring doc 0 (match-end 0))))))))))
+               :thing fn-sym
+               :face (if (functionp fn-sym)
+                         'font-lock-function-name-face
+                       'font-lock-keyword-face)))))
+
 (defun elisp-eldoc-var-docstring (callback &rest _ignored)
   "Document variable at point by calling CALLBACK.
 Intended for `eldoc-documentation-functions' (which see).
-- 
2.48.1

-- 
                                          - E.G via GNU Emacs and Org.