Subject: Re: bug#12744: 24.1; key-binding and local-key-binding return invalid keymap

From: Stefan Monnier <[email-masked]>
Date: Sun, 28 Oct 2012 10:58:23 -0400

> It seems to me. That (key-binding [menu-bar]) returns a wrong keymap.
> It starts with a nested keymap:
> (keymap (keymap (keymap (show . undefined) (hide . undefined) (headings
> .. undefined) (Org menu-item "Org" ...) (Tbl menu-item "Tbl" ...)) keymap
> (headings...
> But there's nothing about that nesting in the docs.

Indeed, it's missing from the docs.  This is a new format added in
Emacs-24 (used in `make-composed-keymap').

Any keymap that appears as above within a keymap is treated as a kind of
additional parent, as if it were "inlined" where it appears.

> When the buffer is in org-mode and i trigger tmm-menubar neither the Org
> nor the Tbl menu are in the list.

Indeed, it looks like the tmm-menubar needs some updating as well,
thanks for spotting this.

I've installed the patch below which should fix those problems.

        Stefan

=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog	2012-10-27 09:54:04 +0000
+++ lisp/ChangeLog	2012-10-28 14:54:26 +0000
@@ -1,3 +1,7 @@
+2012-10-28  Stefan Monnier  <[email-masked]>
+
+	* tmm.el (tmm-prompt): Use map-keymap (bug#12744).
+
 2012-10-27  Eli Zaretskii  <[email-masked]>
 
 	* profiler.el (profiler-report-make-entry-part): Fix help-echo

=== modified file 'lisp/tmm.el'
--- lisp/tmm.el	2012-06-07 16:35:00 +0000
+++ lisp/tmm.el	2012-10-28 14:38:38 +0000
@@ -165,13 +165,15 @@
     ;; tmm-km-list is an alist of (STRING . MEANING).
     ;; It has no other elements.
     ;; The order of elements in tmm-km-list is the order of the menu bar.
+    (if (not not-menu)
+        (map-keymap (lambda (k v) (tmm-get-keymap (cons k v))) menu)
     (dolist (elt menu)
       (cond
        ((stringp elt) (setq gl-str elt))
        ((listp elt) (tmm-get-keymap elt not-menu))
        ((vectorp elt)
         (dotimes (i (length elt))
-          (tmm-get-keymap (cons i (aref elt i)) not-menu)))))
+            (tmm-get-keymap (cons i (aref elt i)) not-menu))))))
     ;; Choose an element of tmm-km-list; put it in choice.
     (if (and not-menu (= 1 (length tmm-km-list)))
 	;; If this is the top-level of an x-popup-menu menu,
@@ -463,9 +465,10 @@
 	       (and (stringp (car elt)) (setq str (car elt))))
 
 	      ((stringp event)		; x-popup or x-popup element
-	       (if (or in-x-menu (stringp (car-safe elt)))
-		   (setq str event event nil km elt)
-		 (setq str event event nil km (cons 'keymap elt)))))
+               (setq str event)
+               (setq event nil)
+	       (setq km (if (or in-x-menu (stringp (car-safe elt)))
+                            elt (cons 'keymap elt)))))
         (unless (or (eq km 'ignore) (null str))
           (let ((binding (where-is-internal km nil t)))
             (when binding

=== modified file 'doc/lispref/ChangeLog'
--- doc/lispref/ChangeLog	2012-10-28 12:56:15 +0000
+++ doc/lispref/ChangeLog	2012-10-28 14:54:03 +0000
@@ -1,3 +1,8 @@
+2012-10-28  Stefan Monnier  <[email-masked]>
+
+	* keymaps.texi (Format of Keymaps): Document the multiple
+	inheritance format.
+
 2012-10-28  Martin Rudalics  <[email-masked]>
 
 	* windows.texi (Basic Windows): Reformulate description of live,

=== modified file 'doc/lispref/keymaps.texi'
--- doc/lispref/keymaps.texi	2012-10-24 03:48:50 +0000
+++ doc/lispref/keymaps.texi	2012-10-28 14:55:42 +0000
@@ -210,6 +210,11 @@
 have a string as an element.  This is called the @dfn{overall prompt
 string} and makes it possible to use the keymap as a menu.
 @xref{Defining Menus}.
+
+@item (keymap @dots{})
+If an element of a keymap is itself a keymap, it counts as if this inner keymap
+were inlined in the outer keymap.  This is used for multiple-inheritance, such
+as in @code{make-composed-keymap}.
 @end table
 
 When the binding is @code{nil}, it doesn't constitute a definition