]> git.eshelyaron.com Git - emacs.git/commitdiff
ElDoc: rework rendering of echo area (bug#62029)
authorJoão Távora <joaotavora@gmail.com>
Thu, 23 Mar 2023 09:02:18 +0000 (09:02 +0000)
committerJoão Távora <joaotavora@gmail.com>
Thu, 23 Mar 2023 21:14:18 +0000 (21:14 +0000)
Previously, the display function 'eldoc-display-in-echo-area' reused
the same buffer as 'eldoc-display-in-doc-buffer', but that made it
harder to render documentation items differently depending on the
specific constraints of each display functions.

Allow documentation-generating backends to pass an :echo-area property
for tweaking the echo area display of certain documentation items.

* lisp/emacs-lisp/eldoc.el (eldoc-documentation-functions): Update docstring.
(eldoc--doc-buffer-docs): Remove.
(eldoc--format-doc-buffer): Simplify.
(eldoc--echo-area-render): New helper.
(eldoc-display-in-echo-area): Use 'eldoc--echo-area-render'.

lisp/emacs-lisp/eldoc.el

index 8fc109dcfefbad798c6935813eedafeddb1a02db..2108e189fbdd2796bd2f40073adb43dd30b3872a 100644 (file)
@@ -437,7 +437,7 @@ documentation-producing backend to cooperate with specific
 documentation-displaying frontends.  For example, KEY can be:
 
 * `:thing', VALUE being a short string or symbol designating what
-  is being reported on.  It can, for example be the name of the
+  DOCSTRING reports on.  It can, for example be the name of the
   function whose signature is being documented, or the name of
   the variable whose docstring is being documented.
   `eldoc-display-in-echo-area', a member of
@@ -453,6 +453,11 @@ documentation-displaying frontends.  For example, KEY can be:
   originated. `eldoc-display-in-buffer' may use this organize the
   documentation buffer accordingly.
 
+* `:echo', controlling how `eldoc-display-in-echo-area' should
+  present this documentation item, to save space.  If VALUE is
+  `skip' don't echo DOCSTRING.  If a number, only echo DOCSTRING
+  up to that character position.
+
 Finally, major modes should modify this hook locally, for
 example:
   (add-hook \\='eldoc-documentation-functions #\\='foo-mode-eldoc nil t)
@@ -476,8 +481,6 @@ directly from the user or from ElDoc's automatic mechanisms'.")
 
 (defvar eldoc--doc-buffer nil "Buffer displaying latest ElDoc-produced docs.")
 
-(defvar eldoc--doc-buffer-docs nil "Documentation items in `eldoc--doc-buffer'.")
-
 (defun eldoc-doc-buffer (&optional interactive)
   "Get or display ElDoc documentation buffer.
 
@@ -501,40 +504,56 @@ If INTERACTIVE, display it.  Else, return said buffer."
                            eldoc--doc-buffer
                          (setq eldoc--doc-buffer
                                (get-buffer-create " *eldoc*")))
-    (unless (eq docs eldoc--doc-buffer-docs)
-      (setq-local eldoc--doc-buffer-docs docs)
-      (let ((inhibit-read-only t)
-            (things-reported-on))
-        (special-mode)
-        (erase-buffer)
-        (setq-local nobreak-char-display nil)
-        (cl-loop for (docs . rest) on docs
-                 for (this-doc . plist) = docs
-                 for thing = (plist-get plist :thing)
-                 when thing do
-                 (cl-pushnew thing things-reported-on)
-                 (setq this-doc
-                       (concat
-                        (propertize (format "%s" thing)
-                                    'face (plist-get plist :face))
-                        ": "
-                        this-doc))
-                 do (insert this-doc)
-                 when rest do (insert "\n")
-                 finally (goto-char (point-min)))
-        ;; Rename the buffer, taking into account whether it was
-        ;; hidden or not
-        (rename-buffer (format "%s*eldoc%s*"
-                               (if (string-match "^ " (buffer-name)) " " "")
-                               (if things-reported-on
-                                   (format " for %s"
-                                           (mapconcat
-                                            (lambda (s) (format "%s" s))
-                                            things-reported-on
-                                            ", "))
-                                 ""))))))
+    (let ((inhibit-read-only t)
+          (things-reported-on))
+      (special-mode)
+      (erase-buffer)
+      (setq-local nobreak-char-display nil)
+      (cl-loop for (docs . rest) on docs
+               for (this-doc . plist) = docs
+               for thing = (plist-get plist :thing)
+               when thing do
+               (cl-pushnew thing things-reported-on)
+               (setq this-doc
+                     (concat
+                      (propertize (format "%s" thing)
+                                  'face (plist-get plist :face))
+                      ": "
+                      this-doc))
+               do (insert this-doc)
+               when rest do (insert "\n")
+               finally (goto-char (point-min)))
+      ;; Rename the buffer, taking into account whether it was
+      ;; hidden or not
+      (rename-buffer (format "%s*eldoc%s*"
+                             (if (string-match "^ " (buffer-name)) " " "")
+                             (if things-reported-on
+                                 (format " for %s"
+                                         (mapconcat
+                                          (lambda (s) (format "%s" s))
+                                          things-reported-on
+                                          ", "))
+                               "")))))
   eldoc--doc-buffer)
 
+(defun eldoc--echo-area-render (docs)
+  "Similar to `eldoc--format-doc-buffer', but for echo area.
+Helper for `eldoc-display-in-echo-area'."
+  (cl-loop for (item . rest) on docs
+           for (this-doc . plist) = item
+           for echo = (plist-get plist :echo)
+           for thing = (plist-get plist :thing)
+           unless (eq echo 'skip) do
+           (when echo (setq this-doc (substring this-doc 0 echo)))
+           (when thing (setq this-doc
+                             (concat
+                              (propertize (format "%s" thing)
+                                          'face (plist-get plist :face))
+                              ": "
+                              this-doc)))
+           (insert this-doc)
+           (when rest (insert "\n"))))
+
 (defun eldoc--echo-area-substring (available)
   "Given AVAILABLE lines, get buffer substring to display in echo area.
 Helper for `eldoc-display-in-echo-area'."
@@ -620,15 +639,15 @@ Honor `eldoc-echo-area-use-multiline-p' and
                single-doc)
               ((and (numberp available)
                     (cl-plusp available))
-               ;; Else, given a positive number of logical lines, we
-               ;; format the *eldoc* buffer, using as most of its
-               ;; contents as we know will fit.
-               (with-current-buffer (eldoc--format-doc-buffer docs)
-                 (save-excursion
-                   (eldoc--echo-area-substring available))))
+               ;; Else, given a positive number of logical lines, grab
+               ;; as many as we can.
+               (with-temp-buffer
+                 (eldoc--echo-area-render docs)
+                 (eldoc--echo-area-substring available)))
               (t ;; this is the "truncate brutally" situation
                (let ((string
-                      (with-current-buffer (eldoc--format-doc-buffer docs)
+                      (with-temp-buffer
+                        (eldoc--echo-area-render docs)
                         (buffer-substring (goto-char (point-min))
                                           (progn (end-of-visible-line)
                                                  (point))))))