summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Távora <joaotavora@gmail.com>2020-07-19 00:48:43 +0100
committerJoão Távora <joaotavora@gmail.com>2020-07-23 11:57:27 +0100
commitfcd43287b3d36a5706760d68b7d88502ebe43a47 (patch)
treec7ec4a1dd15ba9dabbdcfb2135cf687efbe6f3ef
parent1bae7ba53b8239201853ce755e9e21a96ad279c0 (diff)
downloademacs-fcd43287b3d36a5706760d68b7d88502ebe43a47.tar.gz
Don't needlessly request docs from ElDoc functions
Fixes: bug#42421 Do this conservatively for now: if the ElDoc helper buffer (as returned by eldoc--doc-buffer) is visible and showing documentation for the very same "situation" (as computed by the the new eldoc--request-state helper), don't request that documentation from sources again. Before this change, not only was that request inefficient but if the user invoked scroll-other-window to see more of the helper buffer, that would eventually cause it to be reformatted and unexpectedly recentered. Later on, when a customizable list of documentation "sinks" is offered to the user, say, something like eldoc-display-functions, this process must be consolidated. In those circumstances, as soon as one of those sinks signals that it doesn't have up-to-date documentation for the state computed by eldoc--request-state, documentation will have to be requested anew from eldoc-documentation-functions via eldoc--invoke-strategy. * lisp/emacs-lisp/eldoc.el (eldoc--request-docs-p): Rework from eglot-display-message-p. (eldoc--last-request-state): New variable. (eldoc--request-state): New helper. (eldoc--handle-docs): Memorize state of request in doc buffer. (eldoc-print-current-symbol-info): Pass a token to eldoc--request-docs-p. (Version): Bump to 1.6.0
-rw-r--r--lisp/emacs-lisp/eldoc.el61
1 files changed, 42 insertions, 19 deletions
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index 6ed5bff9f44..fcb104e5477 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -5,7 +5,7 @@
;; Author: Noah Friedman <friedman@splode.com>
;; Keywords: extensions
;; Created: 1995-10-06
-;; Version: 1.5.0
+;; Version: 1.6.0
;; Package-Requires: ((emacs "26.3"))
;; This is a GNU ELPA :core package. Avoid functionality that is not
@@ -340,16 +340,32 @@ Also store it in `eldoc-last-message' and return that value."
;; for us, but do note that the last-message will be gone.
(setq eldoc-last-message nil))))
-;; Decide whether now is a good time to display a message.
-(defun eldoc-display-message-p ()
- "Return non-nil when it is appropriate to display an ElDoc message."
- (and (eldoc-display-message-no-interference-p)
- ;; If this-command is non-nil while running via an idle
- ;; timer, we're still in the middle of executing a command,
- ;; e.g. a query-replace where it would be annoying to
- ;; overwrite the echo area.
- (not this-command)
- (eldoc--message-command-p last-command)))
+(defvar-local eldoc--last-request-state nil
+ "Tuple containing information about last ElDoc request.")
+(defun eldoc--request-state ()
+ "Compute information to store in `eldoc--last-request-state'."
+ (list (current-buffer) (buffer-modified-tick) (point)))
+
+(defun eldoc--request-docs-p (request-state)
+ "Return non-nil when it is appropriate to request docs.
+REQUEST-STATE is a candidate for `eldoc--last-request-state'"
+ (and
+ ;; FIXME: The original idea behind this function is to protect the
+ ;; Echo area from ElDoc interference, but since that is only one of
+ ;; the possible outlets of ElDoc, this must soon be reworked.
+ (eldoc-display-message-no-interference-p)
+ (not (and eldoc--doc-buffer
+ (get-buffer-window eldoc--doc-buffer)
+ (equal request-state
+ (with-current-buffer
+ eldoc--doc-buffer
+ eldoc--last-request-state))))
+ ;; If this-command is non-nil while running via an idle
+ ;; timer, we're still in the middle of executing a command,
+ ;; e.g. a query-replace where it would be annoying to
+ ;; overwrite the echo area.
+ (not this-command)
+ (eldoc--message-command-p last-command)))
;; Check various conditions about the current environment that might make
@@ -400,7 +416,8 @@ so that the global value (i.e. the default value of the hook) is
taken into account if the major mode specific function does not
return any documentation.")
-(defvar eldoc--doc-buffer nil "Buffer holding latest eldoc-produced docs.")
+(defvar eldoc--doc-buffer nil "Buffer displaying latest ElDoc-produced docs.")
+
(defun eldoc-doc-buffer (&optional interactive)
"Get latest *eldoc* help buffer. Interactively, display it."
(interactive (list t))
@@ -410,6 +427,7 @@ return any documentation.")
(setq eldoc--doc-buffer (get-buffer-create "*eldoc*")))
(when interactive (display-buffer eldoc--doc-buffer))))
+
(defun eldoc--handle-docs (docs)
"Display multiple DOCS in echo area.
DOCS is a list of (STRING PLIST...). It is already sorted.
@@ -429,9 +447,12 @@ Honor most of `eldoc-echo-area-use-multiline-p'."
(integer val)
(t 1)))
(things-reported-on)
+ (request eldoc--last-request-state)
single-doc single-doc-sym)
;; Then, compose the contents of the `*eldoc*' buffer.
(with-current-buffer (eldoc-doc-buffer)
+ ;; Set doc-buffer's `eldoc--last-request-state', too
+ (setq eldoc--last-request-state request)
(let ((inhibit-read-only t))
(erase-buffer) (setq buffer-read-only t)
(local-set-key "q" 'quit-window)
@@ -741,14 +762,16 @@ should endeavour to display the docstrings eventually produced."
(defun eldoc-print-current-symbol-info (&optional interactive)
"Document thing at point."
(interactive '(t))
- (cond (interactive
- (eldoc--invoke-strategy))
- (t
- (if (not (eldoc-display-message-p))
- ;; Erase the last message if we won't display a new one.
- (when eldoc-last-message
- (eldoc--message nil))
+ (let ((token (eldoc--request-state)))
+ (cond (interactive
+ (eldoc--invoke-strategy))
+ ((not (eldoc--request-docs-p token))
+ ;; Erase the last message if we won't display a new one.
+ (when eldoc-last-message
+ (eldoc--message nil)))
+ (t
(let ((non-essential t))
+ (setq eldoc--last-request-state token)
;; Only keep looking for the info as long as the user hasn't
;; requested our attention. This also locally disables
;; inhibit-quit.