]> git.eshelyaron.com Git - emacs.git/commitdiff
Add functions to query Emacs Lisp examples registered in shortdoc
authorDaniel Martín <mardani29@yahoo.es>
Tue, 28 Feb 2023 22:15:40 +0000 (23:15 +0100)
committerEli Zaretskii <eliz@gnu.org>
Sun, 12 Mar 2023 07:54:06 +0000 (09:54 +0200)
* 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
doc/lispref/help.texi
etc/NEWS
lisp/emacs-lisp/shortdoc.el
test/lisp/emacs-lisp/shortdoc-tests.el

index 2513e6be271bee1a5cb0a4da1585d5af04bb2738..10c007eb63595b3bfdcf25ede829f59da15c1da0 100644 (file)
@@ -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
index 59b6b6dab1d766495a809f98fe94bb4c0bfb21a0..3175f66122e43312ab2bc4a7ccea501daf23a547 100644 (file)
@@ -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
index 13d073c7fb8c56a0bf83782ef8d5b70857e8fa51..5f51b801774f81f81444c552e420ed73dd3b1a94 100644 (file)
--- 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)
+
 \f
 * New Modes and Packages in Emacs 30.1
 
index c49960c2ee6f816441448b6db9ac14afa5d911e7..cf66a43fc357647626be07f970f8d6b349de1ed2 100644 (file)
@@ -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
index 516d095767f103a9f08053550d3963671edc2669..a65a4a5ddc3b4e2915bfccfe170e736a96bbaa51 100644 (file)
         (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