aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Martín2023-02-28 23:15:40 +0100
committerEli Zaretskii2023-03-12 09:54:06 +0200
commit29227e7c19100bed30b3410b399ee6a2c1ca7213 (patch)
tree4cfde01d3e6841d9ea54194c1e3bb785d464c8b7
parent31f18480ca7291070837a305c64685c3e76afde3 (diff)
downloademacs-29227e7c19100bed30b3410b399ee6a2c1ca7213.tar.gz
emacs-29227e7c19100bed30b3410b399ee6a2c1ca7213.zip
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)
-rw-r--r--doc/emacs/help.texi9
-rw-r--r--doc/lispref/help.texi26
-rw-r--r--etc/NEWS18
-rw-r--r--lisp/emacs-lisp/shortdoc.el122
-rw-r--r--test/lisp/emacs-lisp/shortdoc-tests.el10
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.
316by using the @kbd{M-x shortdoc} command. This will prompt you for an 316by using the @kbd{M-x shortdoc} command. This will prompt you for an
317area of interest, e.g., @code{string}, and pop you to a buffer where 317area of interest, e.g., @code{string}, and pop you to a buffer where
318many of the functions relevant for handling strings are listed. 318many of the functions relevant for handling strings are listed.
319Here's an example you can include in your initialization file
320(@pxref{Init File}) that uses @code{shortdoc} to insert Emacs Lisp
321function examples into regular @file{*Help*} buffers when you use
322@kbd{C-h f}:
323
324@example
325(add-hook 'help-fns-describe-function-functions
326 #'shortdoc-help-fns-examples-function)
327@end example
319 328
320@kindex C-h v 329@kindex C-h v
321@findex describe-variable 330@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.
989If @var{group} doesn't exist, it will be created. If @var{section} 989If @var{group} doesn't exist, it will be created. If @var{section}
990doesn't exist, it will be added to the end of the function group. 990doesn't exist, it will be added to the end of the function group.
991@end defun 991@end defun
992
993You can also query the examples of use of functions defined in
994shortdoc groups.
995
996@defun shortdoc-function-examples function
997This function returns all shortdoc examples for @var{function}. The
998result is an alist with items of the form
999
1000@example
1001(@var{group} . @var{examples})
1002@end example
1003
1004@noindent
1005where @var{group} is a documentation group where @var{function}
1006appears in and @var{examples} is a string with the examples of use of
1007@var{function} defined in @var{group}.
1008
1009@code{shortdoc-function-examples} returns @code{nil} if @var{function}
1010is not a function or if it doesn’t contain shortdoc information.
1011@end defun
1012
1013@defun shortdoc-help-fns-examples-function function
1014This function queries the registered documentation groups and inserts
1015examples of use of a given Emacs Lisp function into the current
1016buffer.
1017@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).
220*** New face 'doc-view-svg-face'. 220*** New face 'doc-view-svg-face'.
221This replaces 'doc-view-svg-foreground' and 'doc-view-svg-background'. 221This replaces 'doc-view-svg-foreground' and 'doc-view-svg-background'.
222 222
223** Shortdoc
224
225+++
226*** New function 'shortdoc-function-examples'.
227This function queries the registered documentation groups and returns
228examples of use of a given Emacs Lisp function.
229
230+++
231*** New function 'shortdoc-help-fns-examples-function'.
232This function queries the registered documentation groups and inserts
233examples of use of a given Emacs Lisp function into the current
234buffer. If you want to insert Emacs Lisp function examples into
235regular *Help* buffers when you use 'describe-function', add the
236following to you init file:
237
238 (add-hook 'help-fns-describe-function-functions
239 #'shortdoc-help-fns-examples-function)
240
223 241
224* New Modes and Packages in Emacs 30.1 242* New Modes and Packages in Emacs 30.1
225 243
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."
1443 (setq group (intern group))) 1443 (setq group (intern group)))
1444 (unless (assq group shortdoc--groups) 1444 (unless (assq group shortdoc--groups)
1445 (error "No such documentation group %s" group)) 1445 (error "No such documentation group %s" group))
1446 (funcall (if same-window 1446 (let ((buf (get-buffer-create (format "*Shortdoc %s*" group))))
1447 #'pop-to-buffer-same-window 1447 (shortdoc--insert-group-in-buffer group buf)
1448 #'pop-to-buffer) 1448 (funcall (if same-window
1449 (format "*Shortdoc %s*" group)) 1449 #'pop-to-buffer-same-window
1450 (let ((inhibit-read-only t) 1450 #'pop-to-buffer)
1451 (prev nil)) 1451 buf))
1452 (erase-buffer)
1453 (shortdoc-mode)
1454 (button-mode)
1455 (mapc
1456 (lambda (data)
1457 (cond
1458 ((stringp data)
1459 (setq prev nil)
1460 (unless (bobp)
1461 (insert "\n"))
1462 (insert (propertize
1463 (substitute-command-keys data)
1464 'face 'shortdoc-heading
1465 'shortdoc-section t
1466 'outline-level 1))
1467 (insert (propertize
1468 "\n\n"
1469 'face 'shortdoc-heading
1470 'shortdoc-section t)))
1471 ;; There may be functions not yet defined in the data.
1472 ((fboundp (car data))
1473 (when prev
1474 (insert (make-separator-line)
1475 ;; This helps with hidden outlines (bug#53981)
1476 (propertize "\n" 'face '(:height 0))))
1477 (setq prev t)
1478 (shortdoc--display-function data))))
1479 (cdr (assq group shortdoc--groups))))
1480 (goto-char (point-min)) 1452 (goto-char (point-min))
1481 (when function 1453 (when function
1482 (text-property-search-forward 'shortdoc-function function t) 1454 (text-property-search-forward 'shortdoc-function function t)
1483 (beginning-of-line))) 1455 (beginning-of-line)))
1484 1456
1457(defun shortdoc--insert-group-in-buffer (group &optional buf)
1458 "Insert a short documentation summary for functions in GROUP in buffer BUF."
1459 (with-current-buffer (or buf (current-buffer))
1460 (let ((inhibit-read-only t)
1461 (prev nil))
1462 (erase-buffer)
1463 (shortdoc-mode)
1464 (button-mode)
1465 (mapc
1466 (lambda (data)
1467 (cond
1468 ((stringp data)
1469 (setq prev nil)
1470 (unless (bobp)
1471 (insert "\n"))
1472 (insert (propertize
1473 (substitute-command-keys data)
1474 'face 'shortdoc-heading
1475 'shortdoc-section t
1476 'outline-level 1))
1477 (insert (propertize
1478 "\n\n"
1479 'face 'shortdoc-heading
1480 'shortdoc-section t)))
1481 ;; There may be functions not yet defined in the data.
1482 ((fboundp (car data))
1483 (when prev
1484 (insert (make-separator-line)
1485 ;; This helps with hidden outlines (bug#53981)
1486 (propertize "\n" 'face '(:height 0))))
1487 (setq prev t)
1488 (shortdoc--display-function data))))
1489 (cdr (assq group shortdoc--groups))))))
1490
1485;;;###autoload 1491;;;###autoload
1486(defalias 'shortdoc #'shortdoc-display-group) 1492(defalias 'shortdoc #'shortdoc-display-group)
1487 1493
@@ -1521,7 +1527,8 @@ function's documentation in the Info manual"))
1521 "=>")) 1527 "=>"))
1522 (single-arrow (if (char-displayable-p ?→) 1528 (single-arrow (if (char-displayable-p ?→)
1523 "→" 1529 "→"
1524 "->"))) 1530 "->"))
1531 (start-example (point)))
1525 (cl-loop for (type value) on data by #'cddr 1532 (cl-loop for (type value) on data by #'cddr
1526 do 1533 do
1527 (cl-case type 1534 (cl-case type
@@ -1572,7 +1579,8 @@ function's documentation in the Info manual"))
1572 (:eg-result-string 1579 (:eg-result-string
1573 (insert " e.g. " double-arrow " ") 1580 (insert " e.g. " double-arrow " ")
1574 (princ value (current-buffer)) 1581 (princ value (current-buffer))
1575 (insert "\n"))))) 1582 (insert "\n"))))
1583 (add-text-properties start-example (point) `(shortdoc-example ,function)))
1576 ;; Insert the arglist after doing the evals, in case that's pulled 1584 ;; Insert the arglist after doing the evals, in case that's pulled
1577 ;; in the function definition. 1585 ;; in the function definition.
1578 (save-excursion 1586 (save-excursion
@@ -1582,6 +1590,48 @@ function's documentation in the Info manual"))
1582 (insert " " (symbol-name param))) 1590 (insert " " (symbol-name param)))
1583 (add-face-text-property arglist-start (point) 'shortdoc-section t)))) 1591 (add-face-text-property arglist-start (point) 'shortdoc-section t))))
1584 1592
1593(defun shortdoc-function-examples (function)
1594 "Return all shortdoc examples for FUNCTION.
1595The result is an alist with items of the form (GROUP . EXAMPLES),
1596where GROUP is a shortdoc group where FUNCTION appears in and
1597EXAMPLES is a string with the usage examples of FUNCTION defined
1598in GROUP. Return nil if FUNCTION is not a function or if it
1599doesn't contain shortdoc information."
1600 (let ((groups (and (symbolp function)
1601 (shortdoc-function-groups function)))
1602 (examples nil))
1603 (mapc
1604 (lambda (group)
1605 (with-temp-buffer
1606 (shortdoc--insert-group-in-buffer group)
1607 (goto-char (point-min))
1608 (setq match (text-property-search-forward
1609 'shortdoc-example function t))
1610 (push `(,group . ,(string-trim
1611 (buffer-substring-no-properties
1612 (prop-match-beginning match)
1613 (prop-match-end match))))
1614 examples)))
1615 groups)
1616 examples))
1617
1618(defun shortdoc-help-fns-examples-function (function)
1619 "Insert Emacs Lisp examples for FUNCTION into the current buffer.
1620You can add this function to the
1621`help-fns-describe-function-functions' list to show function
1622example documentation in *Help* buffers."
1623 (let ((examples (shortdoc-function-examples function))
1624 (times 0))
1625 (dolist (example examples)
1626 (when (zerop times)
1627 (if (eq (length examples) 1)
1628 (insert " Example:\n\n")
1629 (insert " Examples:\n\n")))
1630 (setq times (1+ times))
1631 (insert " ")
1632 (insert (cdr example))
1633 (insert "\n\n"))))
1634
1585(defun shortdoc-function-groups (function) 1635(defun shortdoc-function-groups (function)
1586 "Return all shortdoc groups FUNCTION appears in." 1636 "Return all shortdoc groups FUNCTION appears in."
1587 (cl-loop for group in shortdoc--groups 1637 (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 @@
65 (when buf 65 (when buf
66 (kill-buffer buf)))))) 66 (kill-buffer buf))))))
67 67
68(ert-deftest shortdoc-function-examples-test ()
69 "Test the extraction of usage examples of some Elisp functions."
70 (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\")"))
71 (shortdoc-function-examples 'delete)))
72 (should (equal '((alist . "(assq 'foo '((foo . bar) (zot . baz)))\n => (foo . bar)")
73 (list . "(assq 'b '((a . 1) (b . 2)))\n => (b . 2)"))
74 (shortdoc-function-examples 'assq)))
75 (should (equal '((regexp . "(string-match-p \"^[fo]+\" \"foobar\")\n => 0"))
76 (shortdoc-function-examples 'string-match-p))))
77
68(provide 'shortdoc-tests) 78(provide 'shortdoc-tests)
69 79
70;;; shortdoc-tests.el ends here 80;;; shortdoc-tests.el ends here