1
Fork 0
mirror of git://git.sv.gnu.org/emacs.git synced 2026-01-04 11:00:45 -08:00

ElDoc: rework rendering of echo area (bug#62029)

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'.
This commit is contained in:
João Távora 2023-03-23 09:02:18 +00:00
parent 9b18407c7f
commit e19994fe8c

View file

@ -437,7 +437,7 @@ documentation-producing backend to cooperate with specific
documentation-displaying frontends. For example, KEY can be: documentation-displaying frontends. For example, KEY can be:
* `:thing', VALUE being a short string or symbol designating what * `: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 function whose signature is being documented, or the name of
the variable whose docstring is being documented. the variable whose docstring is being documented.
`eldoc-display-in-echo-area', a member of `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 originated. `eldoc-display-in-buffer' may use this organize the
documentation buffer accordingly. 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 Finally, major modes should modify this hook locally, for
example: example:
(add-hook \\='eldoc-documentation-functions #\\='foo-mode-eldoc nil t) (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 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) (defun eldoc-doc-buffer (&optional interactive)
"Get or display ElDoc documentation buffer. "Get or display ElDoc documentation buffer.
@ -501,40 +504,56 @@ If INTERACTIVE, display it. Else, return said buffer."
eldoc--doc-buffer eldoc--doc-buffer
(setq eldoc--doc-buffer (setq eldoc--doc-buffer
(get-buffer-create " *eldoc*"))) (get-buffer-create " *eldoc*")))
(unless (eq docs eldoc--doc-buffer-docs) (let ((inhibit-read-only t)
(setq-local eldoc--doc-buffer-docs docs) (things-reported-on))
(let ((inhibit-read-only t) (special-mode)
(things-reported-on)) (erase-buffer)
(special-mode) (setq-local nobreak-char-display nil)
(erase-buffer) (cl-loop for (docs . rest) on docs
(setq-local nobreak-char-display nil) for (this-doc . plist) = docs
(cl-loop for (docs . rest) on docs for thing = (plist-get plist :thing)
for (this-doc . plist) = docs when thing do
for thing = (plist-get plist :thing) (cl-pushnew thing things-reported-on)
when thing do (setq this-doc
(cl-pushnew thing things-reported-on) (concat
(setq this-doc (propertize (format "%s" thing)
(concat 'face (plist-get plist :face))
(propertize (format "%s" thing) ": "
'face (plist-get plist :face)) this-doc))
": " do (insert this-doc)
this-doc)) when rest do (insert "\n")
do (insert this-doc) finally (goto-char (point-min)))
when rest do (insert "\n") ;; Rename the buffer, taking into account whether it was
finally (goto-char (point-min))) ;; hidden or not
;; Rename the buffer, taking into account whether it was (rename-buffer (format "%s*eldoc%s*"
;; hidden or not (if (string-match "^ " (buffer-name)) " " "")
(rename-buffer (format "%s*eldoc%s*" (if things-reported-on
(if (string-match "^ " (buffer-name)) " " "") (format " for %s"
(if things-reported-on (mapconcat
(format " for %s" (lambda (s) (format "%s" s))
(mapconcat things-reported-on
(lambda (s) (format "%s" s)) ", "))
things-reported-on "")))))
", "))
""))))))
eldoc--doc-buffer) 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) (defun eldoc--echo-area-substring (available)
"Given AVAILABLE lines, get buffer substring to display in echo area. "Given AVAILABLE lines, get buffer substring to display in echo area.
Helper for `eldoc-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) single-doc)
((and (numberp available) ((and (numberp available)
(cl-plusp available)) (cl-plusp available))
;; Else, given a positive number of logical lines, we ;; Else, given a positive number of logical lines, grab
;; format the *eldoc* buffer, using as most of its ;; as many as we can.
;; contents as we know will fit. (with-temp-buffer
(with-current-buffer (eldoc--format-doc-buffer docs) (eldoc--echo-area-render docs)
(save-excursion (eldoc--echo-area-substring available)))
(eldoc--echo-area-substring available))))
(t ;; this is the "truncate brutally" situation (t ;; this is the "truncate brutally" situation
(let ((string (let ((string
(with-current-buffer (eldoc--format-doc-buffer docs) (with-temp-buffer
(eldoc--echo-area-render docs)
(buffer-substring (goto-char (point-min)) (buffer-substring (goto-char (point-min))
(progn (end-of-visible-line) (progn (end-of-visible-line)
(point)))))) (point))))))