tags:

views:

61

answers:

2

When I query the current value of the keymap it shows me something along these lines:

Value: 
(keymap
 (S-mouse-2 . muse-follow-name-at-mouse-other-window)
 (mouse-2 . muse-follow-name-at-mouse)
 (33554445 . muse-follow-name-at-point-other-window)
 (S-return . muse-follow-name-at-point-other-window)
 (13 . muse-follow-name-at-point)
 (return . muse-follow-name-at-point)
 keymap
 (67108924 . muse-decrease-list-item-indentation)
 (67108926 . muse-increase-list-item-indentation)
 (M-return . muse-insert-list-item)
 (33554441 . muse-previous-reference)
 (S-iso-lefttab . muse-previous-reference)
 (S-tab . muse-previous-reference)
 (S-mouse-2 . muse-follow-name-at-mouse-other-window)
 (mouse-2 . muse-follow-name-at-mouse)
 (33554445 . muse-follow-name-at-point-other-window)
 (9 . muse-next-reference)
 (tab . muse-next-reference)
 (3 keymap
    (19 . muse-search)
    (2 . muse-find-backlinks)
    (tab . muse-insert-thing)
    (9 . muse-insert-thing)
    (16 . muse-project-publish)
    (6 . muse-project-find-file)
    (61 . muse-what-changed)
    (22 . muse-browse-result)
    (27 keymap
        (20 . muse-publish-this-file))
    (33554452 . muse-publish-this-file)
    (20 . muse-project-publish-this-file)
    (12 . font-lock-mode)
    (5 . muse-edit-link-at-point)
    (1 . muse-index))
 keymap
 (27 keymap
     (9 . ispell-complete-word)))

I want instead of numbers see something more meaningful like (control ?c) return for example. How do I do that ?

+3  A: 
  • Did you know the command C-h m (describe-mode), which usually shows a description of the current major and minor modes, usually with their keymaps?

  • (substitute-command-keys "\\{foo-map}") is what describe-mode uses internally to generate the user-friendly description of the keymap foo-map.

  • If you'd like to have something closer to the keymap structure, the API is documented in "Classifying Events" in the Emacs Lisp manual. For example,
        (event-modifiers 33554445) ==> (shift control)
        (format "%c" (event-basic-type 33554445)) ==> "m"

Gilles
This is a nice simple answer! (Simply evaluate (substitute-command-keys "\\{foo-map}"); why haven't I thought of this!)
imz
+1  A: 

Here's a poor-man's implementation what describe-bindings (C-h b) gives you, but restricted to a particular keymap. The formatting isn't great, but should get you started:

(defun describe-keymap (keymap &optional prefix)
  (pop-to-buffer "Keymap description")
  (erase-buffer)
  (describe-keymap-impl keymap prefix))

(defun describe-keymap-impl (keymap &optional prefix)
  "show a description of keymap"
  (let (keymaps-to-process)
    (mapc (lambda (partofkeymap)
            (when prefix
              (insert (concat prefix " ")))
            (insert (key-description (list partofkeymap)))
            (insert "                ")
            (cond ((atom partofkeymap))
                  ((listp (cdr partofkeymap))
                   (insert "prefix-key")
                   (if (eq 'keymap (cadr partofkeymap))
                       (setq keymaps-to-process (cons partofkeymap keymaps-to-process))))
                  (t 
                   (insert (symbol-name (cdr partofkeymap)))))
            (insert "\n"))
          (if (and (symbolp keymap) (boundp keymap))
              (symbol-value keymap)
            keymap))
    (while keymaps-to-process
      (insert "\n\n")
      (describe-keymap-impl (cddar keymaps-to-process) (concat prefix (key-description (list (caar keymaps-to-process)))))
      (setq keymaps-to-process (cdr keymaps-to-process))))
  nil)

I tested by evaluating both:

(describe-keymap emacs-lisp-mode-map)
(describe-keymap 'emacs-lisp-mode-map)
Trey Jackson
But you shouldn't need to re-implement describe-bindings. Just the available function -- describe-bindings -- should be able to do what is needed for any arbitrary keymap.Consider `describe-mode': it prints out keymaps specified by expressions of the form \{MAPVAR} inside the documentation in human readable form. Its output is the documentation string of the mode function formatted by `documentation' function; in its turn, the `documentation' function uses `substitute-command-keys', which in its turn calls exactly `describe-bindings' to format \{MAPVAR} expressions in the source doc string.
imz
After studying the Elisp source, I discovered that contrary to what I have written above and what can be inferred from the documentation, `describe-bindings' doesn't take a keymap as an argument. :(But the documentation for `substitute-command-keys' clearly supposes this:"Substrings of the form \{MAPVAR} are replaced by summaries(made by `describe-bindings') of the value of MAPVAR, taken as a keymap."Perhaps, one can overcome this by installing the interesting keymap as a local keymap in a temporary buffer, and running the standard `describe-bindings' there...
imz