diff --git a/doc/generate.el b/doc/generate.el index 2b0357e7..88ce5719 100644 --- a/doc/generate.el +++ b/doc/generate.el @@ -1,6 +1,6 @@ ;;; generate.el -*- lexical-binding: t -*- -;; Copyright (c) 2013-2022 by Greg Hendershott. +;; Copyright (c) 2013-2024 by Greg Hendershott. ;; SPDX-License-Identifier: GPL-3.0-or-later ;;; Generate a reference.org file from doc strings @@ -10,7 +10,8 @@ ;; Info and HTML format documentation. ;; ;; Note that this file is /not/ loaded when running Racket Mode -- -;; just used as part of the build process. +;; just used as part of the build process, when we run Emacs in batch +;; mode. As a result we don't bother with namespace prefixes. (require 'racket-mode) (require 'racket-debug) @@ -29,15 +30,18 @@ (defun racket-generate-reference.org () (find-file "reference.org") (delete-region (point-min) (point-max)) - (insert (racket-generate--commands)) - (insert (racket-generate--variables)) - (insert (racket-generate--configuration-functions)) - (insert (racket-generate--faces)) + (insert-org-contents) (save-buffer 0)) ;don't create reference.org~ backup +(defun insert-org-contents () + (insert-commands) + (insert-variables) + (insert-configuration-functions) + (insert-faces)) + ;;; Interactive command functions -(defconst racket-generate--commands +(defconst the-commands `("Edit" racket-mode racket-insert-lambda @@ -123,37 +127,35 @@ racket-mode-start-slower) "Commands to include in the Reference.") -(defun racket-generate--commands () - (apply - #'concat - "* Commands\n\n" - (mapcar (lambda (s) - (pcase s - ((and str (pred stringp)) - (format "** %s\n\n" s)) - ((and sym (pred symbolp)) - (racket-generate--command-or-function sym racket-mode-map)) - (`(,sym ,keymap) - (racket-generate--command-or-function sym keymap)))) - racket-generate--commands))) +(defun insert-commands () + (insert "* Commands\n\n") + (dolist (s the-commands) + (pcase s + ((and str (pred stringp)) + (insert (format "** %s\n\n" str))) + ((and sym (pred symbolp)) + (insert-command-or-function sym racket-mode-map)) + (`(,sym ,keymap) + (insert-command-or-function sym keymap))))) -(defun racket-generate--command-or-function (sym keymap) +(defun insert-command-or-function (sym keymap) (unless (fboundp sym) (error "not defined %s" sym)) - (concat (format "*** %s\n" sym) + (insert (format "*** %s\n" sym) (if keymap - (when (interactive-form sym) - (racket-generate--bindings-as-kbd sym keymap)) + (if (interactive-form sym) + (bindings-as-kbd sym keymap) + "") (format "~%s~\n" (cons sym (help-function-arglist sym)))) "\n\n" - (racket-generate--format-doc-string + (format-doc-string (or (documentation sym t) "No documentation.\n\n")) "\n\n")) ;;; Configuration functions -(defconst racket-generate--configuration-functions +(defconst the-functions `("Showing information" racket-show-pseudo-tooltip racket-show-echo-area @@ -175,21 +177,18 @@ racket-vterm) "Configuration functions to include in the Reference.") -(defun racket-generate--configuration-functions () - (apply - #'concat - "* Configuration functions\n\n" - (mapcar (lambda (s) - (pcase s - ((and str (pred stringp)) - (format "** %s\n\n" s)) - ((and sym (pred symbolp)) - (racket-generate--command-or-function sym nil)))) - racket-generate--configuration-functions))) +(defun insert-configuration-functions () + (insert "* Configuration functions\n\n") + (dolist (s the-functions) + (pcase s + ((and str (pred stringp)) + (insert (format "** %s\n\n" str))) + ((and sym (pred symbolp)) + (insert-command-or-function sym nil))))) ;;; Variables -(defconst racket-generate--variables +(defconst the-variables '("General variables" racket-program racket-command-timeout @@ -241,30 +240,27 @@ racket-input-translations) "Variables to include in the Reference.") -(defun racket-generate--variables () - (apply - #'concat - "* Variables\n\n" - (mapcar (lambda (s) - (if (stringp s) - (format "** %s\n\n" s) - (unless (boundp s) - (error "variable does not exist: %s" s)) - (concat - (format "*** %s\n" s) - (racket-generate--format-doc-string - (or (documentation-property s 'variable-documentation t) - ;; Do check for function documentation here, - ;; to support documenting values for - ;; `-functions' variables. - (documentation s t) - "No documentation.\n\n")) - "\n\n"))) - racket-generate--variables))) +(defun insert-variables () + (insert "* Variables\n\n") + (dolist (s the-variables) + (if (stringp s) + (insert (format "** %s\n\n" s)) + (unless (boundp s) + (error "variable does not exist: %s" s)) + (insert + (format "*** %s\n" s) + (format-doc-string + (or (documentation-property s 'variable-documentation t) + ;; Do check for function documentation here, + ;; to support documenting values for + ;; `-functions' variables. + (documentation s t) + "No documentation.\n\n")) + "\n\n")))) ;;; Faces -(defconst racket-generate--faces +(defconst the-faces '(racket-keyword-argument-face racket-reader-quoted-symbol-face racket-reader-syntax-quoted-symbol-face @@ -301,23 +297,20 @@ racket-hash-lang-text) "Faces to include in the Reference.") -(defun racket-generate--faces () - (apply - #'concat - "* Faces\n\n" - "** All\n\n" - (mapcar (lambda (symbol) - (concat - (format "*** %s\n" symbol) - (racket-generate--format-doc-string - (or (documentation-property symbol 'face-documentation t) - "No documentation.\n\n")) - "\n\n")) - racket-generate--faces))) +(defun insert-faces () + (insert "* Faces\n\n" + "** All\n\n") + (dolist (s the-faces) + (insert + (format "*** %s\n" s) + (format-doc-string + (or (documentation-property s 'face-documentation t) + "No documentation.\n\n")) + "\n\n"))) ;;; Utility -(defun racket-generate--format-doc-string (docstring) +(defun format-doc-string (docstring) "Convert command key references and keymap references in DOCSTRING to buttons. @@ -344,7 +337,7 @@ unescaping too." (name (match-string-no-properties 1)) (sym (intern-soft name))) (delete-region (point) (+ (point) len)) - (insert (racket-generate--ref-or-code sym)))) + (insert (ref-or-code sym)))) ((looking-at ;; Text of the form `contents' or `contents` (rx "`" (group (+ (not (in "`'")))) (in "`'"))) @@ -372,7 +365,7 @@ unescaping too." ;; Insert an org-mode table (when km (insert "|Key|Binding|\n") - (racket-generate--insert-keymap km) + (insert-keymap km) (newline)))) ((looking-at ;; Text of the form \\[foo-command] @@ -384,13 +377,13 @@ unescaping too." (insert (if (string-equal name "universal-argument") "{{{kbd(C-u)}}}" - (racket-generate--bindings-as-kbd (intern-soft name) keymap))))) + (bindings-as-kbd (intern-soft name) keymap))))) ;; Don't modify other characters. (t (forward-char 1)))) (buffer-string)))) -(defun racket-generate--insert-keymap (km) +(defun insert-keymap (km) "Insert org table describing keymap KM. Filter \"noise\" like bindings for `negative-argument' and @@ -428,16 +421,16 @@ table, sorted shortest first." (dolist (v (seq-sort-by (lambda (v) (symbol-name (car v))) #'string< alist)) - (let* ((command-str (racket-generate--ref-or-code (car v))) + (let* ((command-str (ref-or-code (car v))) (keys-strs (seq-map (lambda (binding) (format "{{{kbd(%s)}}}" - (racket-generate--key-description binding))) + (escaped-key-description binding))) (cdr v))) (keys-str (string-join (seq-sort-by #'length #'< keys-strs) - ", "))) + " or "))) (insert "|" keys-str "|" command-str "|\n")))))) -(defun racket-generate--key-description (xs) +(defun escaped-key-description (xs) "Like `key-description' but escapes some chars for our \"KBD\" texi macro." (with-temp-buffer (insert (key-description xs)) @@ -449,38 +442,38 @@ table, sorted shortest first." (insert str))) (buffer-string))) -(defun racket-generate--bindings-as-kbd (symbol keymap) - (let* ((bindings (or (racket-generate--where-is/no-menu symbol keymap) - (racket-generate--where-is/no-menu symbol racket-mode-map))) +(defun bindings-as-kbd (symbol keymap) + (let* ((bindings (or (where-is/no-menu symbol keymap) + (where-is/no-menu symbol racket-mode-map))) (strs (and bindings (seq-filter #'identity (mapcar (lambda (binding) - (let ((desc (racket-generate--key-description binding))) + (let ((desc (escaped-key-description binding))) ;; I don't know how to escape { or } ;; for texi (unless (string-match-p "[{}]" desc) (format "{{{kbd(%s)}}}" desc)))) bindings))))) (if strs - (string-join strs " or ") + (string-join strs "or ") (format "{{{kbd(M-x)}}} ~%s~" symbol)))) -(defun racket-generate--where-is/no-menu (symbol keymap) +(defun where-is/no-menu (symbol keymap) (seq-filter (lambda (binding) (not (eq (aref binding 0) 'menu-bar))) (where-is-internal symbol keymap))) -(defun racket-generate--ref-or-code (sym) +(defun ref-or-code (sym) "Return either a reference or code formatting for SYM." (if (or (seq-some (lambda (v) (or (eq v sym) (and (listp v) (eq (car v) sym)))) - racket-generate--commands) - (member sym racket-generate--configuration-functions) - (member sym racket-generate--variables) - (member sym racket-generate--faces)) + the-commands) + (member sym the-functions) + (member sym the-variables) + (member sym the-faces)) (format "@@texinfo:@ref{%s}@@" sym) (format "~%s~" sym))) diff --git a/doc/racket-mode.texi b/doc/racket-mode.texi index 38aa5877..de1e345c 100644 --- a/doc/racket-mode.texi +++ b/doc/racket-mode.texi @@ -972,7 +972,7 @@ You can also view these by using the normal Emacs help mechanism: Major mode for editing Racket source files. -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} +@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} @item Key @tab Binding @item @kbd{TAB} @@ -981,7 +981,7 @@ Major mode for editing Racket source files. @tab @ref{racket-backward-up-list} @item @kbd{C-c C-p} @tab @ref{racket-cycle-paren-shapes} -@item @kbd{C-c C-s} , @kbd{C-c C-.} +@item @kbd{C-c C-s} or @kbd{C-c C-.} @tab @ref{racket-describe-search} @item @kbd{C-c C-d} @tab @ref{racket-documentation-search} @@ -997,7 +997,7 @@ Major mode for editing Racket source files. @tab @ref{racket-expand-region} @item @kbd{C-c C-f} @tab @ref{racket-fold-all-tests} -@item @kbd{)} , @kbd{]} , @kbd{@}} +@item @kbd{)} or @kbd{]} or @kbd{@}} @tab @ref{racket-insert-closing} @item @kbd{C-M-y} @tab @ref{racket-insert-lambda} @@ -1007,7 +1007,7 @@ Major mode for editing Racket source files. @tab @ref{racket-open-require-path} @item @kbd{C-c C-o} @tab @ref{racket-profile} -@item @kbd{C-c C-c} , @kbd{C-c C-k} +@item @kbd{C-c C-c} or @kbd{C-c C-k} @tab @ref{racket-run-module-at-point} @item @kbd{C-M-x} @tab @ref{racket-send-definition} @@ -1374,7 +1374,7 @@ it is disabled. @node racket-insert-closing @subsection racket-insert-closing -@kbd{]} or @kbd{)} +@kbd{]} or @kbd{)} Insert a matching closing delimiter. @@ -1582,7 +1582,7 @@ A discussion of the information provided by a Racket language: @uref{https://docs.racket-lang.org/tools/lang-languages-customization.html} -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} +@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} @item Key @tab Binding @item @kbd{TAB} @@ -1621,7 +1621,7 @@ A discussion of the information provided by a Racket language: @tab @ref{racket-open-require-path} @item @kbd{C-c C-o} @tab @ref{racket-profile} -@item @kbd{C-c C-c} , @kbd{C-c C-k} +@item @kbd{C-c C-c} or @kbd{C-c C-k} @tab @ref{racket-run-module-at-point} @item @kbd{C-M-x} @tab @ref{racket-send-definition} @@ -1880,7 +1880,7 @@ type, remember that as an Emacs user, you are free to bind this map to a more convenient prefix, and/or bind any individual commands directly to whatever keys you prefer. -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} +@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} @item Key @tab Binding @item @kbd{C-c # N} @@ -1913,7 +1913,7 @@ commands directly to whatever keys you prefer. @tab @ref{racket-xp-tail-previous-sibling} @item @kbd{C-c # ^} @tab @ref{racket-xp-tail-up} -@item @kbd{M-.} , @kbd{C-c # .} +@item @kbd{M-.} or @kbd{C-c # .} @tab @code{xref-find-definitions} @item @kbd{C-c # ?} @tab @code{xref-find-references} @@ -2151,7 +2151,7 @@ External links -- which are opened using the variable @ref{racket-browse-url-function}, by default in an external web browser program -- are given @ref{racket-ext-link-face}. -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} +@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} @item Key @tab Binding @item @kbd{<} @@ -2160,11 +2160,11 @@ browser program -- are given @ref{racket-ext-link-face}. @tab @code{end-of-buffer} @item @kbd{q} @tab @code{quit-window} -@item @kbd{l} , @kbd{b} , @kbd{C-c C-b} +@item @kbd{l} or @kbd{b} or @kbd{C-c C-b} @tab @code{racket-describe-back} @item @kbd{x} @tab @code{racket-describe-browse-external} -@item @kbd{r} , @kbd{f} , @kbd{C-c C-f} +@item @kbd{r} or @kbd{f} or @kbd{C-c C-f} @tab @code{racket-describe-forward} @item @kbd{n} @tab @code{racket-describe-nav-next} @@ -2174,11 +2174,11 @@ browser program -- are given @ref{racket-ext-link-face}. @tab @code{racket-describe-nav-top} @item @kbd{^} @tab @code{racket-describe-nav-up} -@item @kbd{i} , @kbd{C-c C-s} +@item @kbd{i} or @kbd{C-c C-s} @tab @ref{racket-describe-search} @item @kbd{g} @tab @code{revert-buffer} -@item @kbd{DEL} , @kbd{S-SPC} +@item @kbd{DEL} or @kbd{S-SPC} @tab @code{scroll-down-command} @item @kbd{SPC} @tab @code{scroll-up-command} @@ -2193,7 +2193,7 @@ or penultimate step during initialization. @node racket-describe-search @subsection racket-describe-search -@kbd{C-c C-.} or @kbd{C-c C-s} +@kbd{C-c C-.} or @kbd{C-c C-s} Search installed documentation; view using @ref{racket-describe-mode}. @@ -2231,7 +2231,7 @@ You may use @code{xref-find-definitions} @kbd{M-.} and @code{xref-backend-functions}. This backend uses information about identifier bindings and modules from the REPL's namespace. -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} +@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} @item Key @tab Binding @item @kbd{TAB} @@ -2252,7 +2252,7 @@ identifier bindings and modules from the REPL's namespace. @tab @ref{racket-expand-last-sexp} @item @kbd{C-c C-e r} @tab @ref{racket-expand-region} -@item @kbd{)} , @kbd{]} , @kbd{@}} +@item @kbd{)} or @kbd{]} or @kbd{@}} @tab @ref{racket-insert-closing} @item @kbd{C-M-y} @tab @ref{racket-insert-lambda} @@ -2362,7 +2362,7 @@ the variable @ref{racket-before-run-hook}. @node racket-run-module-at-point @subsection racket-run-module-at-point -@kbd{C-c C-k} or @kbd{C-c C-c} +@kbd{C-c C-k} or @kbd{C-c C-c} Save the buffer and run the module at point. @@ -2514,7 +2514,7 @@ delete compiled/*.zo files. Major mode for results of @ref{racket-profile}. -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} +@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} @item Key @tab Binding @item @kbd{q} @@ -2525,7 +2525,7 @@ Major mode for results of @ref{racket-profile}. @tab @code{racket-profile-show-non-project} @item @kbd{z} @tab @code{racket-profile-show-zero} -@item @kbd{.} , @kbd{RET} +@item @kbd{.} or @kbd{RET} @tab @code{racket-profile-visit} @end multitable @@ -2701,7 +2701,7 @@ Delete all text in the REPL, except for the last prompt. @node racket-test @subsection racket-test -@kbd{C-} or @kbd{C-c C-t} +@kbd{C-} or @kbd{C-c C-t} Run the ``test'' submodule. @@ -2833,12 +2833,12 @@ Used by the commands @ref{racket-expand-file}, @ref{racket-expand-definition}, @ref{racket-expand-region}, and @ref{racket-expand-last-sexp}. -@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} +@multitable {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} {aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa} @item Key @tab Binding -@item @kbd{n} , @kbd{j} +@item @kbd{n} or @kbd{j} @tab @code{racket-stepper-next-item} -@item @kbd{p} , @kbd{k} +@item @kbd{p} or @kbd{k} @tab @code{racket-stepper-previous-item} @item @kbd{g} @tab @code{racket-stepper-refresh} @@ -3540,9 +3540,9 @@ It is NOT used by commands that run one specific module, such as: @itemize @item -@ref{racket-run-module-at-point} @kbd{C-c C-k} or @kbd{C-c C-c} +@ref{racket-run-module-at-point} @kbd{C-c C-k} or @kbd{C-c C-c} @item -@ref{racket-test} @kbd{C-} or @kbd{C-c C-t} +@ref{racket-test} @kbd{C-} or @kbd{C-c C-t} @item @ref{racket-profile} @end itemize