diff options
Diffstat (limited to 'lisp/help-fns.el')
-rw-r--r-- | lisp/help-fns.el | 112 |
1 files changed, 82 insertions, 30 deletions
diff --git a/lisp/help-fns.el b/lisp/help-fns.el index d7fb038f45a..17fabe4f63a 100644 --- a/lisp/help-fns.el +++ b/lisp/help-fns.el @@ -64,6 +64,12 @@ described in `help-fns-describe-variable-functions', except that the functions are called with two parameters: The face and the frame.") +(defvar help-fns--activated-functions nil + "Internal variable let-bound to help functions that have triggered. +Help functions can check the contents of this list to see whether +a specific previous help function has inserted something in the +current help buffer.") + ;; Functions (defvar help-definition-prefixes nil @@ -126,6 +132,12 @@ with the current prefix. The files are chosen according to :group 'help :version "26.3") +(defcustom help-enable-symbol-autoload nil + "Perform autoload if docs are missing from autoload objects." + :type 'boolean + :group 'help + :version "28.1") + (defun help--symbol-class (s) "Return symbol class characters for symbol S." (when (stringp s) @@ -154,7 +166,7 @@ with the current prefix. The files are chosen according to (mapcar (lambda (c) (let* ((s (intern c)) (doc (condition-case nil (documentation s) (error nil))) - (doc (and doc (substring doc 0 (string-match "\n" doc))))) + (doc (and doc (substring doc 0 (string-search "\n" doc))))) (list c (propertize (format "%-4s" (help--symbol-class s)) 'face 'completions-annotations) @@ -164,8 +176,11 @@ with the current prefix. The files are chosen according to completions)) (defun help--symbol-completion-table (string pred action) - (if (and completions-detailed (eq action 'metadata)) - '(metadata (affixation-function . help--symbol-completion-table-affixation)) + (if (eq action 'metadata) + `(metadata + ,@(when completions-detailed + '((affixation-function . help--symbol-completion-table-affixation))) + (category . symbol-help)) (when help-enable-completion-autoload (let ((prefixes (radix-tree-prefixes (help-definition-prefixes) string))) (help--load-prefixes prefixes))) @@ -221,7 +236,10 @@ interactive command." ;;;###autoload (defun describe-function (function) "Display the full documentation of FUNCTION (a symbol). -When called from lisp, FUNCTION may also be a function object." +When called from Lisp, FUNCTION may also be a function object. + +See the `help-enable-symbol-autoload' variable for special +handling of autoloaded functions." (interactive (help-fns--describe-function-or-command-prompt)) ;; We save describe-function-orig-buffer on the help xref stack, so @@ -257,7 +275,7 @@ When called from lisp, FUNCTION may also be a function object." ;;;###autoload (defun describe-command (command) "Display the full documentation of COMMAND (a symbol). -When called from lisp, COMMAND may also be a function object." +When called from Lisp, COMMAND may also be a function object." (interactive (help-fns--describe-function-or-command-prompt 'is-command)) (describe-function command)) @@ -723,8 +741,12 @@ FILE is the file where FUNCTION was probably defined." (add-hook 'help-fns-describe-variable-functions #'help-fns--mention-first-release) (defun help-fns--mention-first-release (object) - (let ((first (if (symbolp object) (help-fns--first-release object)))) - (when first + ;; Don't output anything if we've already output the :version from + ;; the `defcustom'. + (unless (memq 'help-fns--customize-variable-version + help-fns--activated-functions) + (when-let ((first (and (symbolp object) + (help-fns--first-release object)))) (with-current-buffer standard-output (insert (format " Probably introduced at or before Emacs version %s.\n" first)))))) @@ -801,7 +823,7 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." ;; Advised & aliased function. (and advised (symbolp real-function) (not (eq 'autoload (car-safe def)))) - (and (subrp def) + (and (subrp def) (symbolp function) (not (string= (subr-name def) (symbol-name function))))))) (real-def (cond @@ -813,6 +835,16 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." f)) ((subrp def) (intern (subr-name def))) (t def)))) + + ;; If we don't have a doc string, then try to load the file. + (when (and help-enable-symbol-autoload + (autoloadp real-def) + ;; Empty documentation slot. + (not (nth 2 real-def))) + (condition-case err + (autoload-do-load real-def) + (error (message "Error while autoloading: %S" err)))) + (list real-function def aliased real-def))) (defun help-fns-function-description-header (function) @@ -950,9 +982,9 @@ Returns a list of the form (REAL-FUNCTION DEF ALIASED REAL-DEF)." ;; E.g. an alias for a not yet defined function. ((invalid-function void-function) doc-raw)))) (help-fns--ensure-empty-line) - (run-hook-with-args 'help-fns-describe-function-functions function) - (help-fns--ensure-empty-line) - (insert (or doc "Not documented."))) + (insert (or doc "Not documented.")) + (help-fns--run-describe-functions + help-fns-describe-function-functions function)) ;; Avoid asking the user annoying questions if she decides ;; to save the help buffer, when her locale's codeset ;; isn't UTF-8. @@ -1152,7 +1184,7 @@ it is displayed along with the global value." (princ (format "Local in buffer %s; " (buffer-name buffer)))) ((terminal-live-p locus) - (princ (format "It is a terminal-local variable; "))) + (princ "It is a terminal-local variable; ")) (t (princ (format "It is local to %S" locus)))) (if (not (default-boundp variable)) @@ -1186,10 +1218,6 @@ it is displayed along with the global value." ;; of a symbol. (set-syntax-table emacs-lisp-mode-syntax-table) (goto-char val-start-pos) - ;; The line below previously read as - ;; (delete-region (point) (progn (end-of-line) (point))) - ;; which suppressed display of the buffer local value for - ;; large values. (when (looking-at "value is") (replace-match "")) (save-excursion (insert "\n\nValue:") @@ -1210,19 +1238,40 @@ it is displayed along with the global value." (documentation-property alias 'variable-documentation)))) + (with-current-buffer standard-output + (insert (or doc "Not documented as a variable."))) + + ;; Output the indented administrative bits. (with-current-buffer buffer - (run-hook-with-args 'help-fns-describe-variable-functions - variable)) + (help-fns--run-describe-functions + help-fns-describe-variable-functions variable)) (with-current-buffer standard-output - (help-fns--ensure-empty-line)) - (with-current-buffer standard-output - (insert (or doc "Not documented as a variable.")))) + ;; If we have the long value of the variable at the + ;; end, remove superfluous empty lines before it. + (unless (eobp) + (while (looking-at-p "\n") + (delete-char 1))))) (with-current-buffer standard-output ;; Return the text we displayed. (buffer-string)))))))) +(defun help-fns--run-describe-functions (functions &rest args) + (with-current-buffer standard-output + (unless (bolp) + (insert "\n")) + (help-fns--ensure-empty-line)) + (let ((help-fns--activated-functions nil)) + (dolist (func functions) + (let ((size (buffer-size standard-output))) + (apply func args) + ;; This function inserted something, so register it. + (when (> (buffer-size standard-output) size) + (push func help-fns--activated-functions))))) + (with-current-buffer standard-output + (help-fns--ensure-empty-line))) + (add-hook 'help-fns-describe-variable-functions #'help-fns--customize-variable) (defun help-fns--customize-variable (variable &optional text) ;; Make a link to customize if this variable can be customized. @@ -1234,13 +1283,15 @@ it is displayed along with the global value." (re-search-backward (concat "\\(" customize-label "\\)") nil t) (help-xref-button 1 'help-customize-variable variable))) - (terpri)) + (terpri)))) + +(add-hook 'help-fns-describe-variable-functions + #'help-fns--customize-variable-version) +(defun help-fns--customize-variable-version (variable) + (when (custom-variable-p variable) ;; Note variable's version or package version. - (let ((output (describe-variable-custom-version-info variable))) - (when output - ;; (terpri) - ;; (terpri) - (princ output))))) + (when-let ((output (describe-variable-custom-version-info variable))) + (princ output)))) (add-hook 'help-fns-describe-variable-functions #'help-fns--var-safe-local) (defun help-fns--var-safe-local (variable) @@ -1479,7 +1530,8 @@ If FRAME is omitted or nil, use the selected frame." (terpri) (terpri)))) (terpri) - (run-hook-with-args 'help-fns-describe-face-functions f frame)))))) + (help-fns--run-describe-functions + help-fns-describe-face-functions f frame)))))) (add-hook 'help-fns-describe-face-functions #'help-fns--face-custom-version-info) @@ -1509,7 +1561,7 @@ If FRAME is omitted or nil, use the selected frame." (:fontset . "Fontset") (:extend . "Extend") (:inherit . "Inherit"))) - (max-width (apply #'max (mapcar #'(lambda (x) (length (cdr x))) + (max-width (apply #'max (mapcar (lambda (x) (length (cdr x))) attrs)))) (dolist (a attrs) (let ((attr (face-attribute face (car a) frame))) @@ -1611,7 +1663,7 @@ BUFFER defaults to the current buffer." ((char-table-p value) "deeper char-table ...") (t (condition-case nil (category-set-mnemonics value) - (error "invalid")))))) + (error "Invalid")))))) ;;;###autoload (defun describe-categories (&optional buffer) |