From: Mark Oteiza <mvoteiza@udel.edu>
To: 28257@debbugs.gnu.org
Subject: bug#28257: 26.0.50; [PATCH] expose eldoc functions in a hook
Date: Sun, 27 Aug 2017 22:10:57 -0400 [thread overview]
Message-ID: <87ziakwifi.fsf@holos> (raw)
Hi,
This makes it possible to use the results from multiple eldoc functions
at once, through the addition of an abnormal hook.
I'm not aware of a good way to access the default value (or other local
values) of eldoc-documentation-function when shadowed by a :before-until
advice returning non-nil.
Perhaps eldoc-documentation-function should remain a defvar, not sure.
diff --git a/doc/emacs/programs.texi b/doc/emacs/programs.texi
index 27ac0eb640..ea7f2f3d26 100644
--- a/doc/emacs/programs.texi
+++ b/doc/emacs/programs.texi
@@ -1279,9 +1279,27 @@ Lisp Doc
for a function, it shows the argument list, and for a variable it
shows the first line of the variable's documentation string. To
toggle Eldoc mode, type @kbd{M-x eldoc-mode}. There's also a Global
-Eldoc mode, which is turned on by default, and affects buffers, such
-as @samp{*scratch*}, whose major mode is Emacs Lisp or Lisp
-Interaction (@w{@kbd{M-x global-eldoc-mode}} to turn it off globally).
+Eldoc mode, which is turned on by default, and affects buffers whose
+major mode sets the variables described below. Use @w{@kbd{M-x
+global-eldoc-mode}} to turn it off globally.
+
+@vindex eldoc-documentation-function
+@vindex eldoc-documentation-functions
+ These variables can be used to configure ElDoc mode:
+
+@table @code
+@item eldoc-documentation-function
+This variable holds the function which is used to retrieve
+documentation for the item at point from the functions in the hook
+@code{eldoc-documentation-functions}. By default,
+@code{eldoc-documentation-function} returns the first documentation
+string produced by the @code{eldoc-documentation-functions} hook.
+
+@item eldoc-documentation-functions
+This abnormal hook holds documentation functions. It acts as a
+collection of backends for ElDoc. This is what modes should use to
+register their documentation functions with ElDoc.
+@end table
@node Hideshow
@section Hideshow minor mode
diff --git a/etc/NEWS b/etc/NEWS
index 3f38153048..b2dc06b137 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -791,6 +791,15 @@ breakpoint (e.g. with "f" and "o") by customizing the new option
This allows to enlarge the maximum recursion depth when instrumenting
code.
+** ElDoc
+
+*** New hook 'eldoc-documentation-functions' to be used for registering
+doc string functions. This makes the results of all doc string
+functions accessible to the user through the existing single function hook
+'eldoc-documentation-function'.
+
+*** 'eldoc-documentation-function' is now a custom variable.
+
** Eshell
*** 'eshell-input-filter's value is now a named function
diff --git a/lisp/emacs-lisp/eldoc.el b/lisp/emacs-lisp/eldoc.el
index bca40ab87d..7d0ff0f359 100644
--- a/lisp/emacs-lisp/eldoc.el
+++ b/lisp/emacs-lisp/eldoc.el
@@ -41,9 +41,9 @@
;; (add-hook 'ielm-mode-hook 'eldoc-mode)
;; (add-hook 'eval-expression-minibuffer-setup-hook 'eldoc-mode)
-;; Major modes for other languages may use ElDoc by defining an
-;; appropriate function as the buffer-local value of
-;; `eldoc-documentation-function'.
+;; Major modes for other languages may use ElDoc by adding an
+;; appropriate function to the buffer-local value of
+;; `eldoc-documentation-functions'.
;;; Code:
@@ -222,7 +222,11 @@ turn-on-eldoc-mode
(defun eldoc--supported-p ()
"Non-nil if an ElDoc function is set for this buffer."
- (not (memq eldoc-documentation-function '(nil ignore))))
+ (let ((hook 'eldoc-documentation-functions))
+ (and eldoc-documentation-function
+ (or (and (local-variable-p hook)
+ (buffer-local-value hook (current-buffer)))
+ (default-value hook)))))
\f
(defun eldoc-schedule-timer ()
@@ -341,7 +345,47 @@ eldoc-display-message-no-interference-p
\f
;;;###autoload
-(defvar eldoc-documentation-function #'ignore
+(defvar eldoc-documentation-functions nil
+ "Hook for functions to call to return doc string.
+Each function should accept no arguments and return a one-line
+string for displaying doc about a function etc. appropriate to
+the context around point. It should return nil if there's no doc
+appropriate for the context. Typically doc is returned if point
+is on a function-like name or in its arg list.
+
+Major modes should modify this hook locally, for example:
+ (add-hook \\='eldoc-documentation-functions #\\='foo-mode-eldoc nil t)
+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.")
+
+(defun eldoc-documentation-default ()
+ "Show doc string for item at point.
+Default value for `eldoc-documentation-function'."
+ (let ((res (run-hook-with-args-until-success 'eldoc-documentation-functions)))
+ (when res
+ (if eldoc-echo-area-use-multiline-p res
+ (truncate-string-to-width
+ res (1- (window-width (minibuffer-window))))))))
+
+(defun eldoc-documentation-compose ()
+ "Show multiple doc string results at once.
+Meant as a value for `eldoc-documentation-function'."
+ (let (res)
+ (run-hook-wrapped
+ 'eldoc-documentation-functions
+ (lambda (f)
+ (let ((str (funcall f)))
+ (when str (push str res))
+ nil)))
+ (when res
+ (setq res (mapconcat #'identity (nreverse res) ", "))
+ (if eldoc-echo-area-use-multiline-p res
+ (truncate-string-to-width
+ res (1- (window-width (minibuffer-window))))))))
+
+;;;###autoload
+(defcustom eldoc-documentation-function #'eldoc-documentation-default
"Function to call to return doc string.
The function of no args should return a one-line string for displaying
doc about a function etc. appropriate to the context around point.
@@ -352,14 +396,12 @@ eldoc-documentation-function
The result is used as is, so the function must explicitly handle
the variables `eldoc-argument-case' and `eldoc-echo-area-use-multiline-p',
and the face `eldoc-highlight-function-argument', if they are to have any
-effect.
-
-Major modes should modify this variable using `add-function', for example:
- (add-function :before-until (local \\='eldoc-documentation-function)
- #\\='foo-mode-eldoc-function)
-so that the global documentation function (i.e. the default value of the
-variable) is taken into account if the major mode specific function does not
-return any documentation.")
+effect."
+ :link '(info-link "(emacs) Lisp Doc")
+ :type '(radio (function-item eldoc-documentation-default)
+ (function-item eldoc-documentation-compose)
+ (function :tag "Other function"))
+ :group 'eldoc)
(defun eldoc-print-current-symbol-info ()
"Print the text produced by `eldoc-documentation-function'."
@@ -371,7 +413,8 @@ eldoc-print-current-symbol-info
(when eldoc-last-message
(eldoc-message nil)
nil))
- (eldoc-message (funcall eldoc-documentation-function)))))
+ (let ((fun eldoc-documentation-function))
+ (when fun (eldoc-message (funcall fun)))))))
;; If the entire line cannot fit in the echo area, the symbol name may be
;; truncated or eliminated entirely from the output to make room for the
diff --git a/lisp/hexl.el b/lisp/hexl.el
index 0a598b22f6..e1c5386c1a 100644
--- a/lisp/hexl.el
+++ b/lisp/hexl.el
@@ -395,8 +395,8 @@ hexl-mode
(add-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer nil t)
;; Set a callback function for eldoc.
- (add-function :before-until (local 'eldoc-documentation-function)
- #'hexl-print-current-point-info)
+ (add-hook 'eldoc-documentation-functions
+ #'hexl-print-current-point-info nil t)
(eldoc-add-command-completions "hexl-")
(eldoc-remove-command "hexl-save-buffer"
"hexl-current-address")
@@ -506,6 +506,8 @@ hexl-mode-exit
(remove-hook 'change-major-mode-hook 'hexl-maybe-dehexlify-buffer t)
(remove-hook 'post-command-hook 'hexl-follow-ascii-find t)
+ (remove-hook 'eldoc-documentation-functions
+ #'hexl-print-current-point-info t)
(setq hexl-ascii-overlay nil)
(let ((mms ()))
diff --git a/lisp/ielm.el b/lisp/ielm.el
index 42b065fe62..3e8b8198f5 100644
--- a/lisp/ielm.el
+++ b/lisp/ielm.el
@@ -541,8 +541,8 @@ inferior-emacs-lisp-mode
(set (make-local-variable 'completion-at-point-functions)
'(comint-replace-by-expanded-history
ielm-complete-filename elisp-completion-at-point))
- (add-function :before-until (local 'eldoc-documentation-function)
- #'elisp-eldoc-documentation-function)
+ (add-hook 'eldoc-documentation-functions
+ #'elisp-eldoc-documentation-function nil t)
(set (make-local-variable 'ielm-prompt-internal) ielm-prompt)
(set (make-local-variable 'comint-prompt-read-only) ielm-prompt-read-only)
(setq comint-get-old-input 'ielm-get-old-input)
diff --git a/lisp/progmodes/cfengine.el b/lisp/progmodes/cfengine.el
index 5bc7b66063..c775a18220 100644
--- a/lisp/progmodes/cfengine.el
+++ b/lisp/progmodes/cfengine.el
@@ -1390,12 +1390,15 @@ cfengine3-mode
(when buffer-file-name
(shell-quote-argument buffer-file-name)))))
- ;; For emacs < 25.1 where `eldoc-documentation-function' defaults to
- ;; nil.
- (or eldoc-documentation-function
- (setq-local eldoc-documentation-function #'ignore))
- (add-function :before-until (local 'eldoc-documentation-function)
- #'cfengine3-documentation-function)
+ (if (> emacs-major-version 25)
+ (add-hook 'eldoc-documentation-functions
+ #'cfengine3-documentation-function nil t)
+ ;; For emacs < 25.1 where `eldoc-documentation-function' defaults
+ ;; to nil.
+ (or eldoc-documentation-function
+ (setq-local eldoc-documentation-function #'ignore))
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'cfengine3-documentation-function))
(add-hook 'completion-at-point-functions
#'cfengine3-completion-function nil t)
diff --git a/lisp/progmodes/elisp-mode.el b/lisp/progmodes/elisp-mode.el
index b3f452ca5b..07210381f3 100644
--- a/lisp/progmodes/elisp-mode.el
+++ b/lisp/progmodes/elisp-mode.el
@@ -235,8 +235,8 @@ emacs-lisp-mode
(append '((?\` . ?\') (?‘ . ?’)) electric-pair-text-pairs))
(setq-local electric-quote-string t)
(setq imenu-case-fold-search nil)
- (add-function :before-until (local 'eldoc-documentation-function)
- #'elisp-eldoc-documentation-function)
+ (add-hook 'eldoc-documentation-functions
+ #'elisp-eldoc-documentation-function nil t)
(add-hook 'xref-backend-functions #'elisp--xref-backend nil t)
(setq-local project-vc-external-roots-function #'elisp-load-path-roots)
(add-hook 'completion-at-point-functions
diff --git a/lisp/progmodes/octave.el b/lisp/progmodes/octave.el
index ac9ba630c4..5843361dbd 100644
--- a/lisp/progmodes/octave.el
+++ b/lisp/progmodes/octave.el
@@ -596,8 +596,7 @@ octave-mode
(add-hook 'before-save-hook 'octave-sync-function-file-names nil t)
(setq-local beginning-of-defun-function 'octave-beginning-of-defun)
(and octave-font-lock-texinfo-comment (octave-font-lock-texinfo-comment))
- (add-function :before-until (local 'eldoc-documentation-function)
- 'octave-eldoc-function)
+ (add-hook 'eldoc-documentation-functions 'octave-eldoc-function nil t)
(easy-menu-add octave-mode-menu))
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 6f169123b9..8b4cfaa77a 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -5198,8 +5198,10 @@ python-mode
;; Emacs<25
(set (make-local-variable 'eldoc-documentation-function)
#'python-eldoc-function)
- (add-function :before-until (local 'eldoc-documentation-function)
- #'python-eldoc-function))
+ (if (< emacs-major-version 26)
+ (add-function :before-until (local 'eldoc-documentation-function)
+ #'python-eldoc-function)
+ (add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t)))
(add-to-list
'hs-special-modes-alist
diff --git a/lisp/simple.el b/lisp/simple.el
index 58f8372192..f56a505523 100644
--- a/lisp/simple.el
+++ b/lisp/simple.el
@@ -1490,8 +1490,8 @@ read--expression
(minibuffer-with-setup-hook
(lambda ()
;; FIXME: call emacs-lisp-mode?
- (add-function :before-until (local 'eldoc-documentation-function)
- #'elisp-eldoc-documentation-function)
+ (add-hook 'eldoc-documentation-functions
+ #'elisp-eldoc-documentation-function nil t)
(eldoc-mode 1)
(add-hook 'completion-at-point-functions
#'elisp-completion-at-point nil t)
next reply other threads:[~2017-08-28 2:10 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-08-28 2:10 Mark Oteiza [this message]
2017-08-28 2:49 ` bug#28257: 26.0.50; [PATCH] expose eldoc functions in a hook npostavs
2017-08-28 3:11 ` Mark Oteiza
2017-08-29 1:05 ` npostavs
2017-08-30 1:50 ` Mark Oteiza
2019-06-24 16:16 ` Lars Ingebrigtsen
2019-06-24 22:51 ` Noam Postavsky
2019-06-26 14:03 ` Mark Oteiza
2020-01-26 23:47 ` Mark Oteiza
2020-01-31 14:05 ` Eli Zaretskii
2020-02-08 10:03 ` Eli Zaretskii
2020-02-11 21:57 ` Noam Postavsky
2020-02-14 9:58 ` Eli Zaretskii
2020-02-14 14:51 ` Stefan Monnier
2020-02-14 14:50 ` Stefan Monnier
2020-02-14 22:54 ` Mark Oteiza
2020-02-21 8:47 ` Eli Zaretskii
2020-02-25 23:18 ` Mark Oteiza
2020-08-10 14:42 ` Lars Ingebrigtsen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87ziakwifi.fsf@holos \
--to=mvoteiza@udel.edu \
--cc=28257@debbugs.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).