From 31f18480ca7291070837a305c64685c3e76afde3 Mon Sep 17 00:00:00 2001 From: Jim Porter Date: Sat, 11 Mar 2023 23:51:20 -0800 Subject: [PATCH 1/3] ; Fix typo in docstring * test/lisp/eshell/em-cmpl-tests.el (em-cmpl-test/variable-assign-completion/non-assignment): Fix typo. --- test/lisp/eshell/em-cmpl-tests.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lisp/eshell/em-cmpl-tests.el b/test/lisp/eshell/em-cmpl-tests.el index b60faab9114..ea907f1945d 100644 --- a/test/lisp/eshell/em-cmpl-tests.el +++ b/test/lisp/eshell/em-cmpl-tests.el @@ -261,7 +261,7 @@ See ." "Test completion of things that look like variable assignment, but aren't. For example, the second argument in \"tar --directory=dir\" looks like it could be a variable assignment, but it's not. We should -let `pcomplete-tar' handle it instead. +let `pcomplete/tar' handle it instead. See ." (with-temp-eshell From 29227e7c19100bed30b3410b399ee6a2c1ca7213 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=ADn?= Date: Tue, 28 Feb 2023 23:15:40 +0100 Subject: [PATCH 2/3] Add functions to query Emacs Lisp examples registered in shortdoc * lisp/emacs-lisp/shortdoc.el (shortdoc--display-function): Add a new shortdoc-example text property so that ELisp examples can be searched for later. (shortdoc--insert-group-in-buffer): New function extracted from the buffer insertion code in 'shortdoc-display-group'. (shortdoc-display-group): Implement in terms of 'shortdoc--insert-group-in-buffer'. (shortdoc-function-examples): New function that returns an alist of Emacs Lisp examples from shortdoc. (shortdoc-help-fns-examples-function): New function to insert Emacs Lisp function examples in *Help* buffers, if added to 'help-fns-describe-function-functions'. * test/lisp/emacs-lisp/shortdoc-tests.el (shortdoc-function-examples-test): Test it. * doc/emacs/help.texi (Name Help): Document in the user manual. * doc/lispref/help.texi (Documentation Groups): Document it. * etc/NEWS: Advertise it. (Bug#61877) --- doc/emacs/help.texi | 9 ++ doc/lispref/help.texi | 26 ++++++ etc/NEWS | 18 ++++ lisp/emacs-lisp/shortdoc.el | 122 +++++++++++++++++-------- test/lisp/emacs-lisp/shortdoc-tests.el | 10 ++ 5 files changed, 149 insertions(+), 36 deletions(-) diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi index 2513e6be271..10c007eb635 100644 --- a/doc/emacs/help.texi +++ b/doc/emacs/help.texi @@ -316,6 +316,15 @@ there's a doc string there. by using the @kbd{M-x shortdoc} command. This will prompt you for an area of interest, e.g., @code{string}, and pop you to a buffer where many of the functions relevant for handling strings are listed. +Here's an example you can include in your initialization file +(@pxref{Init File}) that uses @code{shortdoc} to insert Emacs Lisp +function examples into regular @file{*Help*} buffers when you use +@kbd{C-h f}: + +@example +(add-hook 'help-fns-describe-function-functions + #'shortdoc-help-fns-examples-function) +@end example @kindex C-h v @findex describe-variable diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 59b6b6dab1d..3175f66122e 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -989,3 +989,29 @@ in the function group to insert the function into. If @var{group} doesn't exist, it will be created. If @var{section} doesn't exist, it will be added to the end of the function group. @end defun + +You can also query the examples of use of functions defined in +shortdoc groups. + +@defun shortdoc-function-examples function +This function returns all shortdoc examples for @var{function}. The +result is an alist with items of the form + +@example +(@var{group} . @var{examples}) +@end example + +@noindent +where @var{group} is a documentation group where @var{function} +appears in and @var{examples} is a string with the examples of use of +@var{function} defined in @var{group}. + +@code{shortdoc-function-examples} returns @code{nil} if @var{function} +is not a function or if it doesn’t contain shortdoc information. +@end defun + +@defun shortdoc-help-fns-examples-function function +This function queries the registered documentation groups and inserts +examples of use of a given Emacs Lisp function into the current +buffer. +@end defun diff --git a/etc/NEWS b/etc/NEWS index 13d073c7fb8..5f51b801774 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -220,6 +220,24 @@ asynchronously (which is the default behavior). *** New face 'doc-view-svg-face'. This replaces 'doc-view-svg-foreground' and 'doc-view-svg-background'. +** Shortdoc + ++++ +*** New function 'shortdoc-function-examples'. +This function queries the registered documentation groups and returns +examples of use of a given Emacs Lisp function. + ++++ +*** New function 'shortdoc-help-fns-examples-function'. +This function queries the registered documentation groups and inserts +examples of use of a given Emacs Lisp function into the current +buffer. If you want to insert Emacs Lisp function examples into +regular *Help* buffers when you use 'describe-function', add the +following to you init file: + + (add-hook 'help-fns-describe-function-functions + #'shortdoc-help-fns-examples-function) + * New Modes and Packages in Emacs 30.1 diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index c49960c2ee6..cf66a43fc35 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -1443,45 +1443,51 @@ If SAME-WINDOW, don't pop to a new window." (setq group (intern group))) (unless (assq group shortdoc--groups) (error "No such documentation group %s" group)) - (funcall (if same-window - #'pop-to-buffer-same-window - #'pop-to-buffer) - (format "*Shortdoc %s*" group)) - (let ((inhibit-read-only t) - (prev nil)) - (erase-buffer) - (shortdoc-mode) - (button-mode) - (mapc - (lambda (data) - (cond - ((stringp data) - (setq prev nil) - (unless (bobp) - (insert "\n")) - (insert (propertize - (substitute-command-keys data) - 'face 'shortdoc-heading - 'shortdoc-section t - 'outline-level 1)) - (insert (propertize - "\n\n" - 'face 'shortdoc-heading - 'shortdoc-section t))) - ;; There may be functions not yet defined in the data. - ((fboundp (car data)) - (when prev - (insert (make-separator-line) - ;; This helps with hidden outlines (bug#53981) - (propertize "\n" 'face '(:height 0)))) - (setq prev t) - (shortdoc--display-function data)))) - (cdr (assq group shortdoc--groups)))) + (let ((buf (get-buffer-create (format "*Shortdoc %s*" group)))) + (shortdoc--insert-group-in-buffer group buf) + (funcall (if same-window + #'pop-to-buffer-same-window + #'pop-to-buffer) + buf)) (goto-char (point-min)) (when function (text-property-search-forward 'shortdoc-function function t) (beginning-of-line))) +(defun shortdoc--insert-group-in-buffer (group &optional buf) + "Insert a short documentation summary for functions in GROUP in buffer BUF." + (with-current-buffer (or buf (current-buffer)) + (let ((inhibit-read-only t) + (prev nil)) + (erase-buffer) + (shortdoc-mode) + (button-mode) + (mapc + (lambda (data) + (cond + ((stringp data) + (setq prev nil) + (unless (bobp) + (insert "\n")) + (insert (propertize + (substitute-command-keys data) + 'face 'shortdoc-heading + 'shortdoc-section t + 'outline-level 1)) + (insert (propertize + "\n\n" + 'face 'shortdoc-heading + 'shortdoc-section t))) + ;; There may be functions not yet defined in the data. + ((fboundp (car data)) + (when prev + (insert (make-separator-line) + ;; This helps with hidden outlines (bug#53981) + (propertize "\n" 'face '(:height 0)))) + (setq prev t) + (shortdoc--display-function data)))) + (cdr (assq group shortdoc--groups)))))) + ;;;###autoload (defalias 'shortdoc #'shortdoc-display-group) @@ -1521,7 +1527,8 @@ function's documentation in the Info manual")) "=>")) (single-arrow (if (char-displayable-p ?→) "→" - "->"))) + "->")) + (start-example (point))) (cl-loop for (type value) on data by #'cddr do (cl-case type @@ -1572,7 +1579,8 @@ function's documentation in the Info manual")) (:eg-result-string (insert " e.g. " double-arrow " ") (princ value (current-buffer)) - (insert "\n"))))) + (insert "\n")))) + (add-text-properties start-example (point) `(shortdoc-example ,function))) ;; Insert the arglist after doing the evals, in case that's pulled ;; in the function definition. (save-excursion @@ -1582,6 +1590,48 @@ function's documentation in the Info manual")) (insert " " (symbol-name param))) (add-face-text-property arglist-start (point) 'shortdoc-section t)))) +(defun shortdoc-function-examples (function) + "Return all shortdoc examples for FUNCTION. +The result is an alist with items of the form (GROUP . EXAMPLES), +where GROUP is a shortdoc group where FUNCTION appears in and +EXAMPLES is a string with the usage examples of FUNCTION defined +in GROUP. Return nil if FUNCTION is not a function or if it +doesn't contain shortdoc information." + (let ((groups (and (symbolp function) + (shortdoc-function-groups function))) + (examples nil)) + (mapc + (lambda (group) + (with-temp-buffer + (shortdoc--insert-group-in-buffer group) + (goto-char (point-min)) + (setq match (text-property-search-forward + 'shortdoc-example function t)) + (push `(,group . ,(string-trim + (buffer-substring-no-properties + (prop-match-beginning match) + (prop-match-end match)))) + examples))) + groups) + examples)) + +(defun shortdoc-help-fns-examples-function (function) + "Insert Emacs Lisp examples for FUNCTION into the current buffer. +You can add this function to the +`help-fns-describe-function-functions' list to show function +example documentation in *Help* buffers." + (let ((examples (shortdoc-function-examples function)) + (times 0)) + (dolist (example examples) + (when (zerop times) + (if (eq (length examples) 1) + (insert " Example:\n\n") + (insert " Examples:\n\n"))) + (setq times (1+ times)) + (insert " ") + (insert (cdr example)) + (insert "\n\n")))) + (defun shortdoc-function-groups (function) "Return all shortdoc groups FUNCTION appears in." (cl-loop for group in shortdoc--groups diff --git a/test/lisp/emacs-lisp/shortdoc-tests.el b/test/lisp/emacs-lisp/shortdoc-tests.el index 516d095767f..a65a4a5ddc3 100644 --- a/test/lisp/emacs-lisp/shortdoc-tests.el +++ b/test/lisp/emacs-lisp/shortdoc-tests.el @@ -65,6 +65,16 @@ (when buf (kill-buffer buf)))))) +(ert-deftest shortdoc-function-examples-test () + "Test the extraction of usage examples of some Elisp functions." + (should (equal '((list . "(delete 2 (list 1 2 3 4))\n => (1 3 4)\n (delete \"a\" (list \"a\" \"b\" \"c\" \"d\"))\n => (\"b\" \"c\" \"d\")")) + (shortdoc-function-examples 'delete))) + (should (equal '((alist . "(assq 'foo '((foo . bar) (zot . baz)))\n => (foo . bar)") + (list . "(assq 'b '((a . 1) (b . 2)))\n => (b . 2)")) + (shortdoc-function-examples 'assq))) + (should (equal '((regexp . "(string-match-p \"^[fo]+\" \"foobar\")\n => 0")) + (shortdoc-function-examples 'string-match-p)))) + (provide 'shortdoc-tests) ;;; shortdoc-tests.el ends here From 9191fd50d242cde5256b876dd756ffbc6f46db90 Mon Sep 17 00:00:00 2001 From: Eli Zaretskii Date: Sun, 12 Mar 2023 10:25:10 +0200 Subject: [PATCH 3/3] ; Fix last change * lisp/emacs-lisp/shortdoc.el (shortdoc-help-fns-examples-function) (shortdoc-function-examples): Fix compilation warning and add an empty line before the examples. * lisp/emacs-lisp/shortdoc.el (shortdoc--insert-group-in-buffer) (shortdoc-function-examples) (shortdoc-help-fns-examples-function): * etc/NEWS: * doc/lispref/help.texi (Documentation Groups): * doc/emacs/help.texi (Name Help): Improve documentation of the last change. (Bug#61877) --- doc/emacs/help.texi | 9 +++++---- doc/lispref/help.texi | 28 ++++++++++++++-------------- etc/NEWS | 12 ++++++------ lisp/emacs-lisp/shortdoc.el | 31 ++++++++++++++++--------------- 4 files changed, 41 insertions(+), 39 deletions(-) diff --git a/doc/emacs/help.texi b/doc/emacs/help.texi index 10c007eb635..945e12a05d2 100644 --- a/doc/emacs/help.texi +++ b/doc/emacs/help.texi @@ -316,10 +316,11 @@ there's a doc string there. by using the @kbd{M-x shortdoc} command. This will prompt you for an area of interest, e.g., @code{string}, and pop you to a buffer where many of the functions relevant for handling strings are listed. -Here's an example you can include in your initialization file -(@pxref{Init File}) that uses @code{shortdoc} to insert Emacs Lisp -function examples into regular @file{*Help*} buffers when you use -@kbd{C-h f}: + +You can also request that documentation of functions and commands +shown in @file{*Help*} buffers popped by @kbd{C-h f} includes examples +of their use. To that end, add the following to your initialization +file (@pxref{Init File}): @example (add-hook 'help-fns-describe-function-functions diff --git a/doc/lispref/help.texi b/doc/lispref/help.texi index 3175f66122e..d5e4e1c31d3 100644 --- a/doc/lispref/help.texi +++ b/doc/lispref/help.texi @@ -995,23 +995,23 @@ shortdoc groups. @defun shortdoc-function-examples function This function returns all shortdoc examples for @var{function}. The -result is an alist with items of the form - -@example -(@var{group} . @var{examples}) -@end example - -@noindent -where @var{group} is a documentation group where @var{function} -appears in and @var{examples} is a string with the examples of use of -@var{function} defined in @var{group}. +return value is an alist with items of the form +@w{@code{(@var{group} . @var{examples})}}, where @var{group} is a +documentation group where @var{function} appears, and @var{examples} +is a string with the examples of @var{function}s use as defined in +@var{group}. @code{shortdoc-function-examples} returns @code{nil} if @var{function} -is not a function or if it doesn’t contain shortdoc information. +is not a function or if it doesn't have any shortdoc examples. @end defun +@vindex help-fns-describe-function-functions @defun shortdoc-help-fns-examples-function function -This function queries the registered documentation groups and inserts -examples of use of a given Emacs Lisp function into the current -buffer. +This function queries the registered shortdoc groups and inserts +examples of use of a given Emacs Lisp @var{function} into the current +buffer. It is suitable for addition to the +@code{help-fns-describe-function-functions} hook, in which case +examples from shortdoc of using a function will be displayed in the +@file{*Help*} buffer when the documentation of the function is +requested. @end defun diff --git a/etc/NEWS b/etc/NEWS index 5f51b801774..e43aac614c9 100644 --- a/etc/NEWS +++ b/etc/NEWS @@ -224,15 +224,15 @@ This replaces 'doc-view-svg-foreground' and 'doc-view-svg-background'. +++ *** New function 'shortdoc-function-examples'. -This function queries the registered documentation groups and returns -examples of use of a given Emacs Lisp function. +This function returns examples of use of a given Emacs Lisp function +from the available shortdoc information. +++ *** New function 'shortdoc-help-fns-examples-function'. -This function queries the registered documentation groups and inserts -examples of use of a given Emacs Lisp function into the current -buffer. If you want to insert Emacs Lisp function examples into -regular *Help* buffers when you use 'describe-function', add the +This function inserts into the current buffer examples of use of a +given Emacs Lisp function, which it gleans from the shortdoc +information. If you want 'describe-function' ('C-h f') to insert +examples of using the function into regular *Help* buffers, add the following to you init file: (add-hook 'help-fns-describe-function-functions diff --git a/lisp/emacs-lisp/shortdoc.el b/lisp/emacs-lisp/shortdoc.el index cf66a43fc35..6e3ebc7c6a2 100644 --- a/lisp/emacs-lisp/shortdoc.el +++ b/lisp/emacs-lisp/shortdoc.el @@ -1455,7 +1455,8 @@ If SAME-WINDOW, don't pop to a new window." (beginning-of-line))) (defun shortdoc--insert-group-in-buffer (group &optional buf) - "Insert a short documentation summary for functions in GROUP in buffer BUF." + "Insert a short documentation summary for functions in GROUP in buffer BUF. +BUF defaults to the current buffer if nil or omitted." (with-current-buffer (or buf (current-buffer)) (let ((inhibit-read-only t) (prev nil)) @@ -1593,10 +1594,10 @@ function's documentation in the Info manual")) (defun shortdoc-function-examples (function) "Return all shortdoc examples for FUNCTION. The result is an alist with items of the form (GROUP . EXAMPLES), -where GROUP is a shortdoc group where FUNCTION appears in and +where GROUP is a shortdoc group where FUNCTION appears, and EXAMPLES is a string with the usage examples of FUNCTION defined in GROUP. Return nil if FUNCTION is not a function or if it -doesn't contain shortdoc information." +doesn't has any shortdoc information." (let ((groups (and (symbolp function) (shortdoc-function-groups function))) (examples nil)) @@ -1605,28 +1606,28 @@ doesn't contain shortdoc information." (with-temp-buffer (shortdoc--insert-group-in-buffer group) (goto-char (point-min)) - (setq match (text-property-search-forward - 'shortdoc-example function t)) - (push `(,group . ,(string-trim - (buffer-substring-no-properties - (prop-match-beginning match) - (prop-match-end match)))) - examples))) + (let ((match (text-property-search-forward + 'shortdoc-example function t))) + (push `(,group . ,(string-trim + (buffer-substring-no-properties + (prop-match-beginning match) + (prop-match-end match)))) + examples)))) groups) examples)) (defun shortdoc-help-fns-examples-function (function) "Insert Emacs Lisp examples for FUNCTION into the current buffer. -You can add this function to the -`help-fns-describe-function-functions' list to show function -example documentation in *Help* buffers." +You can add this function to the `help-fns-describe-function-functions' +hook to show examples of using FUNCTION in *Help* buffers produced +by \\[describe-function]." (let ((examples (shortdoc-function-examples function)) (times 0)) (dolist (example examples) (when (zerop times) (if (eq (length examples) 1) - (insert " Example:\n\n") - (insert " Examples:\n\n"))) + (insert "\n Example:\n\n") + (insert "\n Examples:\n\n"))) (setq times (1+ times)) (insert " ") (insert (cdr example))