]> git.eshelyaron.com Git - emacs.git/commitdiff
Add new help command describe-keymap
authorStefan Kangas <stefankangas@gmail.com>
Fri, 23 Aug 2019 23:02:04 +0000 (01:02 +0200)
committerStefan Kangas <stefankangas@gmail.com>
Tue, 4 Feb 2020 01:04:20 +0000 (02:04 +0100)
* lisp/help-fns.el (describe-keymap): New command to show key bindings
for a given keymap.  (Bug#30660)
* doc/emacs/help.texi (Misc Help): Document the new command.
* doc/lispref/keymaps.texi (Scanning Keymaps): Add a cross-reference
to the above documentation.
* etc/NEWS: Announce the new command.

* test/lisp/help-fns-tests.el (help-fns-test-describe-keymap/symbol)
(help-fns-test-describe-keymap/value)
(help-fns-test-describe-keymap/not-keymap)
(help-fns-test-describe-keymap/let-bound)
(help-fns-test-describe-keymap/dynamically-bound-no-file): New tests.

Co-authored-by: Drew Adams <drew.adams@oracle.com>
doc/emacs/help.texi
doc/lispref/keymaps.texi
etc/NEWS
lisp/help-fns.el
test/lisp/help-fns-tests.el

index fce6720b9348ceab76a4159790e8a663a6c3ed0f..49c53c5cbc0e2290542f770d5e7ea3aa8a0c7841 100644 (file)
@@ -601,6 +601,11 @@ is @key{ESC}, because @kbd{@key{ESC} C-h} is actually @kbd{C-M-h},
 which marks a defun.  However, @w{@kbd{@key{ESC} @key{F1}}} and
 @w{@kbd{@key{ESC} ?}} work fine.)
 
+@findex describe-keymap
+Finally, @kbd{M-x describe-keymap} prompts for the name of a keymap,
+with completion, and displays a listing of all key bindings in that
+keymap.
+
 @node Help Files
 @section Help Files
 
index 259efea32489fadcd0e0383fa9e3b1c03865dc1c..4d513132e9ff8178394a1116414b2d052857b4e3 100644 (file)
@@ -1846,8 +1846,11 @@ local map.
 @cindex scanning keymaps
 @cindex keymaps, scanning
 
