From c039a4356fa363ef10b8320c3856eb3466eb32f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20T=C3=A1vora?= Date: Tue, 26 May 2020 19:38:08 +0100 Subject: [PATCH 2/2] Reimplement funcall, but in the future * lisp/emacs-lisp/eldoc.el (eldoc-future, eldoc-future-set) (eldoc-future-set-call): New functions. (eldoc-documentation-functions): Prepare for Stefan's genius docstring. (eldoc-documentation-default, eldoc-documentation-compose): Use futuristic stuff. --- lisp/emacs-lisp/eldoc.el | 54 ++++++++++++++++++++++++++-------------- 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el index fa36987014..e015076c4d 100644 --- a/lisp/emacs-lisp/eldoc.el +++ b/lisp/emacs-lisp/eldoc.el @@ -337,18 +337,32 @@ eldoc-display-message-no-interference-p (not (or executing-kbd-macro (bound-and-true-p edebug-active)))) +;;;; Futuristic interlude +(cl-defstruct (eldoc-future + (:conc-name eldoc-future--) + (:constructor eldoc-future-make ())) ; become Yoda we? + "" + (value 'eldoc-future--unset) + callback) + +(defun eldoc-future-set (f v) + "" + (cl-assert (eq (eldoc-future--value f) 'eldoc-future--unset)) + (setf (eldoc-future--value f) v) + (when (eldoc-future--callback f) + (funcall (eldoc-future--callback f) v))) + +(defun eldoc-future-set-callback (f c) + "" + (cl-assert (null (eldoc-future--callback f))) + (setf (eldoc-future--callback f) c) + (unless (eq (eldoc-future--value f) 'eldoc-future--unset) + (funcall c (eldoc-future--value f)))) + + (defvar eldoc-documentation-functions nil "Hook of functions that produce doc strings. -Each hook function should accept at least one argument CALLBACK -and decide whether to display a doc short string about the -context around point. If the decision and the doc string can be -produced quickly, the hook function can ignore CALLBACK and -immediately return the doc string, or nil if there's no doc -appropriate for the context. Otherwise, if its computation is -expensive or can't be performed directly, the hook function -should arrange for CALLBACK to be asynchronously called at a -later time, passing it either nil or the desired doc string. The -hook function should then return a non-nil, non-string value. + Note that this hook is only in effect if the value of `eldoc-documentation-function' (notice the singular) is bound to @@ -372,19 +386,23 @@ eldoc--handle-multiline (defun eldoc-documentation-default () "Show first doc string for item at point. Default value for `eldoc-documentation-function'." - (run-hook-with-args-until-success 'eldoc-documentation-functions - eldoc--callback)) + (let ((x (run-hook-with-args-until-success 'eldoc-documentation-functions))) + (if (eldoc-future-p x) (eldoc-future-set-callback x eldoc--callback) + x))) (defun eldoc-documentation-compose () "Show multiple doc string results at once. Meant as a value for `eldoc-documentation-function'." (let ((res 0)) - (run-hook-wrapped 'eldoc-documentation-functions - (lambda (f) - (let ((str (funcall f eldoc--callback))) - (if (stringp str) (funcall eldoc--callback str) - (when str (setq res (1+ res)))) - nil))) + (run-hook-wrapped + 'eldoc-documentation-functions + (lambda (f) + (let ((x (funcall f))) + (cond ((stringp x) (funcall eldoc--callback x)) + ((eldoc-future-p x) + (eldoc-future-set-callback x eldoc--callback) + (setq res (1+ res)))) + nil))) ;; play ball with `eldoc-print-current-symbol-info' (if (plusp res) (1- res) ""))) -- 2.20.1