+ /* Skip past the initial element `keymap'. */
+ prev = keymap;
+ while (1)
+ {
+ list = XCONS (prev)->cdr;
+ /* If there is a parent keymap here, replace it.
+ If we came to the end, add the parent in PREV. */
+ if (! CONSP (list) || EQ (Qkeymap, XCONS (list)->car))
+ {
+ XCONS (prev)->cdr = parent;
+ break;
+ }
+ prev = list;
+ }
+
+ /* Scan through for submaps, and set their parents too. */
+
+ for (list = XCONS (keymap)->cdr; CONSP (list); list = XCONS (list)->cdr)
+ {
+ /* Stop the scan when we come to the parent. */
+ if (EQ (XCONS (list)->car, Qkeymap))
+ break;
+
+ /* If this element holds a prefix map, deal with it. */
+ if (CONSP (XCONS (list)->car)
+ && CONSP (XCONS (XCONS (list)->car)->cdr))
+ fix_submap_inheritance (keymap, XCONS (XCONS (list)->car)->car,
+ XCONS (XCONS (list)->car)->cdr);
+
+ if (VECTORP (XCONS (list)->car))
+ for (i = 0; i < XVECTOR (XCONS (list)->car)->size; i++)
+ if (CONSP (XVECTOR (XCONS (list)->car)->contents[i]))
+ fix_submap_inheritance (keymap, make_number (i),
+ XVECTOR (XCONS (list)->car)->contents[i]);
+ }
+
+ return parent;
+}
+
+/* EVENT is defined in MAP as a prefix, and SUBMAP is its definition.
+ if EVENT is also a prefix in MAP's parent,
+ make sure that SUBMAP inherits that definition as its own parent. */
+
+fix_submap_inheritance (map, event, submap)
+ Lisp_Object map, event, submap;
+{
+ Lisp_Object map_parent, parent_entry;
+
+ /* SUBMAP is a cons that we found as a key binding.
+ Discard the other things found in a menu key binding. */
+
+ if (CONSP (submap)
+ && STRINGP (XCONS (submap)->car))
+ {
+ submap = XCONS (submap)->cdr;
+ /* Also remove a menu help string, if any,
+ following the menu item name. */
+ if (CONSP (submap) && STRINGP (XCONS (submap)->car))
+ submap = XCONS (submap)->cdr;
+ /* Also remove the sublist that caches key equivalences, if any. */
+ if (CONSP (submap)
+ && CONSP (XCONS (submap)->car))
+ {
+ Lisp_Object carcar;
+ carcar = XCONS (XCONS (submap)->car)->car;
+ if (NILP (carcar) || VECTORP (carcar))
+ submap = XCONS (submap)->cdr;
+ }
+ }
+
+ /* If it isn't a keymap now, there's no work to do. */
+ if (! CONSP (submap)
+ || ! EQ (XCONS (submap)->car, Qkeymap))
+ return;
+
+ map_parent = Fkeymap_parent (map);
+ if (! NILP (map_parent))
+ parent_entry = access_keymap (map_parent, event, 0, 0);
+ else
+ parent_entry = Qnil;
+
+ if (! EQ (parent_entry, submap))
+ Fset_keymap_parent (submap, parent_entry);
+}
+\f