summaryrefslogtreecommitdiff
path: root/lisp/emacs-lisp/eldoc.el
diff options
context:
space:
mode:
authorJoão Távora <joaotavora@gmail.com>2020-07-05 12:55:27 +0100
committerJoão Távora <joaotavora@gmail.com>2020-07-08 11:25:33 +0100
commitbba3bea247675df234353f0c2cd8af7da23bc6b8 (patch)
treee03738dc3e3e0f753eadb6c5013e8e143a6dc638 /lisp/emacs-lisp/eldoc.el
parent1203626f472b0d99d2746f5999711137c0c1fd0c (diff)
downloademacs-bba3bea247675df234353f0c2cd8af7da23bc6b8.tar.gz
emacs-bba3bea247675df234353f0c2cd8af7da23bc6b8.tar.bz2
emacs-bba3bea247675df234353f0c2cd8af7da23bc6b8.zip
Adjust Eldoc documentation after Eli's review
* etc/NEWS (Eldoc): Adjust paragraphs. * lisp/emacs-lisp/eldoc.el (eldoc-prefer-doc-buffer): Adjust docstring. (eldoc--enthusiasm-curbing-timer, eldoc-documentation-strategy) (eldoc-documentation-functions): Adjust docstring. (eldoc--handle-docs): Adjust comments. (eldoc--documentation-compose-1): New helper. (eldoc-documentation-compose) (eldoc-documentation-compose-eagerly): Use it. (eldoc-print-current-symbol-info): Adjust comments.
Diffstat (limited to 'lisp/emacs-lisp/eldoc.el')
-rw-r--r--lisp/emacs-lisp/eldoc.el201
1 files changed, 106 insertions, 95 deletions
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index ab8dd6a73b5..1f7a29f9621 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -114,8 +114,9 @@ single line of display in the echo area."
(defcustom eldoc-prefer-doc-buffer nil
"Prefer Eldoc's documentation buffer if it is showing in some frame.
If this variable's value is t and a piece of documentation needs
-to be truncated to fit in the echo area, do so only if Eldoc's
-documentation buffer is not already showing."
+to be truncated to fit in the echo area, do so if Eldoc's
+documentation buffer is not already showing, since the buffer
+always holds the full documentation."
:type 'boolean)
(defface eldoc-highlight-function-argument
@@ -365,9 +366,9 @@ A doc string is typically relevant if point is on a function-like
name, inside its arg list, or on any object with some associated
information.
-Each hook function is called with at least one argument CALLBACK
-and decides whether to display a doc short string about the
-context around point.
+Each hook function is called with at least one argument CALLBACK,
+a function, and decides whether to display a doc short string
+about the context around point.
- If that decision can be taken quickly, the hook function may
call CALLBACK immediately following the protocol described
@@ -381,10 +382,10 @@ context around point.
value and arrange for CALLBACK to be called at a later time,
using asynchronous processes or other asynchronous mechanisms.
-Regardless of the context in which CALLBACK is called, it expects
-to be passed an argument DOCSTRING followed by an optional list
-of keyword-value pairs of the form (:KEY VALUE :KEY2 VALUE2...).
-KEY can be:
+To call the CALLBACK function, the hook function must pass it an
+obligatory argument DOCSTRING, a string containing the
+documentation, followed by an optional list of keyword-value
+pairs of the form (:KEY VALUE :KEY2 VALUE2...). KEY can be:
* `:thing', VALUE is be a short string or symbol designating what
is being reported on;
@@ -410,25 +411,24 @@ return any documentation.")
(defun eldoc--handle-docs (docs)
"Display multiple DOCS in echo area.
DOCS is a list of (STRING PLIST...). It is already sorted.
-Honour most of `eldoc-echo-area-use-multiline-p'."
- (if (null docs) (eldoc--message nil) ; if there's nothing to report
- ; clear the echo area, but
- ; don't erase the last *eldoc*
- ; buffer.
- ;; If there's something to report on, first establish some
- ;; parameterso
- (let* ((width (1- (window-width (minibuffer-window))))
- (val (if (and (symbolp eldoc-echo-area-use-multiline-p)
- eldoc-echo-area-use-multiline-p)
- max-mini-window-height
- eldoc-echo-area-use-multiline-p))
- (available (cl-typecase val
- (float (truncate (* (frame-height) val)))
- (integer val)
- (t 1)))
- (things-reported-on)
- single-sym-name)
- ;; Then, compose the contents of the `*eldoc*' buffer
+Honor most of `eldoc-echo-area-use-multiline-p'."
+ ;; If there's nothing to report clear the echo area, but don't erase
+ ;; the last *eldoc* buffer.
+ (if (null docs) (eldoc--message nil)
+ (let*
+ ;; Otherwise, establish some parameters.
+ ((width (1- (window-width (minibuffer-window))))
+ (val (if (and (symbolp eldoc-echo-area-use-multiline-p)
+ eldoc-echo-area-use-multiline-p)
+ max-mini-window-height
+ eldoc-echo-area-use-multiline-p))
+ (available (cl-typecase val
+ (float (truncate (* (frame-height) val)))
+ (integer val)
+ (t 1)))
+ (things-reported-on)
+ single-sym-name)
+ ;; Then, compose the contents of the `*eldoc*' buffer.
(with-current-buffer (eldoc-doc-buffer)
(let ((inhibit-read-only t))
(erase-buffer) (setq buffer-read-only t)
@@ -446,55 +446,55 @@ Honour most of `eldoc-echo-area-use-multiline-p'."
this-doc))
do (insert this-doc)
when rest do (insert "\n")))
- ;; rename the buffer
+ ;; Rename the buffer.
(when things-reported-on
(rename-buffer (format "*eldoc for %s*"
(mapconcat (lambda (s) (format "%s" s))
things-reported-on
", ")))))
- ;; Finally, output to the echo area. We currently do handling
- ;; the `truncate-sym-name-if-fit' special case first, then by
- ;; selecting a top-section of the `*eldoc' buffer. I'm pretty
- ;; sure nicer strategies can be used here, probably by splitting
- ;; this pfunction into some `eldoc-display-functions' special
- ;; hook.
+ ;; Finally, output to the echo area. We handle the
+ ;; `truncate-sym-name-if-fit' special case first, by selecting a
+ ;; top-section of the `*eldoc' buffer. I'm pretty sure nicer
+ ;; strategies can be used here, probably by splitting this
+ ;; function into some `eldoc-display-functions' special hook.
(if (and (eq 'truncate-sym-name-if-fit eldoc-echo-area-use-multiline-p)
(null (cdr docs))
(setq single-sym-name
(format "%s" (plist-get (cdar docs) :thing)))
(> (+ (length (caar docs)) (length single-sym-name) 2) width))
(eldoc--message (caar docs))
- (with-current-buffer (eldoc-doc-buffer)
- (goto-char (point-min))
- (cond
- ;; We truncate a long message
- ((> available 1)
- (cl-loop
- initially (goto-char (line-end-position (1+ available)))
- for truncated = nil then t
- for needed
- = (let ((truncate-lines message-truncate-lines))
- (count-screen-lines (point-min) (point) t (minibuffer-window)))
- while (> needed (if truncated (1- available) available))
- do (goto-char (line-end-position (if truncated 0 -1)))
- (while (bolp) (goto-char (line-end-position 0)))
- finally
- (unless (and truncated
- eldoc-prefer-doc-buffer
- (get-buffer-window eldoc--doc-buffer))
- (eldoc--message
- (concat (buffer-substring (point-min) (point))
- (and truncated
- (format
- "\n(Documentation truncated. Use `%s' to see rest)"
- (substitute-command-keys "\\[eldoc-doc-buffer]"))))))))
- ((= available 1)
- ;; truncate brutally ; FIXME: use `eldoc-prefer-doc-buffer' here, too?
- (eldoc--message
- (truncate-string-to-width
- (buffer-substring (point-min) (line-end-position 1)) width)))))))))
-
-;; this variable should be unbound, but that confuses
+ (with-current-buffer (eldoc-doc-buffer)
+ (goto-char (point-min))
+ (cond
+ ;; Potentially truncate a long message into less lines,
+ ;; then display it in the echo area;
+ ((> available 1)
+ (cl-loop
+ initially (goto-char (line-end-position (1+ available)))
+ for truncated = nil then t
+ for needed
+ = (let ((truncate-lines message-truncate-lines))
+ (count-screen-lines (point-min) (point) t (minibuffer-window)))
+ while (> needed (if truncated (1- available) available))
+ do (goto-char (line-end-position (if truncated 0 -1)))
+ (while (bolp) (goto-char (line-end-position 0)))
+ finally
+ (unless (and truncated
+ eldoc-prefer-doc-buffer
+ (get-buffer-window eldoc--doc-buffer))
+ (eldoc--message
+ (concat (buffer-substring (point-min) (point))
+ (and truncated
+ (format
+ "\n(Documentation truncated. Use `%s' to see rest)"
+ (substitute-command-keys "\\[eldoc-doc-buffer]"))))))))
+ ((= available 1)
+ ;; Truncate "brutally." ; FIXME: use `eldoc-prefer-doc-buffer' too?
+ (eldoc--message
+ (truncate-string-to-width
+ (buffer-substring (point-min) (line-end-position 1)) width)))))))))
+
+;; This variable should be unbound, but that confuses
;; `describe-symbol' for some reason.
(defvar eldoc--make-callback nil "Helper for function `eldoc--make-callback'.")
@@ -506,11 +506,12 @@ Honour most of `eldoc-echo-area-use-multiline-p'."
"Show first doc string for item at point.
Default value for `eldoc-documentation-strategy'."
(run-hook-with-args-until-success 'eldoc-documentation-functions
- (eldoc--make-callback :patient)))
+ (eldoc--make-callback :patient)))
-(defun eldoc-documentation-compose (&optional eagerlyp)
- "Show multiple doc strings at once after waiting for all.
-Meant as a value for `eldoc-documentation-strategy'."
+(defun eldoc--documentation-compose-1 (eagerlyp)
+ "Helper function for composing multiple doc strings.
+If EAGERLYP is non-nil show documentation as soon as possible,
+else wait for all doc strings."
(run-hook-wrapped 'eldoc-documentation-functions
(lambda (f)
(let* ((callback (eldoc--make-callback
@@ -520,10 +521,15 @@ Meant as a value for `eldoc-documentation-strategy'."
nil)))
t)
+(defun eldoc-documentation-compose ()
+ "Show multiple doc strings at once after waiting for all.
+Meant as a value for `eldoc-documentation-strategy'."
+ (eldoc--documentation-compose-1 nil))
+
(defun eldoc-documentation-compose-eagerly ()
"Show multiple doc strings at once as soon as possible.
Meant as a value for `eldoc-documentation-strategy'."
- (eldoc-documentation-compose 'eagerlyp))
+ (eldoc--documentation-compose-1 t))
(defun eldoc-documentation-enthusiast ()
"Show most important doc string produced so far.
@@ -546,25 +552,24 @@ specifies the sources of documentation, is queried and how its
results are organized before being displayed to the user. The
following values are allowed:
-- `eldoc-documentation-default': queries the special hook for the
- first function that produces a doc string value and displays
- only that one;
+- `eldoc-documentation-default': calls functions in the special
+ hook in order until one is found that produces a doc string
+ value. Display only that value;
-- `eldoc-documentation-compose': queries the special hook for all
- functions that produce doc strings and displays all of them
- together as soon as all are ready, preserving the relative
- order of doc strings as specified by the order of functions in
- the hook;
+- `eldoc-documentation-compose': calls all functions in the
+ special hook and displays all of the resulting doc strings
+ together. Wait for all strings to be ready, and preserve their
+ relative as specified by the order of functions in the hook;
-- `eldoc-documentation-compose-eagerly': queries the special hook
- for all functions that produce doc strings and displays as many
- as possible, as soon as possible, preserving the relative order
- of doc strings;
+- `eldoc-documentation-compose-eagerly': calls all functions in
+ the special hook and display as many of the resulting doc
+ strings as possible, as soon as possibl. Preserving the
+ relative order of doc strings;
-- `eldoc-documentation-enthusiast': queries the special hook for
- all functions the produce doc strings but displays only the
- most important one at any given time. A function appearing
- first in the special hook is considered more important.
+- `eldoc-documentation-enthusiast': calls all functions in the
+ special hook and displays only the most important resulting
+ docstring one at any given time. A function appearing first in
+ the special hook is considered more important.
This variable can also be set to a function of no args that
allows for some or all of the special hook
@@ -596,7 +601,11 @@ documentation themselves."
(local-variable-p 'eldoc-documentation-strategy))))
(defvar eldoc--enthusiasm-curbing-timer nil
- "Timer used by `eldoc-documentation-enthusiast' to avoid blinking.")
+ "Timer used by the `eldoc-documentation-enthusiast' strategy.
+When a doc string is encountered, it must endure a certain amount
+of time unchallenged until it is displayed to the user. This
+prevents blinking if a lower priority docstring comes in shortly
+before a higher priority one.")
(defalias 'eldoc #'eldoc-print-current-symbol-info)
@@ -609,7 +618,8 @@ documentation themselves."
(eldoc--message nil))
(let ((non-essential t))
;; Only keep looking for the info as long as the user hasn't
- ;; requested our attention. This also locally disables inhibit-quit.
+ ;; requested our attention. This also locally disables
+ ;; inhibit-quit.
(while-no-input
(let* ((howmany 0) (want 0) (docs-registered '()))
(cl-labels
@@ -652,12 +662,13 @@ documentation themselves."
t))))))
(let* ((eldoc--make-callback #'make-callback)
(res (funcall eldoc-documentation-strategy)))
- (cond (;; old protocol: got string, output immediately
- (stringp res) (register-doc 0 res nil) (display-doc))
- (;; old protocol: got nil, clear the echo area
- (null res) (eldoc--message nil))
- (;; got something else, trust callback will be called
- t)))))))))
+ ;; Observe the old and the new protocol:
+ (cond (;; Old protocol: got string, output immediately;
+ (stringp res) (register-doc 0 res nil) (display-doc))
+ (;; Old protocol: got nil, clear the echo area;
+ (null res) (eldoc--message nil))
+ (;; New protocol: trust callback will be called;
+ t)))))))))
;; When point is in a sexp, the function args are not reprinted in the echo
;; area after every possible interactive command because some of them print