Expose ElDoc functions in a hook (Bug#28257)

* lisp/emacs-lisp/eldoc.el: Update commentary.
(eldoc--eval-expression-setup): Use new hook.
(eldoc--supported-p): Accomodate new hook.
(eldoc-documentation-functions): New hook.
(eldoc-documentation-default, eldoc-documentation-compose): New
functions.
(eldoc-documentation-function): Use 'eldoc-documentation-default' as new
default value.  Update documentation and custom attributes.
(eldoc-print-current-symbol-info): Accomodate possible null value for
'eldoc-documentation-function'.
* etc/NEWS: Mention them.
* doc/emacs/programs.texi (Emacs Lisp Documentation Lookup): Mention
new hook and changes to 'eldoc-documentation-function'.
* lisp/hexl.el (hexl-mode, hexl-revert-buffer-function):
* lisp/ielm.el (inferior-emacs-lisp-mode):
* lisp/progmodes/cfengine.el (cfengine3-mode):
* lisp/progmodes/elisp-mode.el (emacs-lisp-mode):
* lisp/progmodes/octave.el (octave-mode):
* lisp/progmodes/python.el (python-mode): Use new hook.
This commit is contained in:
Mark Oteiza 2020-02-25 17:53:04 -05:00
parent 03c07c88d9
commit c0fcbd2c11
9 changed files with 115 additions and 36 deletions

View file

@ -1269,9 +1269,27 @@ information whenever there is a Lisp function or variable at point;
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

View file

@ -125,6 +125,18 @@ To revert to the previous behaviour,
unconditionally aborts the current edebug instrumentation with the
supplied error message.
+++
** 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.
Modes should use the new hook instead of this variable to register
their backends.
** Tramp
+++

View file

@ -40,9 +40,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,8 +222,8 @@ expression point is on."
(defun eldoc--eval-expression-setup ()
;; Setup `eldoc', similar to `emacs-lisp-mode'. FIXME: Call
;; `emacs-lisp-mode' itself?
(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))
;;;###autoload
@ -235,7 +235,11 @@ See `eldoc-documentation-function' for more detail."
(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 (not (memq eldoc-documentation-function '(nil ignore)))
(or (and (local-variable-p hook)
(buffer-local-value hook (current-buffer)))
(default-value hook)))))
(defun eldoc-schedule-timer ()
@ -347,8 +351,46 @@ Also store it in `eldoc-last-message' and return that value."
(not (or executing-kbd-macro (bound-and-true-p edebug-active))))
;;;###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 first 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))))))))
(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.
@ -359,14 +401,14 @@ arg list.
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")
(const :tag "None" nil))
:version "28.1"
:group 'eldoc)
(defun eldoc-print-current-symbol-info ()
"Print the text produced by `eldoc-documentation-function'."
@ -381,7 +423,8 @@ return any documentation.")
;; Only keep looking for the info as long as the user hasn't
;; requested our attention. This also locally disables inhibit-quit.
(while-no-input
(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

View file

@ -367,8 +367,8 @@ You can use \\[hexl-find-file] to visit a file in 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")
@ -455,6 +455,8 @@ and edit the file in `hexl-mode'."
;; 2. reset change-major-mode-hook in case that `hexl-mode'
;; previously added hexl-maybe-dehexlify-buffer to it.
(remove-hook 'change-major-mode-hook #'hexl-maybe-dehexlify-buffer t)
(remove-hook 'eldoc-documentation-functions
#'hexl-print-current-point-info t)
(setq major-mode 'fundamental-mode)
(hexl-mode)))

View file

@ -541,8 +541,8 @@ Customized bindings may be defined in `ielm-map', which currently contains:
(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)

View file

@ -1390,12 +1390,15 @@ to the action header."
(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 (boundp 'eldoc-documentation-functions)
(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)

View file

@ -250,8 +250,8 @@ Blank lines separate paragraphs. Semicolons start comments.
(add-hook 'electric-pair-mode-hook #'emacs-lisp-set-electric-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

View file

@ -619,8 +619,7 @@ Key bindings:
(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))

View file

@ -5544,8 +5544,10 @@ REPORT-FN is Flymake's callback function."
;; Emacs<25
(set (make-local-variable 'eldoc-documentation-function)
#'python-eldoc-function)
(add-function :before-until (local 'eldoc-documentation-function)
#'python-eldoc-function))
(if (boundp 'eldoc-documentation-functions)
(add-hook 'eldoc-documentation-functions #'python-eldoc-function nil t)
(add-function :before-until (local 'eldoc-documentation-function)
#'python-eldoc-function)))
(add-to-list
'hs-special-modes-alist