-  This section describes functions used to scan all the current keymaps
-for the sake of printing help information.
+  This section describes functions used to scan all the current
+keymaps for the sake of printing help information.  To display the
+bindings in a particular keymap, you can use the
+@code{describe-keymap} command (@pxref{Misc Help, , Other Help
+Commands, emacs, The GNU Emacs Manual})
 
 @defun accessible-keymaps keymap &optional prefix
 This function returns a list of all the keymaps that can be reached (via
index 1fbcd43ab00a71c6a56ee5af5c31545e99caae30..de8e20e2de40d6263cfd8aaa2ed80692b53378db 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -85,6 +85,11 @@ shows equivalent key bindings for all commands that have them.
 \f
 * Changes in Specialized Modes and Packages in Emacs 28.1
 
+** Help
+
++++
+*** New command 'describe-keymap' describes keybindings in a keymap.
+
 ---
 ** The old non-SMIE indentation of 'sh-mode' has been removed.
 
index 0e2ae6b3c3c1d75bbfd846535f632fac55c2c6de..017bb3ae748910af9c3697fdfebdbd63f57548a9 100644 (file)
@@ -1562,6 +1562,65 @@ BUFFER should be a buffer or a buffer name."
          (insert "\nThe parent category table is:")
          (describe-vector table 'help-describe-category-set))))))
 
+;;;###autoload
+(defun describe-keymap (keymap)
+  "Describe key bindings in KEYMAP.
+When called interactively, prompt for a variable that has a
+keymap value."
+  (interactive (list
+                (intern (completing-read "Keymap: " obarray
+                                         (lambda (m)
+                                           (and (boundp m)
+                                                (keymapp (symbol-value m))))
+                                         t nil 'variable-name-history))))
+  (let (used-gentemp)
+    (unless (and (symbolp keymap)
+                 (boundp keymap)
+                 (keymapp (symbol-value keymap)))
+      (when (not (keymapp keymap))
+        (if (symbolp keymap)
+            (error "Not a keymap variable: %S" keymap)
+          (error "Not a keymap")))
+      (let ((sym nil))
+        (unless sym
+          (setq sym (cl-gentemp "KEYMAP OBJECT (no variable) "))
+          (setq used-gentemp t)
+          (set sym keymap))
+        (setq keymap sym)))
+    ;; Follow aliasing.
+    (setq keymap (or (ignore-errors (indirect-variable keymap)) keymap))
+    (help-setup-xref (list #'describe-keymap keymap)
+                     (called-interactively-p 'interactive))
+    (let* ((name (symbol-name keymap))
+           (doc (documentation-property keymap 'variable-documentation))
+           (file-name (find-lisp-object-file-name keymap 'defvar)))
+      (with-help-window (help-buffer)
+        (with-current-buffer standard-output
+          (unless used-gentemp
+            (princ (format-message "%S is a keymap variable" keymap))
+            (if (not file-name)
+                (princ ".\n\n")
+              (princ (format-message
+                      " defined in `%s'.\n\n"
+                      (if (eq file-name 'C-source)
+                          "C source code"
+                        (file-name-nondirectory file-name))))
+              (save-excursion
+                (re-search-backward (substitute-command-keys
+                                     "`\\([^`']+\\)'")
+                                    nil t)
+                (help-xref-button 1 'help-variable-def
+                                  keymap file-name))))
+          (when (and (not (equal "" doc)) doc)
+            (princ "Documentation:\n")
+            (princ (format-message "%s\n\n" doc)))
+          ;; Use `insert' instead of `princ', so control chars (e.g. \377)
+          ;; insert correctly.
+          (insert (substitute-command-keys (concat "\\{" name "}"))))))
+    ;; Cleanup.
+    (when used-gentemp
+      (makunbound keymap))))
+
 \f
 ;;; Replacements for old lib-src/ programs.  Don't seem especially useful.
 
index ef42d4bda29638eb5b16cebc1b363f557ad8cc93..1d6c062979fdc9348d6e131810f4d6f7fd420b1b 100644 (file)
@@ -123,4 +123,32 @@ Return first line of the output of (describe-function-1 FUNC)."
     (goto-char (point-min))
     (should (looking-at "^font-lock-comment-face is "))))
 
+\f
+;;; Tests for describe-keymap
+(ert-deftest help-fns-test-describe-keymap/symbol ()
+  (describe-keymap 'minibuffer-local-must-match-map)
+  (with-current-buffer "*Help*"
+    (should (looking-at "^minibuffer-local-must-match-map is"))))
+
+(ert-deftest help-fns-test-describe-keymap/value ()
+  (describe-keymap minibuffer-local-must-match-map)
+  (with-current-buffer "*Help*"
+    (should (looking-at "^key"))))
+
+(ert-deftest help-fns-test-describe-keymap/not-keymap ()
+  (should-error (describe-keymap nil))
+  (should-error (describe-keymap emacs-version)))
+
+(ert-deftest help-fns-test-describe-keymap/let-bound ()
+  (let ((foobar minibuffer-local-must-match-map))
+    (describe-keymap foobar)
+    (with-current-buffer "*Help*"
+      (should (looking-at "^key")))))
+
+(ert-deftest help-fns-test-describe-keymap/dynamically-bound-no-file ()
+  (setq help-fns-test--describe-keymap-foo minibuffer-local-must-match-map)
+  (describe-keymap 'help-fns-test--describe-keymap-foo)
+  (with-current-buffer "*Help*"
+    (should (looking-at "^help-fns-test--describe-keymap-foo is"))))
+
 ;;; help-fns-tests.el ends here