home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / gnu / lucid / lemacs-19.6 / src / keymap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-13  |  83.9 KB  |  2,781 lines

  1. /* Manipulation of keymaps
  2.    Copyright (C) 1985-1993 Free Software Foundation, Inc.
  3.    Totally redesigned by jwz in 1991.
  4.  
  5. This file is part of GNU Emacs.
  6.  
  7. GNU Emacs is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2, or (at your option)
  10. any later version.
  11.  
  12. GNU Emacs is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with GNU Emacs; see the file COPYING.  If not, write to
  19. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  20.  
  21. /* A keymap contains four slots:
  22.  
  23.    parent       A keymap to search after this one if no match.
  24.            Keymaps can thus be arranged in a hierarchy.
  25.  
  26.    table       A hash table, hashing keysyms to their bindings.
  27.            As in the rest of emacs, a keysym is either a symbol or
  28.            an integer, which is an ASCII code (of one of the printing
  29.            ASCII characters: not 003 meaning C-c, for instance.)
  30.  
  31.    inverse_table   A hash table, hashing bindings to the list of keysyms
  32.            in this keymap which are bound to them.  This is to make
  33.            the Fwhere_is_internal() function be fast.  It needs to be
  34.            fast because we want to be able to call it in realtime to
  35.            update the keyboard-equivalents on the pulldown menus.
  36.  
  37.    sub_maps_cache  An alist; for each entry in this keymap whose binding is
  38.            a keymap (that is, Fkeymapp()) this alist associates that
  39.            keysym with that binding.  This is used to optimize both
  40.            Fwhere_is_internal() and Faccessible_keymaps().  This slot
  41.            gets set to the symbol `t' every time a change is made to
  42.            this keymap, causing it to be recomputed when next needed.
  43.  
  44.    Sequences of keys are stored in the obvious way: if the sequence of keys
  45.    "abc" was bound to some command `foo', the hierarchy would look like
  46.  
  47.       keymap-1: associates "a" with keymap-2
  48.       keymap-2: associates "b" with keymap-3
  49.       keymap-3: associates "c" with foo
  50.  
  51.    However, bucky bits ("modifiers" to the X-minded) are represented in the
  52.    keymap hierarchy as well.  (This lets us use EQable objects as hash keys.)
  53.    If the key `C-a' was bound to some command, the hierarchy would look like
  54.  
  55.       keymap-1: associates the symbol `control' with keymap-2
  56.       keymap-2: associates "a" with the command
  57.  
  58.    Likewise for all other bucky bits: meta, super, hyper, symbol, and shift.
  59.    The ordering of these is strict: there will never be a `control' submap
  60.    of a keymap which is bound to `meta', because that could lead to
  61.    ambiguities.
  62.  
  63.    When associating a command with C-M-a, we'd have
  64.  
  65.       keymap-1: associates the symbol `control' with keymap-2
  66.       keymap-2: associates the symbol `meta' with keymap-3
  67.       keymap-3: associates "a" with the command
  68.  
  69.    Note that keymap-2 might have normal bindings in it, and keymap-1 might
  70.    have a keymap bound to `meta' in it.  That would be the meta-map.
  71.    Keymap-2 is the "control" map.  Keymap-3 is the "control-meta" map.
  72.  
  73.    If the command that "a" was bound to in keymap-3 was itself a keymap,
  74.    then that would make the key "C-M-a" be a prefix character.
  75.  
  76.    Note that this new model of keymaps takes much of the magic away from
  77.    the Escape key: the value of the variable `esc-map' is no longer indexed
  78.    in the `global-map' under the ESC key.  It's indexed under the symbol
  79.    `meta'.  This is not user-visible, however; none of the "bucky" maps are.
  80.  
  81.    There is a hack in Flookup_key() that makes (lookup-key global-map "\^[")
  82.    and (define-key some-random-map "\^[" my-esc-map) work as before, for
  83.    compatibility.
  84.  
  85.    Since keymaps are opaque, the only way to extract information from them
  86.    is with the functions lookup-key, key-binding, local-key-binding, and
  87.    global-key-binding, which work just as before, and the new function
  88.    map-keymap, which is roughly analagous to maphash.  
  89.  
  90.    Note that map-keymap perpetuates the illusion that the "bucky" submaps
  91.    don't exist: if you map over a keymap with bucky submaps, it will also
  92.    map over those submaps.  It does not, however, map over other random
  93.    submaps of the keymap, just the bucky ones.
  94.  
  95.    One implication of this is that when you map over `global-map', you will
  96.    also map over `esc-map'.  It is merely for compatibility that the esc-map
  97.    is accessible at all; I think that's a bad thing, since it blurs the
  98.    distinction between ESC and "meta" even more.  "M-x" is no more a two-
  99.    key sequence than "C-x" is.
  100.  
  101.  */
  102.  
  103. #include "config.h"
  104. #include <stdio.h>
  105.  
  106. #include "lisp.h"
  107. #include "keymap.h"
  108. #include "commands.h"
  109. #include "buffer.h"
  110. #include "events.h"
  111. #include "insdel.h"
  112. #include "elhash.h"
  113.  
  114. extern Lisp_Object Vcharacter_set_property;
  115.  
  116. #define min(a, b) ((a) < (b) ? (a) : (b))
  117.  
  118. /* Actually allocate storage for these variables */
  119.  
  120. static Lisp_Object Vcurrent_global_map;    /* Current global keymap */
  121.  
  122. /* This is incremented whenever a change is made to a keymap.  This is
  123.    so that things which care (such as the menubar code) can recompute
  124.    privately-cached data when the user has changed their keybindings.
  125.  */
  126. int keymap_tick;
  127.  
  128. /* Prefixing a key with this character is the same as sending a meta bit. */
  129. int meta_prefix_char;
  130.  
  131. Lisp_Object Qkeymapp;
  132.  
  133. Lisp_Object Qsuppress_keymap;
  134.  
  135. void describe_map_tree ();
  136. static Lisp_Object describe_buffer_bindings ();
  137. static Lisp_Object describe_buffer_mouse_bindings ();
  138. static void describe_command ();
  139. static void describe_map ();
  140. static int bucky_sym_to_bucky_bit ();
  141. static void describe_vector ();
  142.  
  143. Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qsymbol, Qshift;
  144. Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3, Qbutton4, Qbutton5,
  145.   Qbutton6, Qbutton7;
  146. Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up, Qbutton4up,
  147.   Qbutton5up, Qbutton6up, Qbutton7up;
  148. Lisp_Object Qmenu_selection;
  149.  
  150.  
  151.  
  152. static void
  153. keymap_store_inverse_internal (keysym, keymap, value)
  154.      Lisp_Object keysym, value;
  155.      struct Lisp_Keymap *keymap;
  156. {
  157.   Lisp_Object keys = Fgethash (value, keymap->inverse_table, Qnil);
  158.   if (NILP (keys))
  159.     {
  160.       keys = Fcons (keysym, Qnil);
  161.       Fputhash (value, keys, keymap->inverse_table);
  162.     }
  163.   else
  164.     {
  165.       Lisp_Object tail = keys;
  166.       while (!NILP (XCONS (tail)->cdr))
  167.     tail = XCONS (tail)->cdr;
  168.       XCONS (tail)->cdr = Fcons (keysym, Qnil);
  169.       /* We don't need to call puthash here, because we've modified the
  170.      list directly (the pointer in the hash table is still valid.)
  171.        */
  172.     }
  173. }
  174.  
  175.  
  176. static void
  177. keymap_delete_inverse_internal (keysym, keymap, value)
  178.      Lisp_Object keysym, value;
  179.      struct Lisp_Keymap *keymap;
  180. {
  181.   Lisp_Object keys = Fgethash (value, keymap->inverse_table, Qnil);
  182.   Lisp_Object new_keys;
  183.   if (NILP (keys))
  184.     abort ();
  185.   new_keys = delq_no_quit (keysym, keys);
  186.   if (NILP (new_keys))
  187.     Fremhash (value, keymap->inverse_table);
  188.   else if (!EQ (keys, new_keys))    /* meaning it was the first elt */
  189.     Fputhash (value, new_keys, keymap->inverse_table);
  190.   /* else the list's tail has been modified, so we don't need to
  191.      touch the hash table again (the pointer in there is ok).
  192.    */
  193. }
  194.  
  195.  
  196. static void
  197. keymap_store_internal (keysym, keymap, value)
  198.      Lisp_Object keysym, value;
  199.      struct Lisp_Keymap *keymap;
  200. {
  201.   Lisp_Object prev_value = Fgethash (keysym, keymap->table, Qnil);
  202.   if (!NILP (prev_value))
  203.     keymap_delete_inverse_internal (keysym, keymap, prev_value);
  204.   if (NILP (value))
  205.     {
  206.       if (!NILP (prev_value))
  207.     {
  208.       if ((--keymap->fullness) < 0) abort ();
  209.       Fremhash (keysym, keymap->table);
  210.     }
  211.     }
  212.   else
  213.     {
  214.       if (NILP (prev_value))
  215.     keymap->fullness++;
  216.       Fputhash (keysym, value, keymap->table);
  217.       keymap_store_inverse_internal (keysym, keymap, value);
  218.     }
  219.   keymap_tick++;
  220. }
  221.  
  222.  
  223. static Lisp_Object
  224. keymap_lookup_directly (km, keysym, modifiers)
  225.      Lisp_Object km, keysym;
  226.      int modifiers;
  227. {
  228.   struct Lisp_Keymap *keymap;
  229.   Lisp_Object submap, submap_name;
  230.   int submap_bit;
  231.   if (!KEYMAPP (km)) abort ();
  232.   keymap = XKEYMAP (km);
  233.   if (! modifiers)
  234.     {
  235.       /* If the keysym is a one-character symbol, use the char code instead. */
  236.       if (SYMBOLP (keysym) && XSYMBOL (keysym)->name->size == 1)
  237.     keysym = make_number (XSYMBOL (keysym)->name->data [0]);
  238.       return (Fgethash (keysym, keymap->table, Qnil));
  239.     }
  240.   else if (modifiers & MOD_META)
  241.     submap_name = Qmeta, submap_bit = MOD_META;
  242.   else if (modifiers & MOD_CONTROL)
  243.     submap_name = Qcontrol, submap_bit = MOD_CONTROL;
  244.   else if (modifiers & MOD_SUPER)
  245.     submap_name = Qsuper, submap_bit = MOD_SUPER;
  246.   else if (modifiers & MOD_HYPER)
  247.     submap_name = Qhyper, submap_bit = MOD_HYPER;
  248.   else if (modifiers & MOD_SYMBOL)
  249.     submap_name = Qsymbol, submap_bit = MOD_SYMBOL;
  250.   else if (modifiers & MOD_SHIFT)
  251.     submap_name = Qshift, submap_bit = MOD_SHIFT;
  252.   else
  253.     abort ();
  254.  
  255.   submap = keymap_lookup_directly (km, submap_name, 0);
  256.   if (NILP (submap))
  257.     return Qnil;
  258.   submap = get_keymap (submap, 1);
  259.   return keymap_lookup_directly (submap, keysym, (modifiers & (~submap_bit)));
  260. }
  261.  
  262.  
  263. static void
  264. keymap_store (keymap, keysym, modifiers, value)
  265.      Lisp_Object keymap, keysym, value;
  266.      int modifiers;
  267. {
  268.   Lisp_Object submap_name, submap;
  269.   int submap_bit;
  270.   if (!KEYMAPP (keymap))
  271.     keymap = get_keymap (keymap, 1);
  272.   XKEYMAP (keymap)->sub_maps_cache = Qt; /* Invalidate cache */
  273.   if (! modifiers)
  274.     {
  275.       /* If the keysym is a one-character symbol, use the char code instead. */
  276.       if (SYMBOLP (keysym) && XSYMBOL (keysym)->name->size == 1)
  277.     keysym = make_number (XSYMBOL (keysym)->name->data [0]);
  278.       keymap_store_internal (keysym, XKEYMAP (keymap), value);
  279.       return;
  280.     }
  281.   else if (modifiers & MOD_META)
  282.     submap_name = Qmeta, submap_bit = MOD_META;
  283.   else if (modifiers & MOD_CONTROL)
  284.     submap_name = Qcontrol, submap_bit = MOD_CONTROL;
  285.   else if (modifiers & MOD_SUPER)
  286.     submap_name = Qsuper, submap_bit = MOD_SUPER;
  287.   else if (modifiers & MOD_HYPER)
  288.     submap_name = Qhyper, submap_bit = MOD_HYPER;
  289.   else if (modifiers & MOD_SYMBOL)
  290.     submap_name = Qsymbol, submap_bit = MOD_SYMBOL;
  291.   else if (modifiers & MOD_SHIFT)
  292.     submap_name = Qshift, submap_bit = MOD_SHIFT;
  293.   else
  294.     abort ();
  295.  
  296.   submap = keymap_lookup_directly (keymap, submap_name, 0);
  297.   if (NILP (submap))
  298.     {
  299.       submap = Fmake_sparse_keymap ();
  300.       /* User won't see this, but it is nice for debugging Emacs */
  301.       XKEYMAP (submap)->name = list2 (submap_name, keymap);
  302.       keymap_store (keymap, submap_name, 0, submap);
  303.     }
  304.   keymap_store (submap, keysym, (modifiers & (~submap_bit)), value);
  305. }
  306.  
  307.  
  308.  
  309. static void
  310. keymap_submaps_mapper (hash_key, hash_contents, closure)
  311.      void *hash_key, *hash_contents, *closure;
  312. {
  313.   Lisp_Object key = (Lisp_Object) hash_key;
  314.   Lisp_Object contents = (Lisp_Object) hash_contents;
  315.   struct Lisp_Keymap *self = (struct Lisp_Keymap *) closure;
  316.   if (NILP (Fkeymapp (contents)))
  317.     return;
  318.   self->sub_maps_cache = Fcons (Fcons (key, contents), self->sub_maps_cache);
  319. }
  320.  
  321. static int map_keymap_sort_predicate ();
  322.  
  323. static Lisp_Object
  324. keymap_submaps (keymap)
  325.      struct Lisp_Keymap *keymap;
  326. {
  327.   if (!EQ (keymap->sub_maps_cache, Qt))
  328.     return keymap->sub_maps_cache;
  329.   keymap->sub_maps_cache = Qnil;
  330.   elisp_maphash (keymap_submaps_mapper, keymap->table, (void *) keymap);
  331.   /* keep it sorted so that the result of accessible-keymaps is ordered */
  332.   keymap->sub_maps_cache = list_sort (keymap->sub_maps_cache, Qnil,
  333.                       map_keymap_sort_predicate);
  334.   return keymap->sub_maps_cache;
  335. }
  336.  
  337.  
  338. static Lisp_Object
  339. make_keymap (size)
  340.      int size;
  341. {
  342.   Lisp_Object keymap = Fmake_vector (make_number (KEYMAP_SIZE), 
  343.                                      make_number (0));
  344.   XSETTYPE (keymap, Lisp_Keymap);
  345.   XKEYMAP (keymap)->parent = Qnil;
  346.   if (size != 0) /* hack for copy-keymap */
  347.     {
  348.       XKEYMAP (keymap)->table = Fmake_hashtable (make_number (size));
  349.       XKEYMAP (keymap)->inverse_table = Fmake_hashtable (make_number (size));
  350.     }
  351.   XKEYMAP (keymap)->sub_maps_cache = Qnil; /* No possible submaps */
  352.   XKEYMAP (keymap)->fullness = 0;
  353.   XKEYMAP (keymap)->name = Qnil;
  354.   return keymap;
  355. }
  356.  
  357. DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 0, 0,
  358.   "Construct and return a new keymap object.  All entries in it are nil,\n\
  359. meaning \"command undefined\".")
  360.   ()
  361. {
  362.   return make_keymap (127);
  363. }
  364.  
  365. DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 0, 0,
  366.   "Construct and return a new keymap object.  All entries in it are nil,\n\
  367. meaning \"command undefined\".  The only difference between this function\n\
  368. and make-keymap is that this function returns a \"smaller\" keymap (one\n\
  369. that is expected to contain less entries.)  As keymaps dynamically resize,\n\
  370. the distinction is not great.")
  371.   ()
  372. {
  373.   return make_keymap (10);
  374. }
  375.  
  376. DEFUN ("keymap-parent", Fkeymap_parent, Skeymap_parent, 1, 1, 0,
  377.        "Returns the `parent' keymap of the given keymap, or nil.\n\
  378. The parent of a keymap is searched for keybindings when a key sequence\n\
  379. isn't bound in this one.  The (current-global-map) is the default parent\n\
  380. of all keymaps.")
  381.      (keymap)
  382.      Lisp_Object keymap;
  383. {
  384.   keymap = get_keymap (keymap, 1);
  385.   return XKEYMAP (keymap)->parent;
  386. }
  387.  
  388. DEFUN ("set-keymap-parent", Fset_keymap_parent, Sset_keymap_parent, 2, 2, 0,
  389.        "Sets the `parent' keymap of the given keymap.\n\
  390. The parent of a keymap is searched for keybindings when a key sequence\n\
  391. isn't bound in this one.  The (current-global-map) is the default parent\n\
  392. of all keymaps.")
  393.      (keymap, parent)
  394.      Lisp_Object keymap, parent;
  395. {
  396.   Lisp_Object k;
  397.   struct gcpro gcpro1, gcpro2;
  398.   GCPRO2 (keymap, parent);
  399.  
  400.   keymap = get_keymap (keymap, 1);
  401.   if (!NILP (parent))
  402.   {
  403.     /* Require that it be an actual keymap object, rather than a symbol
  404.        with a (crockish) symbol-function which is a keymap */
  405.     CHECK_KEYMAP (parent, 1);
  406.   }
  407.   
  408.   for (k = parent; !NILP (k); k = XKEYMAP (k)->parent)
  409.   {
  410.     QUIT;
  411.     if (EQ (k, keymap))
  412.       signal_error (Qerror, 
  413.                     list3 (build_string ("Cyclic keymap indirection"),
  414.                            keymap, 
  415.                            parent));
  416.   }
  417.   keymap_tick++;
  418.   XKEYMAP (keymap)->parent = parent;
  419.   UNGCPRO;
  420.   return (parent);
  421. }
  422.  
  423. DEFUN ("set-keymap-name", Fset_keymap_name, Sset_keymap_name, 2, 2, 0,
  424.   "Sets the `name' of the KEYMAP to NEW-NAME\n\
  425. The name is only a debugging convenience; it is not used except\n\
  426. when printing the keymap.")
  427.      (keymap, new_name)
  428.      Lisp_Object keymap, new_name;
  429. {
  430.   keymap = get_keymap (keymap, 1);
  431.   XKEYMAP (keymap)->name = new_name;
  432.   return (new_name);
  433. }
  434.  
  435.  
  436. extern Lisp_Object QKbackspace, QKtab, QKlinefeed, QKreturn, 
  437.  QKescape, QKspace, QKdelete, QKundefined;
  438.  
  439. DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
  440.   "Return t if ARG is a keymap object.")
  441.   (object)
  442.      Lisp_Object object;
  443. {
  444.   /* >>>> Should this be done, or should we just return KEYMAPP??? */
  445.   Lisp_Object tem = get_keymap (object, 0);
  446.   return ((KEYMAPP (tem)) ? Qt : Qnil);
  447. }
  448.  
  449. Lisp_Object
  450. get_keymap (object, error)
  451.      Lisp_Object object;
  452.      int error;
  453. {
  454.   register Lisp_Object tem;
  455.  
  456.   while (1)
  457.     {
  458.       tem = object;
  459.       while (SYMBOLP (tem) && !EQ (tem, Qunbound))
  460.     {
  461.       tem = XSYMBOL (tem)->function;
  462.       QUIT;
  463.     }
  464.       if (KEYMAPP (tem))
  465.     return tem;
  466.       else if (error)
  467.     object = wrong_type_argument (Qkeymapp, object);
  468.       else
  469.     return Qnil;
  470.     }
  471. }
  472.  
  473. static Lisp_Object
  474. access_keymap (map, idx)
  475.      Lisp_Object map;
  476.      Lisp_Object idx;
  477. {
  478.   Lisp_Object keysym;
  479.   int modifiers;
  480.   switch (XTYPE (idx)) {
  481.   case Lisp_Int:
  482.     {
  483.       struct Lisp_Event event;
  484.       event.event_type = empty_event;
  485.       character_to_event (idx, &event);
  486.       keysym = event.event.key.key;
  487.       modifiers = event.event.key.modifiers;
  488.     }
  489.     break;
  490.   case Lisp_Cons:
  491.     keysym = XCONS (idx)->car;
  492.     modifiers = XCONS (idx)->cdr;
  493.     if (!FIXNUMP (modifiers)) return Qnil;
  494.     break;
  495.   default:
  496.     abort ();
  497.   }
  498.   return keymap_lookup_directly (map, keysym, modifiers);
  499. }
  500.  
  501.  
  502. /* Given OBJECT which was found in a slot in a keymap,
  503.    trace indirect definitions to get the actual definition of that slot.
  504.    An indirect definition is a list of the form
  505.    (KEYMAP . INDEX), where KEYMAP is a keymap or a symbol defined as one
  506.    and INDEX is an ASCII code, or a cons of (KEYSYM . MODIFIERS).
  507.  */
  508.  
  509. static Lisp_Object
  510. get_keyelt (object)
  511.      register Lisp_Object object;
  512. {
  513.   while (1)
  514.     {
  515.       register Lisp_Object map, tem;
  516.  
  517.       map = get_keymap (Fcar_safe (object), 0);
  518.       tem = Fkeymapp (map);
  519.       /* If the contents are (KEYMAP . ELEMENT), go indirect.  */
  520.       if (!NILP (tem))
  521.     {
  522.       object = Fcdr (object);
  523.       return access_keymap (map, object);
  524.     }
  525.       else
  526.     /* If the keymap contents looks like (STRING . DEFN),
  527.        use DEFN.
  528.        Keymap alist elements like (CHAR MENUSTRING . DEFN)
  529.        will be used by HierarKey menus.  */
  530.     if (CONSP (object)
  531.         && STRINGP (XCONS (object)->car))
  532.       object = XCONS (object)->cdr;
  533.       else
  534.     /* Anything else is really the value.  */
  535.     return object;
  536.     }
  537. }
  538.  
  539. static Lisp_Object
  540. keymap_lookup_1 (Lisp_Object keymap, Lisp_Object keysym, int modifiers)
  541. {
  542.   return (get_keyelt (keymap_lookup_directly (keymap, keysym, modifiers)));
  543. }
  544.  
  545. static void
  546. copy_keymap_inverse_mapper (hash_key, hash_contents, closure)
  547.      void *hash_key, *hash_contents, *closure;
  548. {
  549.   Lisp_Object inverse_table = (Lisp_Object) closure;
  550.   Lisp_Object inverse_contents = (Lisp_Object) hash_contents;
  551.   Lisp_Object oiq = Vinhibit_quit;
  552.   Vinhibit_quit = Qt;
  553.   inverse_contents = Fcopy_sequence (inverse_contents);
  554.   Vinhibit_quit = oiq;
  555.   Fputhash ((Lisp_Object) hash_key, inverse_contents, inverse_table);
  556. }
  557.  
  558.  
  559. static Lisp_Object
  560. copy_keymap_internal (keymap)
  561.      struct Lisp_Keymap *keymap;
  562. {
  563.   Lisp_Object nkm = make_keymap (0);
  564.   struct Lisp_Keymap *new_keymap = XKEYMAP (nkm);
  565.   new_keymap->parent = keymap->parent;
  566.   new_keymap->fullness = keymap->fullness;
  567.   new_keymap->sub_maps_cache = Qnil;
  568.   new_keymap->table = Fcopy_hashtable (keymap->table);
  569.   new_keymap->inverse_table = Fcopy_hashtable (keymap->inverse_table);
  570.   /* After copying the inverse map, we need to copy the conses which
  571.      are its values, lest they be shared by the copy, and mangled.
  572.    */
  573.   elisp_maphash (copy_keymap_inverse_mapper, keymap->inverse_table,
  574.          (void *) keymap->inverse_table);
  575.   return nkm;
  576. }
  577.  
  578.  
  579. static Lisp_Object copy_keymap (Lisp_Object keymap);
  580.  
  581. static void
  582. copy_keymap_mapper (hash_key, hash_contents, closure)
  583.      void *hash_key, *hash_contents, *closure;
  584. {
  585.   Lisp_Object key = (Lisp_Object) hash_key;
  586.   Lisp_Object contents = (Lisp_Object) hash_contents;
  587.   struct Lisp_Keymap *self = (struct Lisp_Keymap *) closure;
  588.   /* Don't recursively copy keymaps that are indirected through symbols. */
  589.   if (KEYMAPP (contents))
  590.     keymap_store_internal (key, self, copy_keymap (contents));
  591. }
  592.  
  593. static Lisp_Object
  594. copy_keymap (keymap)
  595.      Lisp_Object keymap;
  596. {
  597.   if (!KEYMAPP (keymap)) abort ();
  598.   keymap = copy_keymap_internal (XKEYMAP (keymap));
  599.   elisp_maphash (copy_keymap_mapper,
  600.          XKEYMAP (keymap)->table,
  601.          XKEYMAP (keymap));
  602.   return keymap;
  603. }
  604.  
  605.  
  606. DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0,
  607.   "Return a copy of the keymap KEYMAP.\n\
  608. The copy starts out with the same definitions of KEYMAP,\n\
  609. but changing either the copy or KEYMAP does not affect the other.\n\
  610. Any key definitions that are subkeymaps are recursively copied.")
  611.   (keymap)
  612.      Lisp_Object keymap;
  613. {
  614.   keymap = get_keymap (keymap, 1);
  615.   return copy_keymap (keymap);
  616. }
  617.  
  618.  
  619. static int
  620. keymap_fullness (keymap)
  621.      struct Lisp_Keymap *keymap;
  622. {
  623. /*  int fullness = XFASTINT (Fhashtable_fullness (keymap->table));*/
  624.   int fullness = keymap->fullness;
  625.   Lisp_Object sub_maps = keymap_submaps (keymap);
  626.   for (; !NILP (sub_maps); sub_maps = XCONS (sub_maps)->cdr)
  627.     if (bucky_sym_to_bucky_bit (XCONS (XCONS (sub_maps)->car)->car))
  628.       {
  629.     Lisp_Object sub_map = XCONS (XCONS (sub_maps)->car)->cdr;
  630.     fullness--; /* don't count bucky maps */
  631.     fullness += keymap_fullness (XKEYMAP (get_keymap (sub_map, 1)));
  632.       }
  633.   return fullness;
  634. }
  635.  
  636. DEFUN ("keymap-fullness", Fkeymap_fullness, Skeymap_fullness, 1, 1, 0,
  637.        "Returns the number of bindings in the keymap.")
  638.      (keymap)
  639.      Lisp_Object keymap;
  640. {
  641.   return make_number (keymap_fullness (XKEYMAP (get_keymap (keymap, 1))));
  642. }
  643.  
  644.  
  645. /* Given any kind of key-specifier, return a keysym and modifier mask.
  646.  */
  647. static void
  648. define_key_parser (spec, keysym_return, modifiers_return)
  649.      Lisp_Object spec, *keysym_return;
  650.      int *modifiers_return;
  651. {
  652.   if (SYMBOLP (spec))
  653.     spec = Fcons (spec, Qnil); /* be nice */
  654.  
  655.   if (FIXNUMP (spec))
  656.     {
  657.       struct Lisp_Event event;
  658.       event.event_type = empty_event;
  659.       character_to_event (XINT (spec), &event);
  660.       *keysym_return = event.event.key.key;
  661.       *modifiers_return = event.event.key.modifiers;
  662.       return;
  663.     }
  664.   else if (EVENTP (spec))
  665.     {
  666.       switch (XEVENT (spec)->event_type)
  667.     {
  668.     case key_press_event:
  669.       *keysym_return = XEVENT (spec)->event.key.key;
  670.       *modifiers_return = XEVENT (spec)->event.key.modifiers;
  671.       return;
  672.     case button_press_event:
  673.     case button_release_event:
  674.       {
  675.         register int down =
  676.           (XEVENT (spec)->event_type == button_press_event);
  677.         switch (XEVENT (spec)->event.button.button) {
  678.         case 1: *keysym_return = (down ? Qbutton1 : Qbutton1up); break;
  679.         case 2: *keysym_return = (down ? Qbutton2 : Qbutton2up); break;
  680.         case 3: *keysym_return = (down ? Qbutton3 : Qbutton3up); break;
  681.         case 4: *keysym_return = (down ? Qbutton4 : Qbutton4up); break;
  682.         case 5: *keysym_return = (down ? Qbutton5 : Qbutton5up); break;
  683.         case 6: *keysym_return = (down ? Qbutton6 : Qbutton6up); break;
  684.         case 7: *keysym_return = (down ? Qbutton7 : Qbutton7up); break;
  685.         default: *keysym_return =(down ? Qbutton0 : Qbutton0up); break;
  686.         }
  687.         *modifiers_return = XEVENT (spec)->event.button.modifiers;
  688.         return;
  689.       }
  690.     default:
  691.       signal_error (Qwrong_type_argument,
  692.             list2 (build_string
  693.                    ("unable to bind this type of event"),
  694.                    spec));
  695.     }
  696.     }
  697.   else if (CONSP (spec))
  698.     {
  699.       int modifiers = 0;
  700.       int mod_p;
  701.       Lisp_Object keysym;
  702.       Lisp_Object rest = spec;
  703.  
  704.       /* First, parse out the leading modifier symbols.
  705.        */
  706.       while (!NILP (rest)) {
  707.     mod_p = 1;
  708.     keysym = XCONS (rest)->car;
  709.     if (EQ (keysym, Qcontrol))    modifiers |= MOD_CONTROL;
  710.     else if (EQ (keysym, Qctrl))  modifiers |= MOD_CONTROL;
  711.     else if (EQ (keysym, Qmeta))  modifiers |= MOD_META;
  712.     else if (EQ (keysym, Qsuper)) modifiers |= MOD_SUPER;
  713.     else if (EQ (keysym, Qhyper)) modifiers |= MOD_HYPER;
  714.     else if (EQ (keysym, Qsymbol))modifiers |= MOD_SYMBOL;
  715.     else if (EQ (keysym, Qshift)) modifiers |= MOD_SHIFT;
  716.     else mod_p = 0;
  717.     if (!NILP (XCONS (rest)->cdr))
  718.       {
  719.         if (! mod_p)
  720.           signal_error (Qerror,
  721.                 list2 (build_string ("unknown modifier"), keysym));
  722.       }
  723.     else
  724.       {
  725.         if (mod_p)
  726.           signal_error (Qerror,
  727.                 list2 (build_string ("nothing but modifiers here"),
  728.                    spec));
  729.       }
  730.     rest = XCONS (rest)->cdr;
  731.     QUIT;
  732.       }
  733.  
  734.       /* Now, check and massage the trailing keysym specifier.
  735.        */
  736.       switch (XTYPE (keysym)) {
  737.       case Lisp_Symbol:
  738.     if (XSYMBOL (keysym)->name->size != 1)
  739.       break;
  740.     XSET (keysym, Lisp_Int, XSYMBOL (keysym)->name->data [0]);
  741.     /* fall through */
  742.       case Lisp_Int:
  743.     if (XINT (keysym) < ' ' || XINT (keysym) > 127)
  744.           signal_error (Qerror,
  745.                         list2 (build_string
  746.                                ("keysym must be in the printing ASCII range"),
  747.                                keysym));
  748.     if (modifiers & MOD_SHIFT)
  749.           signal_error (Qerror,
  750.                         list2 (build_string (
  751.            "the `shift' modifier may not be applied to ASCII keysyms"),
  752.                                spec));
  753.     break;
  754.       default:
  755.         signal_error (Qerror, 
  756.                       list2 (build_string ("unknown keysym specifier"),
  757.                              keysym));
  758.       }
  759.  
  760.       *keysym_return = keysym;
  761.       *modifiers_return = modifiers;
  762.       return;
  763.     }
  764.   else
  765.     {
  766.       signal_error (Qerror, 
  767.             list2 (build_string ("unknown key-sequence specifier"),
  768.                spec));
  769.     }
  770. }
  771.  
  772. /* This piece of crap is used by macros.c */
  773. void
  774. key_desc_list_to_event (list, event, allow_menu_events)
  775.      Lisp_Object list, event;
  776.      int allow_menu_events;
  777. {
  778.   Lisp_Object keysym;
  779.   int modifiers;
  780.  
  781.   if (allow_menu_events &&
  782.       CONSP (list) &&
  783.       EQ (XCONS (list)->car, Qmenu_selection))
  784.     {
  785.       Lisp_Object fn, arg;
  786.       if (! NILP (Fcdr (Fcdr (list))))
  787.     signal_error (Qerror, list2 (build_string ("invalid menu event desc"),
  788.                                      list));
  789.       arg = Fcar (Fcdr (list));
  790.       if (SYMBOLP (arg))
  791.     fn = Qcall_interactively;
  792.       else
  793.     fn = Qeval;
  794.       XEVENT (event)->channel = Qnil;
  795.       XEVENT (event)->event_type = menu_event;
  796.       XEVENT (event)->event.eval.function = fn;
  797.       XEVENT (event)->event.eval.object = arg;
  798.       return;
  799.     }
  800.  
  801.   define_key_parser (list, &keysym, &modifiers);
  802.  
  803.   if (EQ (keysym, Qbutton0) || EQ (keysym, Qbutton0up) ||
  804.       EQ (keysym, Qbutton1) || EQ (keysym, Qbutton1up) ||
  805.       EQ (keysym, Qbutton2) || EQ (keysym, Qbutton2up) ||
  806.       EQ (keysym, Qbutton3) || EQ (keysym, Qbutton3up) ||
  807.       EQ (keysym, Qbutton4) || EQ (keysym, Qbutton4up) ||
  808.       EQ (keysym, Qbutton5) || EQ (keysym, Qbutton5up) ||
  809.       EQ (keysym, Qbutton6) || EQ (keysym, Qbutton6up) ||
  810.       EQ (keysym, Qbutton7) || EQ (keysym, Qbutton7up))
  811.     error ("Mouse-clicks can't appear in saved keyboard macros.");
  812.  
  813.   XEVENT (event)->channel = Qnil;
  814.   XEVENT (event)->event_type = key_press_event;
  815.   XEVENT (event)->event.key.key = keysym;
  816.   XEVENT (event)->event.key.modifiers = modifiers;
  817. }
  818.  
  819.  
  820. static int
  821. meta_prefix_char_p (keysym, modifiers)
  822.      Lisp_Object keysym;
  823.      int modifiers;
  824. {
  825.   struct Lisp_Event event;
  826.   if (meta_prefix_char < 0) return 0;
  827.   event.event_type = key_press_event;
  828.   event.event.key.key = keysym;
  829.   event.event.key.modifiers = modifiers;
  830.   return (meta_prefix_char == event_to_character (&event, 0));
  831. }
  832.  
  833.  
  834. /* ASCII grunge.
  835.    Given a keysym, return another keysym/modifier pair which could be 
  836.    considered the same key in an ASCII world.  Backspace returns ^H, for 
  837.    example.
  838.  */
  839. static void
  840. define_key_alternate_name (keysym, modifiers, keysym_ret, modifiers_ret)
  841.      Lisp_Object keysym, *keysym_ret;
  842.      int modifiers, *modifiers_ret;
  843. {
  844.   int modifiers_sans_control = (modifiers & (~MOD_CONTROL));
  845.   int modifiers_sans_meta = (modifiers & (~MOD_META));
  846.   *keysym_ret = Qnil;
  847.   *modifiers_ret = 0;
  848.   if (modifiers_sans_meta == MOD_CONTROL)
  849.     {
  850.       int k = XINT (keysym);
  851.       if EQ (keysym, QKspace)
  852.         *keysym_ret = make_number ('@'), *modifiers_ret = modifiers;
  853.       else if (!FIXNUMP (keysym))
  854.     ;
  855.       else if (k == '@')
  856.     *keysym_ret = QKspace,       *modifiers_ret = modifiers;
  857.       else if (k == 'h')
  858.     *keysym_ret = QKbackspace, *modifiers_ret = modifiers_sans_control;
  859.       else if (k == 'i')
  860.     *keysym_ret = QKtab,       *modifiers_ret = modifiers_sans_control;
  861.       else if (k == 'j')
  862.     *keysym_ret = QKlinefeed,  *modifiers_ret = modifiers_sans_control;
  863.       else if (k == 'm')
  864.     *keysym_ret = QKreturn,       *modifiers_ret = modifiers_sans_control;
  865.       else if (k == '[')
  866.     *keysym_ret = QKescape,       *modifiers_ret = modifiers_sans_control;
  867.     }
  868.   else if (modifiers_sans_meta)
  869.     ;
  870.   else if (EQ (keysym, QKbackspace))
  871.     *keysym_ret = make_number ('h'), *modifiers_ret = modifiers | MOD_CONTROL;
  872.   else if (EQ (keysym, QKtab))
  873.     *keysym_ret = make_number ('i'), *modifiers_ret = modifiers | MOD_CONTROL;
  874.   else if (EQ (keysym, QKlinefeed))
  875.     *keysym_ret = make_number ('j'), *modifiers_ret = modifiers | MOD_CONTROL;
  876.   else if (EQ (keysym, QKreturn))
  877.     *keysym_ret = make_number ('m'), *modifiers_ret = modifiers | MOD_CONTROL;
  878.   else if (EQ (keysym, QKescape))
  879.     *keysym_ret = make_number ('['), *modifiers_ret = modifiers | MOD_CONTROL;
  880. }
  881.  
  882.  
  883. static void
  884. ensure_meta_prefix_char_keymapp (keys, index, keymap)
  885.      Lisp_Object keys, keymap;
  886.      int index;
  887. {
  888.   char buf [255];
  889.   Lisp_Object new_keys;
  890.   Lisp_Object meta_sym;
  891.   int meta_mods, i;
  892.   Lisp_Object mpc_binding;
  893.   define_key_parser (meta_prefix_char, &meta_sym, &meta_mods);
  894.   mpc_binding = keymap_lookup_1 (keymap, meta_sym, meta_mods);
  895.   if (NILP (mpc_binding) || !NILP (Fkeymapp (mpc_binding)))
  896.     return;
  897.  
  898.   if (index == 0)
  899.     new_keys = keys;
  900.   else if (STRINGP (keys))
  901.     new_keys = Fsubstring (keys, 0, make_number (index));
  902.   else if (VECTORP (keys))
  903.     {
  904.       new_keys = Fmake_vector (make_number (index), Qnil);
  905.       for (i = 0; i < index; i++)
  906.     XVECTOR (new_keys)->contents [i] = XVECTOR (keys)->contents [i];
  907.     }
  908.   else
  909.     abort ();
  910.   if (EQ (keys, new_keys))
  911.     sprintf (buf, "can't bind %s: %s has a non-keymap binding",
  912.     (char *) XSTRING (Fkey_description (keys))->data,
  913.     (char *) XSTRING (Fsingle_key_description 
  914.                           (make_number (meta_prefix_char)))->data);
  915.   else
  916.     sprintf (buf, "can't bind %s: %s %s has a non-keymap binding",
  917.     (char *) XSTRING (Fkey_description (keys))->data,
  918.     (char *) XSTRING (Fkey_description (new_keys))->data,
  919.     (char *) XSTRING (Fsingle_key_description
  920.                           (make_number (meta_prefix_char)))->data);
  921.   signal_error (Qerror, list2 (build_string (buf), mpc_binding));
  922. }
  923.  
  924.  
  925. static Lisp_Object
  926. make_key_description (keysym, modifiers, prettify)
  927.      Lisp_Object keysym;
  928.      int modifiers;
  929.      int prettify;
  930. {
  931.   Lisp_Object result;
  932.   if (prettify && FIXNUMP (keysym))
  933.     {
  934.       /* This is a little slow, but (control a) is prettier than (control 65).
  935.      It's now ok to do this for digit-chars too, since we've fixed the
  936.      bug where \9 read as the integer 9 instead of as the symbol with
  937.      "9" as its name.
  938.        */
  939.       char str [2];
  940.       str[0] = XFASTINT (keysym);
  941.       str[1] = 0;
  942.       keysym = intern (str);
  943.     }
  944.   if (! modifiers) return keysym;
  945.   result = Fcons (keysym, Qnil);
  946.   if (modifiers & MOD_SHIFT) result = Fcons (Qshift, result);
  947.   if (modifiers & MOD_SYMBOL) result = Fcons (Qsymbol, result);
  948.   if (modifiers & MOD_HYPER) result = Fcons (Qhyper, result);
  949.   if (modifiers & MOD_SUPER) result = Fcons (Qsuper, result);
  950.   if (modifiers & MOD_CONTROL) result = Fcons (Qcontrol, result);
  951.   if (modifiers & MOD_META)  result = Fcons (Qmeta, result);
  952.   return result;
  953. }
  954.  
  955. /* This comment supplies the doc string for define-key,
  956.    for make-docfile to see.  We cannot put this in the real DEFUN
  957.    due to limits in the Unix cpp.
  958.  
  959. DEFUN ("define-key", Foo, Sfoo, 3, 3, 0,
  960.   "Args KEYMAP, KEYS, DEF.  Define key sequence KEYS, in KEYMAP, as DEF.\n\
  961. KEYMAP is a keymap object.\n\
  962. KEYS is the sequence of keystrokes to bind, described below.\n\
  963. DEF is anything that can be a key's definition:\n\
  964.  nil (means key is undefined in this keymap);\n\
  965.  a command (a Lisp function suitable for interactive calling);\n\
  966.  a string or key sequence vector (treated as a keyboard macro);\n\
  967.  a keymap (to define a prefix key);\n\
  968.  a symbol; when the key is looked up, the symbol will stand for its\n\
  969.     function definition, that should at that time be one of the above,\n\
  970.     or another symbol whose function definition is used, and so on.\n\
  971.  a cons (STRING . DEFN), meaning that DEFN is the definition\n\
  972.     (DEFN should be a valid definition in its own right);\n\
  973.  or a cons (KEYMAP . CHAR), meaning use definition of CHAR in map KEYMAP.\n\
  974. \n\
  975. Contrary to popular belief, the world is not ASCII.  When running under a\n\
  976. window manager, Emacs can tell the difference between, for example, the\n\
  977. keystrokes control-h, control-shift-h, and backspace.  You can, in fact,\n\
  978. bind different commands to each of these.\n\
  979. \n\
  980. A `key sequence' is a set of keystrokes.  A `keystroke' is a keysym and some\n\
  981. set of modifiers (such as control and meta).  A `keysym' is what is printed\n\
  982. on the keys on your keyboard.\n\
  983. \n\
  984. A keysym may be represented by a symbol, or (if and only if it is equivalent\n\
  985. to a printing ASCII character) by its ASCII code.  The `A' key may be\n\
  986. represented by the symbol `A' or by the number 65.  The `break' key may be\n\
  987. represented only by the symbol `break'.\n\
  988. \n\
  989. A keystroke may be represented by a list: the last element of the list is\n\
  990. the key (a symbol or number, as above) and the preceding elements are the\n\
  991. symbolic names of modifier keys (control, meta, super, hyper, and shift.)\n\
  992. Thus, the sequence control-b is represented by the forms `(control b)' \n\
  993. and `(control 98)'.  A keystroke may also be represented by an event object,\n\
  994. as returned by the `next-command-event' and `read-key-sequence' functions.\n\
  995. \n\
  996. Note that in this context, the keystroke `control-b' is *not* represented\n\
  997. by the number 2 (the ASCII code for ^B).  See below.\n\
  998. \n\
  999. The `shift' modifier is somewhat of a special case.  You should not (and\n\
  1000. cannot) use `(meta shift a)' to mean `(meta A)', since for characters that\n\
  1001. have printing ASCII equivalents, the state of the shift key is implicit in\n\
  1002. the keysym (a vs. A).  You also cannot say `(shift =)' to mean `+', as that\n\
  1003. sort of thing varies from keyboard to keyboard.  The shift modifier is for\n\
  1004. use only with characters that do not have a second keysym on the same key,\n\
  1005. such as `backspace' and `tab'.\n\
  1006. \n\
  1007. A key sequence is a vector of keystrokes.  As a degenerate case, elements\n\
  1008. of this vector may also be keysyms if they have no modifiers.  That is,\n\
  1009. the `A' keystroke is represented by all of these forms:\n\
  1010.     A    65    (A)    (65)    [A]    [65]    [(A)]    [(65)]\n\
  1011. the `control-a' keystroke is represented by these forms:\n\
  1012.     (control A)    (control 65)    [(control A)]    [(control 65)]\n\
  1013. the key sequence `control-c control-a' is represented by these forms:\n\
  1014.     [(control c) (control a)]    [(control 99) (control 65)]\n\
  1015. \n\
  1016. Mouse button clicks work just like keypresses: (control button1) means\n\
  1017. pressing the left mouse button while holding down the control key.\n\
  1018. [(control c) (shift button3)] means control-c, hold shift, click right.\n\
  1019. \n\
  1020. Commands may be bound to the mouse-button up-stroke rather than the down-\n\
  1021. stroke as well.  `button1' means the down-stroke, and `button1up' means the\n\
  1022. up-stroke.  Different commands may be bound to the up and down strokes,\n\
  1023. though that is probably not what you want, so be careful.\n\
  1024. \n\
  1025. For backward compatibility, a key sequence may also be represented by a\n\
  1026. string.  In this case, it represents the key sequence(s) that would\n\
  1027. produce that sequence of ASCII characters in a purely ASCII world.  For\n\
  1028. example, a string containing the ASCII backspace character, \"\\^H\", would\n\
  1029. represent two key sequences: `(control h)' and `backspace'.  Binding a\n\
  1030. command to this will actually bind both of those key sequences.  Likewise\n\
  1031. for the following pairs:\n\
  1032. \n\
  1033.         control h    backspace\n\
  1034.         control i       tab\n\
  1035.         control m       return\n\
  1036.         control j       linefeed\n\
  1037.         control [       escape\n\
  1038.         control @    control space\n\
  1039. \n\
  1040. After binding a command to two key sequences with a form like\n\
  1041. \n\
  1042.     (define-key global-map \"\\^X\\^I\" \'command-1)\n\
  1043. \n\
  1044. it is possible to redefine only one of those sequences like so:\n\
  1045. \n\
  1046.     (define-key global-map [(control x) (control i)] \'command-2)\n\
  1047.     (define-key global-map [(control x) tab] \'command-3)\n\
  1048. \n\
  1049. Of course, all of this applies only when running under a window system.  If\n\
  1050. you're talking to emacs through an ASCII-only channel, you don't get any of\n\
  1051. these features.")
  1052.   (keymap, keys, def)
  1053. */
  1054.  
  1055.  
  1056. DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 3, 0, 0
  1057.        /* See very large comment above */)
  1058.   (keymap, keys, def)
  1059.      Lisp_Object keymap;
  1060.      Lisp_Object keys;
  1061.      Lisp_Object def;
  1062. {
  1063.   int idx;
  1064.   int metized = 0;
  1065.   int size;
  1066.   int ascii_hack;
  1067.  
  1068.   if (VECTORP (keys))
  1069.     size = XVECTOR (keys)->size;
  1070.   else if (STRINGP (keys))
  1071.     size = XSTRING (keys)->size;
  1072.   else if (FIXNUMP (keys) || SYMBOLP (keys) || CONSP (keys))
  1073.     {
  1074.       if (!CONSP (keys)) keys = list1 (keys);
  1075.       size = 1;
  1076.       keys = Fmake_vector (1, keys); /* this is kinda sleazy. */
  1077.     }
  1078.   else
  1079.     {
  1080.       keys = wrong_type_argument (Qsequencep, keys);
  1081.       size = XFASTINT (Flength (keys));
  1082.     }
  1083.   if (size == 0)
  1084.     return (Qnil);
  1085.  
  1086.   /* ASCII grunge.
  1087.      When the user defines a key which, in a strictly ASCII world, would be
  1088.      produced by two different keys (^J and linefeed, or ^H and backspace,
  1089.      for example) then the binding will be made for both keysyms.
  1090.  
  1091.      This is done if the user binds a command to a string, as in
  1092.      (define-key map "\^H" 'something), but not when using one of the new
  1093.      syntaxes, like (define-key map '(control h) 'something).
  1094.    */
  1095.   ascii_hack = (STRINGP (keys));
  1096.  
  1097.   keymap = get_keymap (keymap, 1);
  1098.   idx = 0;
  1099.   while (1)
  1100.     {
  1101.       Lisp_Object c;
  1102.       Lisp_Object keysym, keysym2;
  1103.       int modifiers, modifiers2;
  1104.  
  1105.       if (STRINGP (keys))
  1106.     c = make_number (XSTRING (keys)->data [idx]);
  1107.       else {
  1108.     c = XVECTOR (keys)->contents [idx];
  1109.     if (FIXNUMP (c) &&
  1110.         (XINT (c) < ' ' || XINT (c) > 127))
  1111.       return
  1112.         Fsignal (Qerror,
  1113.              Fcons (build_string
  1114.                 ("keysym must be in the printing ASCII range"),
  1115.                 Fcons (c, Qnil)));
  1116.       }
  1117.  
  1118.       define_key_parser (c, &keysym, &modifiers);
  1119.  
  1120.       if (!metized
  1121.       && meta_prefix_char >= 0
  1122.       && (XFASTINT (c) == meta_prefix_char
  1123.               || meta_prefix_char_p (keysym, modifiers)))
  1124.     {
  1125.       if (idx == (size - 1))
  1126.         {
  1127.           /* This is a hack to prevent a binding for the meta-prefix-char
  1128.          from being made in a map which already has a non-empty "meta"
  1129.          submap.  That is, we can't let both "escape" and "meta" have
  1130.          a binding in the same keymap.  This implies that the idiom
  1131.               (define-key my-map "\e" my-escape-map)
  1132.               (define-key my-escape-map "a" 'my-command)
  1133.          no longer works.  That's ok.  Instead the luser should do
  1134.               (define-key my-map "\ea" 'my-command)
  1135.          or, more correctly
  1136.               (define-key my-map "\M-a" 'my-command)
  1137.          and then perhaps
  1138.               (defvar my-escape-map (lookup-key my-map "\e"))
  1139.          if the luser really wants the map in a variable.
  1140.            */
  1141.           Lisp_Object mmap = keymap_lookup_1 (keymap, Qmeta, 0);
  1142.           if (!NILP (mmap) &&
  1143.           keymap_fullness (XKEYMAP (get_keymap (mmap, 1))) != 0)
  1144.         {
  1145.                   Lisp_Object desc
  1146.                     = Fsingle_key_description (make_number (meta_prefix_char));
  1147.           signal_error (Qerror, list3 (build_string
  1148.                   ("Map contains meta-bindings, can't bind"),
  1149.                            desc, keymap));
  1150.         }
  1151.         }
  1152.       else
  1153.         {
  1154.           metized = 1;
  1155.           idx++;
  1156.           continue;
  1157.         }
  1158.     }
  1159.  
  1160.       if (ascii_hack)
  1161.     define_key_alternate_name (keysym, modifiers, &keysym2, &modifiers2);
  1162.       else
  1163.     keysym2 = Qnil;
  1164.       
  1165.       if (metized) {
  1166.     modifiers  |= MOD_META;
  1167.     modifiers2 |= MOD_META;
  1168.     metized = 0;
  1169.       }
  1170.  
  1171.       /* This crap is to make sure that someone doesn't bind something like
  1172.      "C-x M-a" while "C-x ESC" has a non-keymap binding. */
  1173.       if ((modifiers & MOD_META) && meta_prefix_char >= 0)
  1174.     ensure_meta_prefix_char_keymapp (keys, idx, keymap);
  1175.  
  1176.       if (++idx == size) {
  1177.     keymap_store (keymap, keysym, modifiers, def);
  1178.     if (ascii_hack && !NILP (keysym2))
  1179.       keymap_store (keymap, keysym2, modifiers2, def);
  1180.     return def;
  1181.       }
  1182.       
  1183.       {
  1184.         Lisp_Object cmd = keymap_lookup_1 (keymap, keysym, modifiers);
  1185.     if (NILP (cmd))
  1186.       {
  1187.         cmd = Fmake_sparse_keymap ();
  1188.         XKEYMAP (cmd)->name =
  1189.           list2 (make_key_description (keysym, modifiers, 1), keymap);
  1190.         keymap_store (keymap, keysym, modifiers, cmd);
  1191.       }
  1192.     if (NILP (Fkeymapp (cmd)))
  1193.           signal_error (Qerror,
  1194.                         list3 (build_string
  1195.                                ("invalid prefix keys in sequence"),
  1196.                                c, keys));
  1197.  
  1198.     if (ascii_hack && !NILP (keysym2) &&
  1199.         NILP (keymap_lookup_1 (keymap, keysym2, modifiers2)))
  1200.       keymap_store (keymap, keysym2, modifiers2, cmd);
  1201.  
  1202.     keymap = get_keymap (cmd, 1);
  1203.       }
  1204.     }
  1205. }
  1206.  
  1207.  
  1208. /* We need a very fast (i.e., non-consing) version of lookup-key in order 
  1209.    to make where-is-internal really fly.
  1210.  */
  1211.  
  1212. struct raw_key {
  1213.   unsigned int bits;
  1214.   Lisp_Object keysym;
  1215. };
  1216.  
  1217.  
  1218. static Lisp_Object
  1219. raw_lookup_key (Lisp_Object keymap,
  1220.                 const struct raw_key *raw_keys, int raw_keys_count,
  1221.                 int keys_so_far)
  1222. {
  1223.   Lisp_Object k = keymap;
  1224.   const Lisp_Object keysym = raw_keys[0].keysym;
  1225.   const int modifiers = raw_keys[0].bits;
  1226.   const int remaining = raw_keys_count - 1;
  1227.  
  1228.   /* Loop over keymap and parents */
  1229.   while (1)
  1230.     {
  1231.       /* Do depth-first search */
  1232.       Lisp_Object cmd;
  1233.       int parental_unit;
  1234.       QUIT;
  1235.       k = get_keymap (k, 1);
  1236.       parental_unit = (! NILP (XKEYMAP (k)->parent));
  1237.       
  1238.       if (meta_prefix_char < 0 || ! meta_prefix_char_p (keysym, modifiers))
  1239.     {
  1240.       /* Normal case: every case except the meta-hack (see below). */
  1241.       cmd = keymap_lookup_1 (k, keysym, modifiers);
  1242.       
  1243.       if (remaining == 0)
  1244.         /* Return whatever we found if we're out of keys */
  1245.         ;
  1246.       else if (NILP (cmd))
  1247.         /* Found nothing (though perhaps parent map may have binding) */
  1248.         ;
  1249.       else if (NILP (Fkeymapp (cmd)))
  1250.         /* Didn't find a keymap, and we have more keys.
  1251.          * Return a fixnum to indicate that keys were too long.
  1252.          */
  1253.         cmd = make_number (keys_so_far + 1);
  1254.       else if (parental_unit)
  1255.         /* Durst hope for tail-recursion? */
  1256.         return (raw_lookup_key (cmd, raw_keys + 1, remaining, 
  1257.                     keys_so_far + 1));
  1258.       else
  1259.         cmd = raw_lookup_key (cmd, raw_keys + 1, remaining, 
  1260.                   keys_so_far + 1);
  1261.     }
  1262.       else
  1263.     {
  1264.       /* This is a hack so that looking up a key-sequence whose last
  1265.        * element is the meta-prefix-char will return the keymap that
  1266.        * the "meta" keys are stored in, if there is no binding for
  1267.        * the meta-prefix-char (and if this map has a "meta" submap.)
  1268.        * If this map doesnt have a "meta" submap, then the
  1269.        * meta-prefix-char is looked up just like any other key.
  1270.        */
  1271.       if (remaining == 0)
  1272.         {
  1273.           /* First look for the prefix-char directly */
  1274.           cmd = keymap_lookup_1 (k, keysym, modifiers);
  1275.           if (NILP (cmd))
  1276.         /* Do kludgy return of the meta-map */ 
  1277.         cmd = keymap_lookup_1 (k, Qmeta, 0);
  1278.         }
  1279.       else
  1280.         {
  1281.           /* Search for the prefix-char-prefixed sequence directly */
  1282.           cmd = keymap_lookup_1 (k, keysym, modifiers);
  1283.           if (!NILP (cmd))
  1284.         cmd = get_keymap (cmd, 0);
  1285.           if (!NILP (cmd))
  1286.         cmd = raw_lookup_key (cmd, raw_keys + 1, remaining, 
  1287.                       keys_so_far + 1);
  1288.           else if ((raw_keys[1].bits & MOD_META) == 0)
  1289.         {
  1290.           /* Search for meta-next-char sequence directly */
  1291.           cmd = keymap_lookup_1 (k, 
  1292.                      raw_keys[1].keysym, 
  1293.                      raw_keys[1].bits | MOD_META);
  1294.           if (remaining == 1)
  1295.             ;
  1296.           else if (NILP (cmd))
  1297.             ;
  1298.           else if (NILP (Fkeymapp (cmd)))
  1299.             cmd = make_number (keys_so_far + 2);
  1300.           else if (parental_unit)
  1301.             /* Durst hope for tail-recursion? */
  1302.             return (raw_lookup_key (cmd, raw_keys + 2, remaining - 1,
  1303.                         keys_so_far + 2));
  1304.           else
  1305.             cmd = raw_lookup_key (cmd, raw_keys + 2, remaining - 1,
  1306.                       keys_so_far + 2);
  1307.         }
  1308.         }
  1309.     }
  1310.       if (!NILP (cmd))
  1311.     return (cmd);
  1312.       if (!parental_unit)
  1313.     return (Qnil);
  1314.       k = XKEYMAP (k)->parent;
  1315.     }
  1316. }
  1317.  
  1318.  
  1319. static struct raw_key *lookup_key_buf;
  1320. static int lookup_key_buf_total_size;
  1321.  
  1322. /* Value is number if `keys' is too long; NIL if valid but has no definition. 
  1323. */
  1324. DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 2, 0,
  1325.   "In keymap KEYMAP, look up key sequence KEYS.  Return the definition.\n\
  1326. nil means undefined.  See doc of `define-key' for kinds of definitions\n\
  1327. and key-sequence specifications.\n\
  1328. Number as value means KEYS is \"too long\";\n\
  1329. that is, characters in it except for the last one\n\
  1330. fail to be a valid sequence of prefix characters in KEYMAP.\n\
  1331. The number is how many characters at the front of KEYS\n\
  1332. it takes to reach a non-prefix command.")
  1333.   (keymap, keys)
  1334.      register Lisp_Object keymap;
  1335.      Lisp_Object keys;
  1336. {
  1337.   Lisp_Object c;
  1338.   int i = 0;
  1339.   int size;
  1340.   Lisp_Object keysym;
  1341.   int modifiers;
  1342.  
  1343.   if (STRINGP (keys))
  1344.     size = XSTRING (keys)->size;
  1345.   else if (VECTORP (keys))
  1346.     size = XVECTOR (keys)->size;
  1347.   else if (FIXNUMP (keys) || SYMBOLP (keys))
  1348.     size = 1;
  1349.   else
  1350.     {
  1351.       keys = wrong_type_argument (Qsequencep, keys);
  1352.       size = XINT (Flength (keys));
  1353.     }
  1354.  
  1355.   if (size == 0) return Qnil;
  1356.  
  1357.   if (size >= lookup_key_buf_total_size)
  1358.     {
  1359.       lookup_key_buf_total_size = size + 50;
  1360.       lookup_key_buf = (struct raw_key *)
  1361.     xrealloc (lookup_key_buf, sizeof (struct raw_key) *
  1362.           lookup_key_buf_total_size);
  1363.     }
  1364.  
  1365.   for (i = 0; i < size; i++)
  1366.     {
  1367.       if (STRINGP (keys))
  1368.     c = make_number ((unsigned char) XSTRING (keys)->data [i]);
  1369.       else if (VECTORP (keys))
  1370.     c = XVECTOR (keys)->contents [i];
  1371.       else if (FIXNUMP (keys) || SYMBOLP (keys))
  1372.     c = keys;
  1373.       else
  1374.     abort ();
  1375.       define_key_parser (c, &keysym, &modifiers);
  1376.       lookup_key_buf[i].keysym = keysym;
  1377.       lookup_key_buf[i].bits = modifiers;
  1378.     }
  1379.   return raw_lookup_key (keymap, lookup_key_buf, size, 0);
  1380. }
  1381.  
  1382.  
  1383. extern Lisp_Object Vmouse_grabbed_buffer;
  1384.  
  1385. DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 1, 0,
  1386.   "Return the binding for command KEYS in current keymaps.\n\
  1387. KEYS is a string, a vector of events, or a vector of key-description lists\n\
  1388. as described in the documentation for the `define-key' function.\n\
  1389. The binding is probably a symbol with a function definition.")
  1390.   (keys)
  1391.      Lisp_Object keys;
  1392. {
  1393.   Lisp_Object map, value;
  1394.   int mouse_p = 0;
  1395.   Lisp_Object mouse_buffer = Qnil;
  1396.  
  1397.   /* If this is a mouse-click event, then the "local" keymap is considered
  1398.      to be the local map of the buffer in the window over which the mouse
  1399.      was clicked, not necessarily the window which point is in.
  1400.    */
  1401.   if ((VECTORP (keys) && XVECTOR (keys)->size > 0))
  1402.     {
  1403.       Lisp_Object event = XVECTOR (keys)->contents [XVECTOR (keys)->size - 1];
  1404.       if (EVENTP (event) &&
  1405.       (XEVENT (event)->event_type == button_press_event ||
  1406.        XEVENT (event)->event_type == button_release_event))
  1407.     {
  1408.       Lisp_Object window = Fevent_window (event);
  1409.       if (!NILP (window))
  1410.         mouse_buffer = Fwindow_buffer (window);
  1411.       mouse_p = 1;
  1412.     }
  1413.     }
  1414.  
  1415.   /* If this is a mouse-click event, and if `mouse-grabbed-buffer' is a
  1416.      buffer, then it is consulted before either the local map (in this
  1417.      case, the map of the buffer of the window under point) or the global
  1418.      map.  (The motion-handling code also consults mouse-grabbed-buffer.)
  1419.    */
  1420.   if (mouse_p && BUFFERP (Vmouse_grabbed_buffer))
  1421.     {
  1422.       Lisp_Object grabbed_map = XBUFFER (Vmouse_grabbed_buffer)->keymap;
  1423.       if (!NILP (grabbed_map))
  1424.     {
  1425.       value = Flookup_key (grabbed_map, keys);
  1426.       if (!NILP (value) && !FIXNUMP (value))
  1427.         return value;
  1428.     }
  1429.     }
  1430.  
  1431.   /* If it's a mouse event, the local-map of the current buffer is not
  1432.      consulted at all (unless the mouse is over this buffer.) */
  1433.   if (NILP (mouse_buffer))
  1434.     map = current_buffer->keymap;
  1435.   else
  1436.     map = XBUFFER (mouse_buffer)->keymap;
  1437.  
  1438.   if (!NILP (map))
  1439.     {
  1440.       value = Flookup_key (map, keys);
  1441.       if (! NILP (value) && !FIXNUMP (value))
  1442.     return value;
  1443.     }
  1444.   map = Vcurrent_global_map;
  1445.   value = Flookup_key (map, keys);
  1446.   if (FIXNUMP (value))
  1447.     return Qnil;
  1448.   return value;
  1449. }
  1450.  
  1451.  
  1452. DEFUN ("use-global-map", Fuse_global_map, Suse_global_map, 1, 1, 0,
  1453.   "Select KEYMAP as the global keymap.")
  1454.   (keymap)
  1455.      Lisp_Object keymap;
  1456. {
  1457.   keymap = get_keymap (keymap, 1);
  1458.   Vcurrent_global_map = keymap;
  1459.   return Qnil;
  1460. }
  1461.  
  1462. DEFUN ("use-local-map", Fuse_local_map, Suse_local_map, 1, 1, 0,
  1463.   "Select KEYMAP as the local keymap.\n\
  1464. If KEYMAP is nil, that means no local keymap.")
  1465.   (keymap)
  1466.      Lisp_Object keymap;
  1467. {
  1468.   if (!NILP (keymap))
  1469.     keymap = get_keymap (keymap, 1);
  1470.  
  1471.   current_buffer->keymap = keymap;
  1472.  
  1473.   return Qnil;
  1474. }
  1475.  
  1476. DEFUN ("current-local-map", Fcurrent_local_map, Scurrent_local_map, 0, 0, 0,
  1477.   "Return current buffer's local keymap, or nil if it has none.")
  1478.   ()
  1479. {
  1480.   return current_buffer->keymap;
  1481. }
  1482.  
  1483. DEFUN ("current-global-map", Fcurrent_global_map, Scurrent_global_map, 0, 0, 0,
  1484.   "Return the current global keymap.")
  1485.   ()
  1486. {
  1487.   return (Vcurrent_global_map);
  1488. }
  1489.  
  1490.  
  1491. /* Since keymaps are arranged in a hierarchy, one keymap per bucky bit or
  1492.    prefix key, it's not entirely objvious what map-keymap should do, but 
  1493.    what it does is: map over all keys in this map; then recursively map
  1494.    over all submaps of this map that are "bucky" submaps.  This means that,
  1495.    when mapping over a keymap, it appears that "x" and "C-x" are in the
  1496.    same map, although "C-x" is really in the "control" submap of this one.
  1497.    However, since we don't recursively descend the submaps that are bound
  1498.    to prefix keys (like C-x, C-h, etc) the caller will have to recurse on
  1499.    those explicitly, if that's what they want.
  1500.  
  1501.    So the end result of this is that the bucky keymaps (the ones indexed
  1502.    under the symbols control, meta, super, hyper, symbol, and shift) are
  1503.    invisible from elisp.  They're just an implementation detail that code
  1504.    outside of this file doesn't need to know about.
  1505.  */
  1506.  
  1507. struct map_keymap_closure {
  1508.   void (*fn) ();
  1509.   void *arg;
  1510.   int bits;
  1511. };
  1512.  
  1513. /* used by map_keymap() */
  1514. static void
  1515. map_keymap_unsorted_mapper (hash_key, hash_contents, junk)
  1516.      void *hash_key, *hash_contents, *junk;
  1517. {
  1518.   Lisp_Object key = (Lisp_Object) hash_key;
  1519.   Lisp_Object contents = (Lisp_Object) hash_contents;
  1520.   struct map_keymap_closure *closure = (struct map_keymap_closure *) junk;
  1521.   int modifiers = closure->bits;
  1522.   int mod_bit = bucky_sym_to_bucky_bit (key);
  1523.   if (mod_bit)
  1524.     {
  1525.       int omod = modifiers;
  1526.       closure->bits = modifiers | mod_bit;
  1527.       contents = get_keymap (contents, 1);
  1528.       CHECK_KEYMAP (contents, 0);
  1529.       elisp_maphash (map_keymap_unsorted_mapper,
  1530.              XKEYMAP (contents)->table,
  1531.              junk);
  1532.       closure->bits = omod;
  1533.     }
  1534.   else
  1535.     (*closure->fn) (key, modifiers, contents, closure->arg);
  1536. }
  1537.  
  1538.  
  1539. /* used by map_keymap_sorted() */
  1540. static void
  1541. map_keymap_sorted_mapper (hash_key, hash_contents, closure)
  1542.      void *hash_key, *hash_contents, *closure;
  1543. {
  1544.   Lisp_Object key = (Lisp_Object) hash_key;
  1545.   Lisp_Object contents = (Lisp_Object) hash_contents;
  1546.   Lisp_Object *list = (Lisp_Object *) closure;
  1547.   *list = Fcons (Fcons (key, contents), *list);
  1548. }
  1549.  
  1550.  
  1551. /* used by map_keymap_sorted(), describe_vector_sort_predicate(),
  1552.    and keymap_submaps().
  1553.  */
  1554. static int
  1555. map_keymap_sort_predicate (obj1, obj2, pred)
  1556.      Lisp_Object obj1, obj2, pred;
  1557. {
  1558.   /* obj1 and obj2 are conses with keysyms in their cars.  Cdrs are ignored.
  1559.    */
  1560.   int bit1, bit2;
  1561.   int sym1_p = 0, sym2_p = 0;
  1562.   obj1 = XCONS (obj1)->car;
  1563.   obj2 = XCONS (obj2)->car;
  1564.   if (obj1 == obj2) return -1;
  1565.  
  1566.   bit1 = bucky_sym_to_bucky_bit (obj1);
  1567.   bit2 = bucky_sym_to_bucky_bit (obj2);
  1568.   
  1569.   /* If either is a symbol with a character-set-property, then sort it by
  1570.      that code instead of alphabetically.
  1571.    */
  1572.   if (! bit1 && SYMBOLP (obj1))
  1573.     {
  1574.       Lisp_Object code = Fget (obj1, Vcharacter_set_property);
  1575.       if (FIXNUMP (code))
  1576.     obj1 = code, sym1_p = 1;
  1577.     }
  1578.   if (! bit2 && SYMBOLP (obj2))
  1579.     {
  1580.       Lisp_Object code = Fget (obj2, Vcharacter_set_property);
  1581.       if (FIXNUMP (code))
  1582.     obj2 = code, sym2_p = 1;
  1583.     }
  1584.  
  1585.   /* all symbols (non-ASCIIs) come after integers (ASCIIs) */
  1586.   if (XTYPE (obj1) != XTYPE (obj2))
  1587.     return ((SYMBOLP (obj2)) ? 1 : -1);
  1588.  
  1589.   if (FIXNUMP (obj1)) /* they're both ASCII */
  1590.     {
  1591.       if (obj1 == obj2 &&    /* If one started out as a symbol and the */
  1592.       sym1_p != sym2_p)    /* other didn't, the symbol comes last. */
  1593.     return (sym2_p ? 1 : -1);
  1594.  
  1595.     return ((obj1 < obj2) ? 1 : -1);    /* else just compare them */
  1596.     }
  1597.  
  1598.   /* else they're both symbols.  If they're both buckys, then order them. */
  1599.   if (bit1 && bit2)
  1600.     return ((bit1 < bit2) ? 1 : -1);
  1601.   
  1602.   /* if only one is a bucky, then it comes later */
  1603.   if (bit1 || bit2)
  1604.     return (bit2 ? 1 : -1);
  1605.  
  1606.   /* otherwise, string-sort them. */
  1607.   return ((0 > strcmp ((char *) XSYMBOL (obj1)->name->data,
  1608.                (char *) XSYMBOL (obj2)->name->data))
  1609.       ? 1 : -1);
  1610. }
  1611.  
  1612.  
  1613. /* used by map_keymap() */
  1614. static void
  1615. map_keymap_sorted (keymap, bits, function, closure)
  1616.      struct Lisp_Keymap *keymap;
  1617.      int bits;
  1618.      void (*function) ();
  1619.      void *closure;
  1620. {
  1621.   struct gcpro gcpro1, gcpro2, gcpro3;
  1622.   Lisp_Object key, binding;
  1623.   Lisp_Object contents = Qnil;
  1624.   int sub_bit;
  1625.   if (! XFASTINT (Fhashtable_fullness (keymap->table)))
  1626.     return;
  1627.   GCPRO3 (key, binding, contents);
  1628.   elisp_maphash (map_keymap_sorted_mapper, keymap->table, (void *) &contents);
  1629.   contents = list_sort (contents, Qnil, map_keymap_sort_predicate);
  1630.   for (; !NILP (contents); contents = XCONS (contents)->cdr)
  1631.     {
  1632.       key = XCONS (XCONS (contents)->car)->car;
  1633.       binding = XCONS (XCONS (contents)->car)->cdr;
  1634.       sub_bit = bucky_sym_to_bucky_bit (key);
  1635.       if (sub_bit)
  1636.     map_keymap_sorted (XKEYMAP (get_keymap (binding, 1)), bits | sub_bit,
  1637.                function, closure);
  1638.       else
  1639.     (*function) (key, bits, binding, closure);
  1640.     }
  1641.   UNGCPRO;
  1642. }
  1643.  
  1644.  
  1645. /* externally callable; used by Fmap_keymap() */
  1646. void
  1647. map_keymap (keymap, sort_first, function, fn_arg)
  1648.      struct Lisp_Keymap *keymap;
  1649.      int sort_first;
  1650.      void (*function) ();
  1651.      void *fn_arg;
  1652. {
  1653.   if (sort_first)
  1654.     map_keymap_sorted (keymap, 0, function, fn_arg);
  1655.   else
  1656.     {
  1657.       struct map_keymap_closure closure;
  1658.       closure.fn = function;
  1659.       closure.arg = fn_arg;
  1660.       closure.bits = 0;
  1661.       elisp_maphash (map_keymap_unsorted_mapper, keymap->table,
  1662.              (void *) &closure);
  1663.     }
  1664. }
  1665.  
  1666. /* used by Fmap_keymap() */
  1667. static void
  1668. map_keymap_mapper (key, bits, binding, function)
  1669.      Lisp_Object key, binding;
  1670.      int bits;
  1671.      void *function;
  1672. {
  1673.   call2 ((Lisp_Object) function,
  1674.      make_key_description (key, bits, 1),
  1675.      binding);
  1676. }
  1677.  
  1678.  
  1679. DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 3, 0,
  1680.   "Apply FUNCTION to each element of KEYMAP.  FUNCTION will be called with\n\
  1681. two arguments: a key-description list, and the binding.  The order in which\n\
  1682. the elements of the keymap are passed to the function is unspecified.  If\n\
  1683. the function inserts new elements into the keymap, it may or may not\n\
  1684. be called with them later.  No element of the keymap will ever be passed to\n\
  1685. the function more than once.\n\
  1686. \n\
  1687. The function will not be called on elements of this keymap's parent (see the\n\
  1688. function `keymap-parent') or upon keymaps which are contained within this\n\
  1689. keymap (multi-character definitions).  It will be called on \"meta\"\n\
  1690. characters, however, since they are not really two-character sequences.\n\
  1691. \n\
  1692. If the optional third argument SORT-FIRST is non-nil, then the elements of\n\
  1693. the keymap will be passed to the mapper function in a canonical order.\n\
  1694. Otherwise, they will be passed in hash (that is, random) order, which is\n\
  1695. faster.")
  1696.      (function, keymap, sort_first)
  1697.     Lisp_Object function, keymap, sort_first;
  1698. {
  1699.   if (!NILP (Fkeymapp (function))) /* tolerate obviously transposed args */
  1700.     {
  1701.       Lisp_Object tmp = function;
  1702.       function = keymap;
  1703.       keymap = tmp;
  1704.     }
  1705.   keymap = get_keymap (keymap, 1);
  1706.   map_keymap (XKEYMAP (keymap), !NILP (sort_first),
  1707.           map_keymap_mapper, (void *) function);
  1708.   return Qnil;
  1709. }
  1710.  
  1711.  
  1712.  
  1713. /* we use this global as scratch space because the alternative is even
  1714.    uglier... (ok, well, we could define a struct and pass it instead...)
  1715.  */
  1716. static Lisp_Object accessible_keymaps_tail;
  1717.  
  1718. static int
  1719. bucky_sym_to_bucky_bit (sym)
  1720.      Lisp_Object sym;
  1721. {
  1722.   if (EQ (sym, Qcontrol)) return MOD_CONTROL;
  1723.   else if (EQ (sym, Qmeta)) return MOD_META;
  1724.   else if (EQ (sym, Qsuper)) return MOD_SUPER;
  1725.   else if (EQ (sym, Qhyper)) return MOD_HYPER;
  1726.   else if (EQ (sym, Qsymbol)) return MOD_SYMBOL;
  1727.   else if (EQ (sym, Qshift)) return MOD_SHIFT;
  1728.   else return 0;
  1729. }
  1730.  
  1731. static void
  1732. accessible_keymaps_mapper (hash_key, hash_contents, closure)
  1733.      void *hash_key, *hash_contents, *closure;
  1734. {
  1735.   Lisp_Object key = (Lisp_Object) hash_key;
  1736.   Lisp_Object contents = (Lisp_Object) hash_contents;
  1737.   int modifiers = (int) closure;
  1738.  
  1739.   Lisp_Object thisseq, cmd, vec;
  1740.   int j, bit = bucky_sym_to_bucky_bit (key);
  1741.   if (bit)
  1742.     {
  1743.       Lisp_Object submaps;
  1744.       contents = get_keymap (contents, 1);
  1745.       submaps = keymap_submaps (XKEYMAP (contents));
  1746.       for (; !NILP (submaps); submaps = XCONS (submaps)->cdr)
  1747.     {
  1748.       accessible_keymaps_mapper ((void *)XCONS (XCONS (submaps)->car)->car,
  1749.                      (void *)XCONS (XCONS (submaps)->car)->cdr,
  1750.                      (void *)(bit | modifiers));
  1751.     }
  1752.       return;
  1753.     }
  1754.   cmd = get_keyelt (contents);
  1755.   if (NILP (cmd))
  1756.     abort ();
  1757.   if (NILP (Fkeymapp (cmd)))
  1758.     abort ();
  1759.   cmd = get_keymap (cmd, 1);
  1760.   thisseq = Fcar (Fcar (accessible_keymaps_tail));
  1761.  
  1762.   vec = Fmake_vector (make_number (XVECTOR (thisseq)->size + 1), Qnil);
  1763.   for (j = 0; j < XVECTOR (thisseq)->size; j++)
  1764.     XVECTOR (vec)->contents [j] = XVECTOR (thisseq)->contents [j];
  1765.   XVECTOR (vec)->contents [j] = make_key_description (key, modifiers, 1);
  1766.   nconc2 (accessible_keymaps_tail, Fcons (Fcons (vec, cmd), Qnil));
  1767. }
  1768.  
  1769.  
  1770. DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps,
  1771.   1, 1, 0,
  1772.   "Find all keymaps accessible via prefix characters from KEYMAP.\n\
  1773. Returns a list of elements of the form (KEYS . MAP), where the sequence\n\
  1774. KEYS starting from KEYMAP gets you to MAP.  These elements are ordered\n\
  1775. so that the KEYS increase in length.  The first element is ([] . KEYMAP).")
  1776.   (startmap)
  1777.      Lisp_Object startmap;
  1778. {
  1779.   Lisp_Object accessible_keymaps =
  1780.     list1 (Fcons (Fmake_vector (make_number (0), Qnil),
  1781.           get_keymap (startmap, 1)));
  1782.   accessible_keymaps_tail = accessible_keymaps;
  1783.  
  1784.   /* For each map in the list maps,
  1785.      look at any other maps it points to
  1786.      and stick them at the end if they are not already in the list */
  1787.  
  1788.   for (accessible_keymaps_tail = accessible_keymaps;
  1789.        !NILP (accessible_keymaps_tail);
  1790.        accessible_keymaps_tail = XCONS (accessible_keymaps_tail)->cdr)
  1791.     {
  1792. /*    Lisp_Object thisseq = Fcar (Fcar (accessible_keymaps_tail)); */
  1793.       Lisp_Object thismap = Fcdr (Fcar (accessible_keymaps_tail));
  1794.       CHECK_KEYMAP (thismap, 0);
  1795.       for (; !NILP (thismap); thismap = XKEYMAP (thismap)->parent)
  1796.     {
  1797.       Lisp_Object submaps = keymap_submaps (XKEYMAP (thismap));
  1798.       for (; !NILP (submaps); submaps = XCONS (submaps)->cdr)
  1799.         accessible_keymaps_mapper((void *)XCONS(XCONS (submaps)->car)->car,
  1800.                       (void *)XCONS(XCONS (submaps)->car)->cdr,
  1801.                       (void *) 0);
  1802.     }
  1803.     }
  1804.   return accessible_keymaps;
  1805. }
  1806.  
  1807.  
  1808.  
  1809. DEFUN ("key-description", Fkey_description, Skey_description, 1, 1, 0,
  1810.   "Return a pretty description of key-sequence KEYS.\n\
  1811. Control characters turn into \"C-foo\" sequences, meta into \"M-foo\"\n\
  1812. spaces are put between sequence elements, etc.")
  1813.   (keys)
  1814.      Lisp_Object keys;
  1815. {
  1816.   if (FIXNUMP (keys) || CONSP (keys) || SYMBOLP (keys) || EVENTP (keys))
  1817.     {
  1818.       return Fsingle_key_description (keys);
  1819.     }
  1820.   else if (VECTORP (keys) ||
  1821.        STRINGP (keys))
  1822.     {
  1823.       Lisp_Object string = Qnil;
  1824.       Lisp_Object sep = Qnil;
  1825.       Lisp_Object s2;
  1826.       int i;
  1827.       int size = XFASTINT (Flength (keys));
  1828.       for (i = 0; i < size; i++)
  1829.     {
  1830.       s2 = Fsingle_key_description
  1831.         (((STRINGP (keys))
  1832.           ? make_number ((unsigned char) XSTRING (keys)->data[i])
  1833.           : XVECTOR (keys)->contents[i]));
  1834.  
  1835.       if (NILP (string))
  1836.         string = s2;
  1837.       else
  1838.         {
  1839.           if (NILP (sep)) sep = build_string (" ");
  1840.           string = concat2 (string, concat2 (sep, s2));
  1841.         }
  1842.     }
  1843.       return string;
  1844.     }
  1845.   else
  1846.     {
  1847.       return Fkey_description (wrong_type_argument (Qsequencep, keys));
  1848.     }
  1849. }
  1850.  
  1851. DEFUN ("single-key-description", Fsingle_key_description,
  1852.        Ssingle_key_description, 1, 1, 0,
  1853.   "Return a pretty description of command character KEY.\n\
  1854. Control characters turn into C-whatever, etc.")
  1855.   (key)
  1856.      Lisp_Object key;
  1857. {
  1858.   if (SYMBOLP (key))
  1859.     key = Fcons (key, Qnil); /* sleaze sleaze */
  1860.  
  1861.   if (EVENTP (key) || FIXNUMP (key))
  1862.     {
  1863.       char buf [255];
  1864.       if (FIXNUMP (key))
  1865.     {
  1866.       struct Lisp_Event event;
  1867.       event.event_type = empty_event;
  1868.       character_to_event (XINT (key), &event);
  1869.       format_event_object (buf, &event, 1);
  1870.     }
  1871.       else
  1872.     format_event_object (buf, XEVENT (key), 1);
  1873.       return (build_string (buf));
  1874.     }
  1875.  
  1876.   else if (CONSP (key))
  1877.     {
  1878.       char buf [255];
  1879.       char *bufp = buf;
  1880.       Lisp_Object rest;
  1881.       buf[0]=0;
  1882.       for (rest = key; !NILP (rest); rest = XCONS (rest)->cdr)
  1883.     {
  1884.       Lisp_Object keysym = XCONS (rest)->car;
  1885.       if (EQ (keysym, Qcontrol))    strcpy (bufp, "C-"), bufp += 2;
  1886.       else if (EQ (keysym, Qctrl))  strcpy (bufp, "C-"), bufp += 2;
  1887.       else if (EQ (keysym, Qmeta))  strcpy (bufp, "M-"), bufp += 2;
  1888.       else if (EQ (keysym, Qsuper)) strcpy (bufp, "S-"), bufp += 2;
  1889.       else if (EQ (keysym, Qhyper)) strcpy (bufp, "H-"), bufp += 2;
  1890.       else if (EQ (keysym, Qsymbol)) strcpy (bufp, "Sym-"), bufp += 4;
  1891.       else if (EQ (keysym, Qshift)) strcpy (bufp, "Sh-"), bufp += 3;
  1892.       else if (FIXNUMP (keysym))
  1893.         *bufp = XINT (keysym), bufp++, *bufp = 0;
  1894.       else
  1895.         {
  1896.           CHECK_SYMBOL (keysym, 0);
  1897.           if (EQ (keysym, QKlinefeed))    strcpy (bufp, "LFD");
  1898.           else if (EQ (keysym, QKtab))    strcpy (bufp, "TAB");
  1899.           else if (EQ (keysym, QKreturn))    strcpy (bufp, "RET");
  1900.           else if (EQ (keysym, QKescape))    strcpy (bufp, "ESC");
  1901.           else if (EQ (keysym, QKdelete))    strcpy (bufp, "DEL");
  1902.           else if (EQ (keysym, QKspace))    strcpy (bufp, "SPC");
  1903.           else if (EQ (keysym, QKbackspace))    strcpy (bufp, "BS");
  1904.           else
  1905.         strcpy (bufp, (char *) XSYMBOL (keysym)->name->data);
  1906.           if (!NILP (XCONS (rest)->cdr))
  1907.         signal_error (Qerror,
  1908.                   list2 (build_string ("invalid key description"),
  1909.                      key));
  1910.         }
  1911.     }
  1912.       return build_string (buf);
  1913.     }
  1914.   else
  1915.     {
  1916.       return Fsingle_key_description
  1917.     (wrong_type_argument (intern ("char-or-event-p"), key));
  1918.     }
  1919. }
  1920.  
  1921. static char *
  1922. push_text_char_description (c, p)
  1923.      register unsigned int c;
  1924.      register char *p;
  1925. {
  1926.   if (c >= 0200)
  1927.     {
  1928.       *p++ = 'M';
  1929.       *p++ = '-';
  1930.       c -= 0200;
  1931.     }
  1932.   if (c < 040)
  1933.     {
  1934.       *p++ = '^';
  1935.       *p++ = c + 64;        /* 'A' - 1 */
  1936.     }
  1937.   else if (c == 0177)
  1938.     {
  1939.       *p++ = '^';
  1940.       *p++ = '?';
  1941.     }
  1942.   else
  1943.     *p++ = c;
  1944.   return p;  
  1945. }
  1946.  
  1947. DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, 1, 1, 0,
  1948.   "Return a pretty description of file-character CHAR.\n\
  1949. Control characters turn into \"^char\", etc.")
  1950.   (chr)
  1951.      Lisp_Object chr;
  1952. {
  1953.   char tem[20];
  1954.  
  1955.   if (EVENTP (chr))
  1956.     {
  1957.       Lisp_Object ch = Fevent_to_character (chr, Qt);
  1958.       if (NILP (ch))
  1959.     return
  1960.       Fsignal (Qerror,
  1961.            list2 (build_string ("character has no ASCII equivalent"),
  1962.                           Fcopy_event (chr, Qnil)));
  1963.       chr = ch;
  1964.     }
  1965.  
  1966.   CHECK_FIXNUM (chr, 0);
  1967.  
  1968.   *push_text_char_description (XINT (chr) & 0377, tem) = 0;
  1969.  
  1970.   return build_string (tem);
  1971. }
  1972.  
  1973.  
  1974.  
  1975. static Lisp_Object where_is_recursive ();
  1976.  
  1977. DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0,
  1978.   "Return list of keys that invoke DEFINITION in optional 2nd argument KEYMAP\n\
  1979. or optional 4th argument GLOBAL_KEYMAP.\n\
  1980. If KEYMAP is nil, search only GLOBAL_KEYMAP.\n\
  1981. If GLOBAL_KEYMAP is nil, use the current global map.\n\
  1982. \n\
  1983. If optional 3rd arg FIRSTONLY is non-nil,\n\
  1984. return the first key sequence found, rather than a list of all possible\n\
  1985. key sequences.")
  1986.   (definition, local_keymap, firstonly, global_keymap, noindirect)
  1987.      Lisp_Object definition, local_keymap, global_keymap;
  1988.      Lisp_Object firstonly, noindirect;
  1989. {
  1990.   Lisp_Object found [2];
  1991.   if (NILP (global_keymap))
  1992.     global_keymap = Vcurrent_global_map;
  1993.   if (EQ (local_keymap, global_keymap))
  1994.     local_keymap = Qnil;
  1995.  
  1996.   if (NILP (local_keymap))
  1997.     found[0] = Qnil;
  1998.   else
  1999.     found[0] = where_is_recursive (definition, local_keymap, Qnil,
  2000.                    firstonly, 0, 0, 0);
  2001.  
  2002.   if (!NILP (firstonly) && !NILP (found[0]))
  2003.     return found[0];
  2004.  
  2005.   found[1] = where_is_recursive (definition, global_keymap, local_keymap,
  2006.                  firstonly, 0, 0, 0);
  2007.   if (!NILP (firstonly))
  2008.     return found[1];
  2009.   else if (NILP (found[1]))
  2010.     return found[0];
  2011.   else if (NILP (found[0]))
  2012.     return found[1];
  2013.   else
  2014.     return Fnconc (2, found);
  2015. }
  2016.  
  2017.  
  2018. /* This function is like
  2019.    (key-description (where-is-internal def local-map t global-map))
  2020.    except that it writes its output into a (char *) buffer that you 
  2021.    provide; it doesn't cons (or allocate memory) at all, so it's
  2022.    very fast.  This is used by menubar.c.
  2023.  */
  2024. void
  2025. where_is_to_char (definition, local_keymap, global_keymap, buf)
  2026.      Lisp_Object definition, local_keymap, global_keymap;
  2027.      char *buf;
  2028. {
  2029.   Lisp_Object found;
  2030.   if (NILP (global_keymap))
  2031.     global_keymap = Vcurrent_global_map;
  2032.   if (EQ (local_keymap, global_keymap))
  2033.     local_keymap = Qnil;
  2034.  
  2035.   buf[0] = 0;
  2036.   if (!NILP (local_keymap))
  2037.     {
  2038.       found = where_is_recursive (definition, local_keymap, Qnil, Qt,
  2039.                   0, 0, buf);
  2040.       if (!NILP (found))
  2041.     return;
  2042.     }
  2043.   where_is_recursive (definition, global_keymap, local_keymap, Qt,
  2044.               0, 0, buf);
  2045. }
  2046.  
  2047.  
  2048. static struct raw_key *keys_so_far;
  2049. static int keys_so_far_total_size;
  2050.  
  2051.  
  2052. static Lisp_Object 
  2053. raw_keys_to_keys (keys, count)
  2054.      struct raw_key *keys;
  2055.      int count;
  2056. {
  2057.   Lisp_Object result = Fmake_vector (make_number (count), Qnil);
  2058.   while (count--)
  2059.     XVECTOR (result)->contents [count] =
  2060.       make_key_description (keys[count].keysym, keys[count].bits, 1);
  2061.   return result;
  2062. }
  2063.  
  2064.  
  2065. static void
  2066. format_raw_keys (keys, count, buf)
  2067.      struct raw_key *keys;
  2068.      int count;
  2069.      char *buf;
  2070. {
  2071.   int i;
  2072.   struct Lisp_Event event;
  2073.   event.event_type = key_press_event;
  2074.   for (i = 0; i < count; i++)
  2075.     {
  2076.       event.event.key.key = keys[i].keysym;
  2077.       event.event.key.modifiers = keys[i].bits;
  2078.       format_event_object (buf, &event, 1);
  2079.       buf += strlen (buf);
  2080.       if (i < count-1)
  2081.     buf[0] = ' ', buf++;
  2082.     }
  2083. }
  2084.  
  2085.  
  2086. static Lisp_Object
  2087. where_is_recursive (definition, map, shadow, firstonly,
  2088.             keys_count, bits_so_far, target_buffer)
  2089.      Lisp_Object definition, map, shadow, firstonly;
  2090.      int keys_count, bits_so_far;
  2091.      char *target_buffer;
  2092.   /* definition is the thing to look for.
  2093.      map is a keymap.
  2094.      shadow is a keymap or nil; if it is a keymap, and there is different
  2095.     binding in it of a key that we are considering returning, then we
  2096.     reconsider.
  2097.      firstonly means give up after finding the first match;
  2098.      keys_so_far and bits_so_far describe which map we're looking in;
  2099.     If we're in the "meta" submap of the map that "C-x 4" is bound to,
  2100.     then keys_so_far will be {(control x), \4}, and bits_so_far will
  2101.     be MOD_META.  That is, keys_so_far is the chain of keys that we have
  2102.     followed, and bits_so_far is the bits (partial keys) beyond that.
  2103.  
  2104.      (keys_so_far is a global buffer and the keys_count arg says how much
  2105.      of it we're currently interested in.)
  2106.  
  2107.      If target_buffer is provided, then we write a key-description into it,
  2108.         to avoid consing a string.  This only works with firstonly on.
  2109.    */
  2110. {
  2111.   Lisp_Object result = Qnil;
  2112.  
  2113.   if (keys_count >= keys_so_far_total_size)
  2114.     {
  2115.       keys_so_far_total_size = keys_count + 50;
  2116.       keys_so_far = (struct raw_key *)
  2117.     xrealloc (keys_so_far,
  2118.           keys_so_far_total_size * sizeof (struct raw_key));
  2119.     }
  2120.  
  2121.   for (map = get_keymap (map, 1);
  2122.        !NILP (map);
  2123.        map = get_keymap (XKEYMAP (map)->parent, 0))
  2124.     {
  2125.       Lisp_Object keys = Fgethash (definition, XKEYMAP (map)->inverse_table,
  2126.                    Qnil);
  2127.       Lisp_Object submaps;
  2128.  
  2129.       if (!(NILP (keys)))
  2130.     {
  2131.       /* Verify that this key binding is not shadowed by another binding
  2132.          for the same key, before we say it exists.  The mechanism: look
  2133.          for a local definition of this key and if it is defined and does
  2134.          not match what we found then ignore this key.  Either nil or
  2135.          number as value from raw_lookup_key() means undefined.
  2136.        */
  2137.       Lisp_Object shadowed = Qnil;
  2138.  
  2139.       for (; !NILP (keys); keys = XCONS (keys)->cdr)
  2140.         {
  2141.           keys_so_far [keys_count].keysym = XCONS (keys)->car;
  2142.           keys_so_far [keys_count].bits = bits_so_far;
  2143.           if (!NILP (shadow))
  2144.         shadowed = raw_lookup_key (shadow,
  2145.                        keys_so_far,
  2146.                        keys_count + 1, 
  2147.                        0);
  2148.           if (NILP (shadowed) ||
  2149.           FIXNUMP (shadowed) ||
  2150.           shadowed == definition)
  2151.         {
  2152.           if (target_buffer)
  2153.             {
  2154.               if (NILP (firstonly)) abort ();
  2155.               format_raw_keys (keys_so_far, keys_count + 1,
  2156.                        target_buffer);
  2157.               return 1;
  2158.             }
  2159.           else if (!NILP (firstonly))
  2160.             return raw_keys_to_keys (keys_so_far, keys_count + 1);
  2161.           else
  2162.             result =
  2163.               Fcons (raw_keys_to_keys (keys_so_far, keys_count + 1),
  2164.                  result);
  2165.         }
  2166.         }
  2167.     }
  2168.  
  2169.       /* Now search the sub-keymaps of this map.
  2170.      If we're in "firstonly" mode and have already found one, this 
  2171.      point is not reached.  If we get one from lower down, either
  2172.      return it immediately (in firstonly mode) or tack it onto the
  2173.      end of the ones we've gotten so far.
  2174.        */
  2175.       for (submaps = keymap_submaps (XKEYMAP (map));
  2176.        !NILP (submaps);
  2177.        submaps = XCONS (submaps)->cdr)
  2178.     {
  2179.       Lisp_Object key    = XCONS (XCONS (submaps)->car)->car;
  2180.       Lisp_Object submap = XCONS (XCONS (submaps)->car)->cdr;
  2181.       Lisp_Object lower;
  2182.       int lower_bits;
  2183.       int lower_keys_count = keys_count;
  2184.       int bucky;
  2185.  
  2186.       submap = get_keymap (submap, 0);
  2187.  
  2188.       /* If this is not a keymap, then that's probably because someone
  2189.          did an `fset' of a symbol that used to point to a map such that
  2190.          it no longer does.  Sigh.  Ignore this, and invalidate the cache
  2191.          so that it doesn't happen to us next time too.
  2192.        */
  2193.       if (NILP (submap))
  2194.         {
  2195.           XKEYMAP (map)->sub_maps_cache = Qt;
  2196.           continue;
  2197.         }
  2198.  
  2199.       /* If the map is a "bucky" map, then add a bit to the bits_so_far
  2200.          list.  Otherwise, add a new raw_key onto the end of keys_so_far.
  2201.        */
  2202.       bucky = bucky_sym_to_bucky_bit (key);
  2203.       if (bucky)
  2204.         lower_bits = bits_so_far | bucky;
  2205.       else
  2206.         {
  2207.           lower_bits = 0;
  2208.           keys_so_far [lower_keys_count].keysym = key;
  2209.           keys_so_far [lower_keys_count].bits = bits_so_far;
  2210.           lower_keys_count++;
  2211.         }
  2212.       lower = where_is_recursive (definition, submap, shadow, firstonly,
  2213.                       lower_keys_count, lower_bits,
  2214.                       target_buffer);
  2215.       if (NILP (firstonly))
  2216.         result = nconc2 (lower, result);
  2217.       else if (!NILP (lower))
  2218.         return lower;
  2219.     }
  2220.     }
  2221.   if (! (keys_count || bits_so_far))
  2222.     /* ...meaning we are the outermost call */
  2223.     return Fnreverse (result);
  2224.   else
  2225.     return (result);
  2226. }
  2227.  
  2228.  
  2229. DEFUN ("describe-bindings", Fdescribe_bindings, Sdescribe_bindings, 0, 1, "P",
  2230.   "Show a list of all defined keys, and their definitions.\n\
  2231. The list is put in a buffer, which is displayed.\n\
  2232. If the argument is non-null, then only the mouse bindings are displayed.")
  2233.   (mice_only_p)
  2234.   Lisp_Object mice_only_p;
  2235. {
  2236.   register Lisp_Object thisbuf;
  2237.   XSET (thisbuf, Lisp_Buffer, current_buffer);
  2238.   internal_with_output_to_temp_buffer ("*Help*",
  2239.                        NILP (mice_only_p)
  2240.                        ? describe_buffer_bindings
  2241.                        : describe_buffer_mouse_bindings,
  2242.                        thisbuf, Qnil);
  2243.   return Qnil;
  2244. }
  2245.  
  2246. static Lisp_Object
  2247. describe_buffer_bindings_1 (descbuf, mice_only_p)
  2248.      Lisp_Object descbuf;
  2249.      int mice_only_p;
  2250. {
  2251.   const char *heading =
  2252.     (mice_only_p
  2253.      ? "button          binding\n------          -------\n"
  2254.      : "key             binding\n---             -------\n");
  2255.   struct gcpro gcpro1;
  2256.  
  2257.   GCPRO1 (descbuf);
  2258.   Fset_buffer (Vstandard_output);
  2259.  
  2260.   if (!NILP (XBUFFER (descbuf)->keymap))
  2261.     {
  2262.       insert_string ("Local Bindings:\n");
  2263.       insert_string (heading);
  2264.       describe_map_tree (XBUFFER (descbuf)->keymap,
  2265.              0, Qnil, Qnil, mice_only_p);
  2266.       insert_string ("\n");
  2267.     }
  2268.  
  2269.   insert_string ("Global Bindings:\n");
  2270.   insert_string (heading);
  2271.  
  2272.   describe_map_tree (Vcurrent_global_map, 0, XBUFFER (descbuf)->keymap, Qnil, mice_only_p);
  2273.  
  2274.   Fset_buffer (descbuf);
  2275.   UNGCPRO;
  2276.   return Qnil;
  2277. }
  2278.  
  2279. static Lisp_Object
  2280. describe_buffer_bindings (descbuf)
  2281.      Lisp_Object descbuf;
  2282. {
  2283.   return describe_buffer_bindings_1 (descbuf, 0);
  2284. }
  2285.  
  2286. static Lisp_Object
  2287. describe_buffer_mouse_bindings (descbuf)
  2288.      Lisp_Object descbuf;
  2289. {
  2290.   return describe_buffer_bindings_1 (descbuf, 1);
  2291. }
  2292.  
  2293.  
  2294. /* Insert a desription of the key bindings in STARTMAP,
  2295.     followed by those of all maps reachable through STARTMAP.
  2296.    If PARTIAL is nonzero, omit certain "uninteresting" commands
  2297.     (such as `undefined').
  2298.    If SHADOW is non-nil, it is another map;
  2299.     don't mention keys which would be shadowed by it */
  2300.  
  2301. void
  2302. describe_map_tree (startmap, partial, shadow, chartab, mice_only_p)
  2303.      Lisp_Object startmap, shadow;
  2304.      int partial;
  2305.      Lisp_Object chartab;
  2306.      int mice_only_p;
  2307. {
  2308.   Lisp_Object maps, elt, sh;
  2309.   struct gcpro gcpro1;
  2310.  
  2311.   maps = Faccessible_keymaps (startmap);
  2312.  
  2313.   GCPRO1 (maps);
  2314.  
  2315.   for (; !NILP (maps); maps = Fcdr (maps))
  2316.     {
  2317.       elt = Fcar (maps);
  2318.       sh = Fcar (elt);
  2319.       if (NILP (shadow))
  2320.     sh = Qnil;
  2321.       else if (VECTORP (sh)
  2322.            && XVECTOR (sh)->size == 0)
  2323.     sh = shadow;
  2324.       else
  2325.     {
  2326.       sh = Flookup_key (shadow, Fcar (elt));
  2327.       if (FIXNUMP (sh))
  2328.         sh = Qnil;
  2329.     }
  2330.       if (NILP (sh) || !NILP (Fkeymapp (sh)))
  2331.     describe_map (Fcdr (elt), Fcar (elt), partial,
  2332.               (NILP (sh) ? Qnil : get_keymap (sh, 1)),
  2333.               chartab, mice_only_p);
  2334.     }
  2335.   UNGCPRO;
  2336. }
  2337.  
  2338.  
  2339. #define insert1(arg) \
  2340.   do { Lisp_Object tem = (arg); Finsert (1, &tem); } while (0)
  2341.  
  2342. static void
  2343. describe_command (definition)
  2344.      Lisp_Object definition;
  2345. {
  2346.   struct gcpro gcpro1;
  2347.   GCPRO1 (definition);
  2348.  
  2349.   Findent_to (make_number (16), make_number (1));
  2350.   if (SYMBOLP (definition))
  2351.     {
  2352.       insert1 (Fsymbol_name (definition));
  2353.     }
  2354.   else if (STRINGP (definition) || VECTORP (definition))
  2355.     {
  2356.       insert_string ("Kbd Macro: ");
  2357.       insert1 (Fkey_description (definition));
  2358.     }
  2359.   else if (COMPILEDP (definition))
  2360.     insert_string ("Anonymous Compiled Function");
  2361.   else if (CONSP (definition) && EQ (XCONS (definition)->car, Qlambda))
  2362.     insert_string ("Anonymous Lambda");
  2363.   else if (KEYMAPP (definition))
  2364.     {
  2365.       Lisp_Object name = XKEYMAP (definition)->name;
  2366.       if (!NILP (name) 
  2367.       && (SYMBOLP (name) || STRINGP (name)) /* >>>??? */
  2368.       )
  2369.     {
  2370.       insert_string ("Prefix Command ");
  2371.       if (SYMBOLP (name) 
  2372.           && !NILP (Fboundp (name))
  2373.           && EQ (Fsymbol_value (name), definition))
  2374.         insert1 (name);
  2375.       else
  2376.         {
  2377.           insert1 (Fprin1_to_string (name, Qnil));
  2378.         }
  2379.     }
  2380.       else
  2381.     insert_string ("Prefix Command");
  2382.     }
  2383.   else
  2384.     insert_string ("??");
  2385.  
  2386.   insert_string ("\n");
  2387.   UNGCPRO;
  2388. }
  2389.  
  2390. /* Describe the contents of map MAP, assuming that this map
  2391.    itself is reached by the sequence of prefix keys KEYS (a vector).
  2392.    PARTIAL, SHADOW and CHARTAB are as in `describe_map_tree' above.  */
  2393.  
  2394. static void
  2395. describe_map (map, keys, partial, shadow, chartab, mice_only_p)
  2396.      Lisp_Object map, keys;
  2397.      int partial;
  2398.      Lisp_Object shadow;
  2399.      Lisp_Object chartab;
  2400.      int mice_only_p;
  2401. {
  2402.   Lisp_Object keysdesc;
  2403.   struct gcpro gcpro1;
  2404.   
  2405.   if (!NILP (keys) && XINT (Flength (keys)) > 0)
  2406.     keysdesc = concat2 (Fkey_description (keys), build_string (" "));
  2407.   else
  2408.     keysdesc = Qnil;
  2409.   GCPRO1 (keysdesc);
  2410.   describe_vector (map, keysdesc, describe_command,
  2411.            partial, shadow, chartab, mice_only_p);
  2412.   UNGCPRO;
  2413. }
  2414.  
  2415. struct describe_vector_closure {
  2416.   Lisp_Object *list;     /* pointer to the list to update */
  2417.   Lisp_Object partial;     /* whether to ignore suppressed commands */
  2418.   Lisp_Object shadow;     /* the map that shadows this one */
  2419.   Lisp_Object self;     /* this map */
  2420.   Lisp_Object self_root; /* this map, or some map that has this map as
  2421.                 a parent.  this is the base of the tree */
  2422.   int mice_only_p;     /* whether we are to display only button bindings */
  2423. };
  2424.  
  2425. static void
  2426. describe_vector_mapper (key, bits, binding, junk)
  2427.      Lisp_Object key, binding;
  2428.      int bits;
  2429.      void *junk;
  2430. {
  2431.   Lisp_Object sh;
  2432.   struct describe_vector_closure *closure =
  2433.     (struct describe_vector_closure *) junk;
  2434.  
  2435.   /* Dont mention suppressed commands.  */
  2436.   if (SYMBOLP (binding) &&
  2437.       !NILP (closure->partial) &&
  2438.       !NILP (Fget (binding, closure->partial)))
  2439.     return;
  2440.           
  2441.   /* If we're only supposed to display mouse bindings and this isn't one,
  2442.      then bug out. */
  2443.   if (closure->mice_only_p &&
  2444.       (! (EQ (key, Qbutton0) || EQ (key, Qbutton1) || EQ (key, Qbutton2) ||
  2445.       EQ (key, Qbutton3) || EQ (key, Qbutton4) || EQ (key, Qbutton5) ||
  2446.       EQ (key, Qbutton6) || EQ (key, Qbutton7))))
  2447.     return;
  2448.  
  2449.   /* If this command in this map is shadowed by some other map, ignore it. */
  2450.   if (!NILP (closure->shadow))
  2451.     {
  2452.       for (sh = closure->shadow;
  2453.        !NILP (Fkeymapp (sh));
  2454.        sh = XKEYMAP (sh)->parent)
  2455.     {
  2456.       if (!NILP (keymap_lookup_directly (sh, key, bits)))
  2457.         return;
  2458.     }
  2459.     }
  2460.   /* If this key is in some map of which this map is a parent, then ignore
  2461.      it (in that case, it has been shadowed.)
  2462.    */
  2463.   for (sh = closure->self_root;
  2464.        !EQ (sh, closure->self);
  2465.        sh = XKEYMAP (sh)->parent)
  2466.     {
  2467.       if (!NILP (keymap_lookup_directly (sh, key, bits)))
  2468.     return;
  2469.     }
  2470.  
  2471.   /* Otherwise add it to the list to be sorted. */
  2472.   *(closure->list) = Fcons (Fcons (Fcons (key, make_number (bits)), binding),
  2473.                 *(closure->list));
  2474. }
  2475.  
  2476.  
  2477. static int
  2478. describe_vector_sort_predicate (obj1, obj2, pred)
  2479.      Lisp_Object obj1, obj2, pred;
  2480. {
  2481.   /* obj1 and obj2 are conses of the form
  2482.      ( ( <keysym> . <bits> ) . <binding> )
  2483.      keysym and bits are used, binding is ignored.
  2484.    */
  2485.   int bit1, bit2;
  2486.   obj1 = XCONS (obj1)->car;
  2487.   obj2 = XCONS (obj2)->car;
  2488.   bit1 = XFASTINT (XCONS (obj1)->cdr);
  2489.   bit2 = XFASTINT (XCONS (obj2)->cdr);
  2490.   if (bit1 != bit2)
  2491.     return ((bit1 < bit2) ? 1 : -1);
  2492.   else
  2493.     return map_keymap_sort_predicate (obj1, obj2, pred);
  2494. }
  2495.  
  2496. /* Elide 2 or more consecutive numeric keysyms bound to the same thing,
  2497.    or 2 or more symbolic keysyms that are bound to the same thing and
  2498.    have consecutive character-set-properties.
  2499.  */
  2500. static int
  2501. elide_next_two_p (list)
  2502.      Lisp_Object list;
  2503. {
  2504.   Lisp_Object s1, s2;
  2505.  
  2506. #define CAR(x) (XCONS(x)->car)
  2507. #define CDR(x) (XCONS(x)->cdr)
  2508.  
  2509.   if (NILP (CDR (list)))
  2510.     return 0;
  2511.  
  2512.   /* next two bindings differ */
  2513.   if (!EQ (CDR (CAR (list)),
  2514.        CDR (CAR (CDR (list)))))
  2515.     return 0;
  2516.  
  2517.   /* next two modifier-sets differ */
  2518.   if (!EQ (CDR (CAR (CAR (list))),
  2519.        CDR (CAR (CAR (CDR (list))))))
  2520.     return 0;
  2521.  
  2522.   s1 = CAR (CAR (CAR (list)));
  2523.   s2 = CAR (CAR (CAR (CDR (list))));
  2524.  
  2525.   if (SYMBOLP (s1))
  2526.     {
  2527.       Lisp_Object code = Fget (s1, Vcharacter_set_property);
  2528.       if (FIXNUMP (code)) s1 = code;
  2529.       else return 0;
  2530.     }
  2531.   if (SYMBOLP (s2))
  2532.     {
  2533.       Lisp_Object code = Fget (s2, Vcharacter_set_property);
  2534.       if (FIXNUMP (code)) s2 = code;
  2535.       else return 0;
  2536.     }
  2537.  
  2538.   if (XFASTINT (s1) == XFASTINT (s2) ||
  2539.       XFASTINT (s1) + 1 == XFASTINT (s2))
  2540.     return 1;
  2541.   return 0;
  2542.  
  2543. #undef CDR
  2544. #undef CAR
  2545. }
  2546.  
  2547.  
  2548. static void
  2549. describe_vector (keymap, elt_prefix, elt_describer, partial, shadow, chartab,
  2550.          mice_only_p)
  2551.      Lisp_Object keymap;
  2552.      Lisp_Object elt_prefix;
  2553.      void (*elt_describer) (Lisp_Object);
  2554.      int partial;
  2555.      Lisp_Object shadow;
  2556.      Lisp_Object chartab;
  2557.      int mice_only_p;
  2558. {
  2559.   struct describe_vector_closure closure;
  2560.   Lisp_Object list = Qnil;
  2561.   struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
  2562.  
  2563.   keymap = get_keymap (keymap, 1);
  2564.   closure.partial = (partial ? Qsuppress_keymap : Qnil);
  2565.   closure.shadow = shadow;
  2566.   closure.list = &list;
  2567.   closure.self_root = keymap;
  2568.   closure.mice_only_p = mice_only_p;
  2569.  
  2570.   if (!NILP (chartab))
  2571.     CHECK_VECTOR (chartab, 0);
  2572.  
  2573.   GCPRO4 (keymap, elt_prefix, shadow, /* chartab, */ list);
  2574.  
  2575.   for (; !NILP (Fkeymapp (keymap)); keymap = XKEYMAP (keymap)->parent)
  2576.     {
  2577.       closure.self = get_keymap (keymap, 1);
  2578.       map_keymap (XKEYMAP (closure.self),
  2579.           0, /* don't sort: we'll do it later */
  2580.           describe_vector_mapper, (void *) &closure);
  2581.     }
  2582.  
  2583.   list = list_sort (list, Qnil, describe_vector_sort_predicate);
  2584.  
  2585.   insert_raw_string ("\n", 1);
  2586.   while (!NILP (list)) {
  2587.     Lisp_Object keysym = XCONS (XCONS (XCONS (list)->car)->car)->car;
  2588.     int modifiers = XINT (XCONS (XCONS (XCONS (list)->car)->car)->cdr);
  2589.  
  2590.     if (!NILP (elt_prefix))
  2591.       insert_relocatable_raw_string ((char *) XSTRING (elt_prefix)->data,
  2592.                      XSTRING (elt_prefix)->size,
  2593.                      elt_prefix);
  2594.  
  2595.     if (modifiers & MOD_META)    insert_raw_string ("M-", 2);
  2596.     if (modifiers & MOD_CONTROL) insert_raw_string ("C-", 2);
  2597.     if (modifiers & MOD_SUPER)   insert_raw_string ("S-", 2);
  2598.     if (modifiers & MOD_HYPER)   insert_raw_string ("H-", 2);
  2599.     if (modifiers & MOD_SYMBOL)  insert_raw_string ("Sym-", 4);
  2600.     if (modifiers & MOD_SHIFT)   insert_raw_string ("Sh-", 3);
  2601.     switch (XTYPE (keysym)) {
  2602.     case Lisp_Symbol:
  2603.       {
  2604.     /* Calling Fsingle_key_description() would cons more */
  2605.     if (EQ (keysym, QKlinefeed))    insert_raw_string ("LFD", 3);
  2606.     else if (EQ (keysym, QKtab))    insert_raw_string ("TAB", 3);
  2607.     else if (EQ (keysym, QKreturn))    insert_raw_string ("RET", 3);
  2608.     else if (EQ (keysym, QKescape))    insert_raw_string ("ESC", 3);
  2609.     else if (EQ (keysym, QKdelete))    insert_raw_string ("DEL", 3);
  2610.     else if (EQ (keysym, QKspace))    insert_raw_string ("SPC", 3);
  2611.     else if (EQ (keysym, QKbackspace)) insert_raw_string ("BS", 2);
  2612.     else insert_raw_string ((char *) XSYMBOL (keysym)->name->data,
  2613.                 XSYMBOL (keysym)->name->size);
  2614.     break;
  2615.       }
  2616.     case Lisp_Int:
  2617.       {
  2618.     char string [1];
  2619.     string [0] = XFASTINT (keysym);
  2620.     insert_raw_string (string, 1);
  2621.     break;
  2622.       }
  2623.     default:
  2624.       insert_string ("---bad keysym---");
  2625.     }
  2626.  
  2627.     {
  2628.       int k = 0;
  2629.  
  2630.       while (elide_next_two_p (list))
  2631.     {
  2632.       k++;
  2633.       list = XCONS (list)->cdr;
  2634.     }
  2635.       if (k)
  2636.     {
  2637.       if (k == 1)
  2638.         insert_raw_string (", ", 2);
  2639.       else
  2640.         insert_raw_string (" .. ", 4);
  2641.       continue;
  2642.     }
  2643.     }
  2644.     
  2645.     /* Print a description of the definition of this character.  */
  2646.     (*elt_describer) (XCONS (XCONS (list)->car)->cdr);
  2647.     list = XCONS (list)->cdr;
  2648.   }
  2649.   UNGCPRO;
  2650. }
  2651.  
  2652.  
  2653. /* Apropos */
  2654. static Lisp_Object apropos_predicate;
  2655. static Lisp_Object apropos_accumulate;
  2656.  
  2657. static void
  2658. apropos_accum (symbol, string)
  2659.      Lisp_Object symbol, string;
  2660. {
  2661.   register Lisp_Object tem;
  2662.  
  2663.   tem = Fstring_match (string, Fsymbol_name (symbol), Qnil);
  2664.   if (!NILP (tem) && !NILP (apropos_predicate))
  2665.     tem = call1 (apropos_predicate, symbol);
  2666.   if (!NILP (tem))
  2667.     apropos_accumulate = Fcons (symbol, apropos_accumulate);
  2668. }
  2669.  
  2670. DEFUN ("apropos-internal", Fapropos_internal, Sapropos_internal, 1, 2, 0, 
  2671.   "Show all symbols whose names contain match for REGEXP.\n\
  2672. If optional 2nd arg PRED is non-nil, (funcall PRED SYM) is done\n\
  2673. for each symbol and a symbol is mentioned only if that returns non-nil.\n\
  2674. Return list of symbols found.")
  2675.   (string, pred)
  2676.      Lisp_Object string, pred;
  2677. {
  2678.   struct gcpro gcpro1, gcpro2;
  2679.   CHECK_STRING (string, 0);
  2680.   apropos_predicate = pred;
  2681.   GCPRO2 (apropos_predicate, apropos_accumulate);
  2682.   apropos_accumulate = Qnil;
  2683.   map_obarray (Vobarray, apropos_accum, string);
  2684.   apropos_accumulate = Fsort (apropos_accumulate, Qstring_lessp);
  2685.   UNGCPRO;
  2686.   return apropos_accumulate;
  2687. }
  2688.  
  2689. void
  2690. syms_of_keymap ()
  2691. {
  2692.   DEFVAR_INT ("meta-prefix-char", &meta_prefix_char,
  2693.     "Meta-prefix character code.  Must be an ASCII integer.\n\
  2694. This character followed by some character `foo' turns into `Meta-foo'.\n\
  2695. To disable the meta-prefix-char, set it to a negative number.");
  2696.   meta_prefix_char = 033;
  2697.  
  2698.   DEFVAR_INT ("keymap-tick", &keymap_tick,
  2699.           "Incremented for each change to any keymap.");
  2700.   keymap_tick = 0;
  2701.  
  2702.   defsymbol (&Qkeymapp, "keymapp");
  2703.   defsymbol (&Qsuppress_keymap, "suppress-keymap");
  2704.  
  2705. #if 0
  2706.   defsymbol (&Qsingle_key_description, "single-key-description");
  2707.   defsymbol (&Qkey_description, "key-description");
  2708. #endif
  2709.  
  2710.   staticpro (&Vcurrent_global_map);
  2711.  
  2712.   defsubr (&Skeymapp);
  2713.   defsubr (&Smake_keymap);
  2714.   defsubr (&Smake_sparse_keymap);
  2715.   defsubr (&Skeymap_parent);
  2716.   defsubr (&Sset_keymap_parent);
  2717.   defsubr (&Sset_keymap_name);
  2718.   defsubr (&Scopy_keymap);
  2719.   defsubr (&Skeymap_fullness);
  2720.   defsubr (&Smap_keymap);
  2721.   defsubr (&Sdefine_key);
  2722.   defsubr (&Slookup_key);
  2723.   defsubr (&Skey_binding);
  2724.   defsubr (&Suse_global_map);
  2725.   defsubr (&Suse_local_map);
  2726.   defsubr (&Scurrent_local_map);
  2727.   defsubr (&Scurrent_global_map);
  2728.   defsubr (&Saccessible_keymaps);
  2729.   defsubr (&Skey_description);
  2730.   defsubr (&Ssingle_key_description);
  2731.   defsubr (&Stext_char_description);
  2732.   defsubr (&Swhere_is_internal);
  2733.   defsubr (&Sdescribe_bindings);
  2734.   defsubr (&Sapropos_internal);
  2735.  
  2736.   defsymbol (&Qcontrol, "control");
  2737.   defsymbol (&Qctrl, "ctrl");
  2738.   defsymbol (&Qmeta, "meta"); 
  2739.   defsymbol (&Qsuper, "super"); 
  2740.   defsymbol (&Qhyper, "hyper"); 
  2741.   defsymbol (&Qsymbol, "symbol");
  2742.   defsymbol (&Qshift, "shift");
  2743.   defsymbol (&Qbutton0, "button0");
  2744.   defsymbol (&Qbutton1, "button1");
  2745.   defsymbol (&Qbutton2, "button2");
  2746.   defsymbol (&Qbutton3, "button3");
  2747.   defsymbol (&Qbutton4, "button4");
  2748.   defsymbol (&Qbutton5, "button5");
  2749.   defsymbol (&Qbutton6, "button6");
  2750.   defsymbol (&Qbutton7, "button7");
  2751.   defsymbol (&Qbutton0up, "button0up");
  2752.   defsymbol (&Qbutton1up, "button1up");
  2753.   defsymbol (&Qbutton2up, "button2up");
  2754.   defsymbol (&Qbutton3up, "button3up");
  2755.   defsymbol (&Qbutton4up, "button4up");
  2756.   defsymbol (&Qbutton5up, "button5up");
  2757.   defsymbol (&Qbutton6up, "button6up");
  2758.   defsymbol (&Qbutton7up, "button7up");
  2759.   defsymbol (&Qmenu_selection, "menu-selection");
  2760.  
  2761.   /* no need to staticpro these because where_is_internal and lookup_key
  2762.      do not eval, and do not use the data in these after they exit.
  2763.    */
  2764.   keys_so_far_total_size = 50;
  2765.   keys_so_far = (struct raw_key *)
  2766.     xmalloc (sizeof (struct raw_key) * keys_so_far_total_size);
  2767.  
  2768.   lookup_key_buf_total_size = 50;
  2769.   lookup_key_buf = (struct raw_key *)
  2770.     xmalloc (sizeof (struct raw_key) * keys_so_far_total_size);
  2771. }
  2772.  
  2773. void
  2774. keys_of_keymap ()
  2775. {
  2776.   Lisp_Object ESC_prefix = intern ("ESC-prefix");
  2777.   Vcurrent_global_map = Fmake_keymap ();
  2778.   Ffset (ESC_prefix, Fmake_keymap ());
  2779.   keymap_store (Vcurrent_global_map, Qmeta, 0, ESC_prefix);
  2780. }
  2781.