diff --git a/doc/generate.el b/doc/generate.el index 22383b43..2b0357e7 100644 --- a/doc/generate.el +++ b/doc/generate.el @@ -8,6 +8,9 @@ ;; The reference.org file is included by racket-mode.org as its last, ;; "Reference" section. Then racket-mode.org is used to create both ;; Info and HTML format documentation. +;; +;; Note that this file is /not/ loaded when running Racket Mode -- +;; just used as part of the build process. (require 'racket-mode) (require 'racket-debug) @@ -388,7 +391,7 @@ unescaping too." (buffer-string)))) (defun racket-generate--insert-keymap (km) - "Insert org table for keymap KM. + "Insert org table describing keymap KM. Filter \"noise\" like bindings for `negative-argument' and `digit-argument'. @@ -397,9 +400,17 @@ Insert sorted by command name. When multiple key-bindings for a command, group into one row of table, sorted shortest first." - (let ((result (make-hash-table))) + ;; Accumulate nested keymaps into a flat association list. Each key + ;; is a command symbol. Each value is a list of lists of keys + ;; (potentially more than one key sequence bound for each command). + (let ((alist nil)) (cl-labels - ((keymap (v prefix-keys) + ((add (sym keys) + (let ((cell (assq sym alist))) + (if cell + (setcdr cell (push keys (cdr cell))) + (push (cons sym (list keys)) alist)))) + (keymap (v prefix-keys) (dolist (v (cdr v)) (pcase v (`(,(and key (pred numberp)) . ,(and km (pred keymapp))) @@ -410,26 +421,21 @@ table, sorted shortest first." (unless (member sym '(negative-argument digit-argument describe-mode)) - (puthash sym - (cons (reverse (cons key prefix-keys)) - (gethash sym result)) - result))))))) + (add sym (reverse (cons key prefix-keys))))))))) + ;; Recursively mutate `alist'. (keymap km nil) - (let* ((alist nil) - (_ (maphash (lambda (sym keys) - (push (cons sym keys) alist)) - result))) - (dolist (v (seq-sort-by (lambda (v) (symbol-name (car v))) - #'string< - alist)) - (let* ((command-str (racket-generate--ref-or-code (car v))) - (keys-strs (seq-map (lambda (binding) - (format "{{{kbd(%s)}}}" - (racket-generate--key-description binding))) - (cdr v))) - (keys-str (string-join (seq-sort-by #'length #'< keys-strs) - ", "))) - (insert "|" keys-str "|" command-str "|\n"))))))) + ;; Navigate `alist' sorted by command. + (dolist (v (seq-sort-by (lambda (v) (symbol-name (car v))) + #'string< + alist)) + (let* ((command-str (racket-generate--ref-or-code (car v))) + (keys-strs (seq-map (lambda (binding) + (format "{{{kbd(%s)}}}" + (racket-generate--key-description binding))) + (cdr v))) + (keys-str (string-join (seq-sort-by #'length #'< keys-strs) + ", "))) + (insert "|" keys-str "|" command-str "|\n")))))) (defun racket-generate--key-description (xs) "Like `key-description' but escapes some chars for our \"KBD\" texi macro."