/* Manipulation of keymaps
- Copyright (C) 1985, 86, 87, 88, 93, 94, 95 Free Software Foundation, Inc.
+ Copyright (C) 1985, 86,87,88,93,94,95,98,99 Free Software Foundation, Inc.
This file is part of GNU Emacs.
/* Alist of minor mode variables and keymaps. */
Lisp_Object Vminor_mode_map_alist;
+/* Alist of major-mode-specific overrides for
+ minor mode variables and keymaps. */
+Lisp_Object Vminor_mode_overriding_map_alist;
+
/* Keymap mapping ASCII function key sequences onto their preferred forms.
Initialized by the terminal-specific lisp files. See DEFVAR for more
documentation. */
when Emacs starts up. t means don't record anything here. */
Lisp_Object Vdefine_key_rebound_commands;
-Lisp_Object Qkeymapp, Qkeymap, Qnon_ascii;
+Lisp_Object Qkeymapp, Qkeymap, Qnon_ascii, Qmenu_item;
/* A char with the CHAR_META bit set in a vector or the 0200 bit set
in a string key sequence is equivalent to prefixing with this
static Lisp_Object describe_buffer_bindings ();
static void describe_command (), describe_translation ();
static void describe_map ();
-Lisp_Object Fcopy_keymap ();
\f
/* Keymap object support - constructors and predicates. */
DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 1, 0,
- "Construct and return a new keymap, of the form (keymap VECTOR . ALIST).\n\
-VECTOR is a vector which holds the bindings for the ASCII\n\
+ "Construct and return a new keymap, of the form (keymap CHARTABLE . ALIST).\n\
+CHARTABLE is a char-table that holds the bindings for the ASCII\n\
characters. ALIST is an assoc-list which holds bindings for function keys,\n\
mouse events, and any other things that appear in the input stream.\n\
All entries in it are initially nil, meaning \"command undefined\".\n\n\
Lisp_Object tem;
autoload_retry:
- tem = indirect_function (object);
- if (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap))
- return tem;
+ if (NILP (object))
+ goto end;
+ if (CONSP (object) && EQ (XCAR (object), Qkeymap))
+ return object;
+ else
+ {
+ tem = indirect_function (object);
+ if (CONSP (tem) && EQ (XCAR (tem), Qkeymap))
+ return tem;
+ }
/* Should we do an autoload? Autoload forms for keymaps have
Qkeymap as their fifth element. */
if (autoload
&& SYMBOLP (object)
&& CONSP (tem)
- && EQ (XCONS (tem)->car, Qautoload))
+ && EQ (XCAR (tem), Qautoload))
{
Lisp_Object tail;
}
}
+ end:
if (error)
wrong_type_argument (Qkeymapp, object);
else
keymap = get_keymap_1 (keymap, 1, 1);
/* Skip past the initial element `keymap'. */
- list = XCONS (keymap)->cdr;
- for (; CONSP (list); list = XCONS (list)->cdr)
+ list = XCDR (keymap);
+ for (; CONSP (list); list = XCDR (list))
{
/* See if there is another `keymap'. */
- if (EQ (Qkeymap, XCONS (list)->car))
+ if (EQ (Qkeymap, XCAR (list)))
return list;
}
prev = keymap;
while (1)
{
- list = XCONS (prev)->cdr;
+ list = XCDR (prev);
/* If there is a parent keymap here, replace it.
If we came to the end, add the parent in PREV. */
- if (! CONSP (list) || EQ (Qkeymap, XCONS (list)->car))
+ if (! CONSP (list) || EQ (Qkeymap, XCAR (list)))
{
/* If we already have the right parent, return now
so that we avoid the loops below. */
- if (EQ (XCONS (prev)->cdr, parent))
+ if (EQ (XCDR (prev), parent))
return parent;
- XCONS (prev)->cdr = parent;
+ XCDR (prev) = parent;
break;
}
prev = list;
/* Scan through for submaps, and set their parents too. */
- for (list = XCONS (keymap)->cdr; CONSP (list); list = XCONS (list)->cdr)
+ for (list = XCDR (keymap); CONSP (list); list = XCDR (list))
{
/* Stop the scan when we come to the parent. */
- if (EQ (XCONS (list)->car, Qkeymap))
+ if (EQ (XCAR (list), Qkeymap))
break;
/* If this element holds a prefix map, deal with it. */
- if (CONSP (XCONS (list)->car)
- && CONSP (XCONS (XCONS (list)->car)->cdr))
- fix_submap_inheritance (keymap, XCONS (XCONS (list)->car)->car,
- XCONS (XCONS (list)->car)->cdr);
-
- if (VECTORP (XCONS (list)->car))
- for (i = 0; i < XVECTOR (XCONS (list)->car)->size; i++)
- if (CONSP (XVECTOR (XCONS (list)->car)->contents[i]))
+ if (CONSP (XCAR (list))
+ && CONSP (XCDR (XCAR (list))))
+ fix_submap_inheritance (keymap, XCAR (XCAR (list)),
+ XCDR (XCAR (list)));
+
+ if (VECTORP (XCAR (list)))
+ for (i = 0; i < XVECTOR (XCAR (list))->size; i++)
+ if (CONSP (XVECTOR (XCAR (list))->contents[i]))
fix_submap_inheritance (keymap, make_number (i),
- XVECTOR (XCONS (list)->car)->contents[i]);
+ XVECTOR (XCAR (list))->contents[i]);
- if (CHAR_TABLE_P (XCONS (list)->car))
+ if (CHAR_TABLE_P (XCAR (list)))
{
- Lisp_Object *indices
- = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object));
+ Lisp_Object indices[3];
- map_char_table (fix_submap_inheritance, Qnil, XCONS (list)->car,
+ map_char_table (fix_submap_inheritance, Qnil, XCAR (list),
keymap, 0, indices);
}
}
if EVENT is also a prefix in MAP's parent,
make sure that SUBMAP inherits that definition as its own parent. */
+void
fix_submap_inheritance (map, event, submap)
Lisp_Object map, event, submap;
{
/* SUBMAP is a cons that we found as a key binding.
Discard the other things found in a menu key binding. */
- if (CONSP (submap)
- && STRINGP (XCONS (submap)->car))
+ if (CONSP (submap))
{
- submap = XCONS (submap)->cdr;
- /* Also remove a menu help string, if any,
- following the menu item name. */
- if (CONSP (submap) && STRINGP (XCONS (submap)->car))
- submap = XCONS (submap)->cdr;
- /* Also remove the sublist that caches key equivalences, if any. */
- if (CONSP (submap)
- && CONSP (XCONS (submap)->car))
+ /* May be an old format menu item */
+ if (STRINGP (XCAR (submap)))
+ {
+ submap = XCDR (submap);
+ /* Also remove a menu help string, if any,
+ following the menu item name. */
+ if (CONSP (submap) && STRINGP (XCAR (submap)))
+ submap = XCDR (submap);
+ /* Also remove the sublist that caches key equivalences, if any. */
+ if (CONSP (submap)
+ && CONSP (XCAR (submap)))
+ {
+ Lisp_Object carcar;
+ carcar = XCAR (XCAR (submap));
+ if (NILP (carcar) || VECTORP (carcar))
+ submap = XCDR (submap);
+ }
+ }
+
+ /* Or a new format menu item */
+ else if (EQ (XCAR (submap), Qmenu_item)
+ && CONSP (XCDR (submap)))
{
- Lisp_Object carcar;
- carcar = XCONS (XCONS (submap)->car)->car;
- if (NILP (carcar) || VECTORP (carcar))
- submap = XCONS (submap)->cdr;
+ submap = XCDR (XCDR (submap));
+ if (CONSP (submap))
+ submap = XCAR (submap);
}
}
/* If it isn't a keymap now, there's no work to do. */
if (! CONSP (submap)
- || ! EQ (XCONS (submap)->car, Qkeymap))
+ || ! EQ (XCAR (submap), Qkeymap))
return;
map_parent = Fkeymap_parent (map);
/* If MAP's parent has something other than a keymap,
our own submap shadows it completely, so use nil as SUBMAP's parent. */
- if (! (CONSP (parent_entry) && EQ (XCONS (parent_entry)->car, Qkeymap)))
+ if (! (CONSP (parent_entry) && EQ (XCAR (parent_entry), Qkeymap)))
parent_entry = Qnil;
if (! EQ (parent_entry, submap))
- Fset_keymap_parent (submap, parent_entry);
+ {
+ Lisp_Object submap_parent;
+ submap_parent = submap;
+ while (1)
+ {
+ Lisp_Object tem;
+ tem = Fkeymap_parent (submap_parent);
+ if (EQ (tem, parent_entry))
+ return;
+ if (CONSP (tem)
+ && EQ (XCAR (tem), Qkeymap))
+ submap_parent = tem;
+ else
+ break;
+ }
+ Fset_keymap_parent (submap_parent, parent_entry);
+ }
}
\f
/* Look up IDX in MAP. IDX may be any sort of event.
Lisp_Object t_binding;
t_binding = Qnil;
- for (tail = map; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = map; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object binding;
- binding = XCONS (tail)->car;
+ binding = XCAR (tail);
if (SYMBOLP (binding))
{
/* If NOINHERIT, stop finding prefix definitions
}
else if (CONSP (binding))
{
- if (EQ (XCONS (binding)->car, idx))
+ if (EQ (XCAR (binding), idx))
{
- val = XCONS (binding)->cdr;
- if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
+ val = XCDR (binding);
+ if (noprefix && CONSP (val) && EQ (XCAR (val), Qkeymap))
return Qnil;
if (CONSP (val))
fix_submap_inheritance (map, idx, val);
return val;
}
- if (t_ok && EQ (XCONS (binding)->car, Qt))
- t_binding = XCONS (binding)->cdr;
+ if (t_ok && EQ (XCAR (binding), Qt))
+ t_binding = XCDR (binding);
}
else if (VECTORP (binding))
{
if (NATNUMP (idx) && XFASTINT (idx) < XVECTOR (binding)->size)
{
val = XVECTOR (binding)->contents[XFASTINT (idx)];
- if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
+ if (noprefix && CONSP (val) && EQ (XCAR (val), Qkeymap))
return Qnil;
if (CONSP (val))
fix_submap_inheritance (map, idx, val);
| CHAR_SHIFT | CHAR_CTL | CHAR_META)))
{
val = Faref (binding, idx);
- if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
+ if (noprefix && CONSP (val) && EQ (XCAR (val), Qkeymap))
return Qnil;
if (CONSP (val))
fix_submap_inheritance (map, idx, val);
{
while (1)
{
- register Lisp_Object map, tem;
+ if (!(CONSP (object)))
+ /* This is really the value. */
+ return object;
- /* If the contents are (KEYMAP . ELEMENT), go indirect. */
- map = get_keymap_1 (Fcar_safe (object), 0, autoload);
- tem = Fkeymapp (map);
- if (!NILP (tem))
+ /* If the keymap contents looks like (keymap ...) or (lambda ...)
+ then use itself. */
+ else if (EQ (XCAR (object), Qkeymap) || EQ (XCAR (object), Qlambda))
+ return object;
+
+ /* If the keymap contents looks like (menu-item name . DEFN)
+ or (menu-item name DEFN ...) then use DEFN.
+ This is a new format menu item.
+ */
+ else if (EQ (XCAR (object), Qmenu_item))
{
- Lisp_Object key;
- key = Fcdr (object);
- if (INTEGERP (key) && (XINT (key) & meta_modifier))
+ if (CONSP (XCDR (object)))
{
- object = access_keymap (map, meta_prefix_char, 0, 0);
- map = get_keymap_1 (object, 0, autoload);
- object = access_keymap (map,
- make_number (XINT (key) & ~meta_modifier),
- 0, 0);
+ object = XCDR (XCDR (object));
+ if (CONSP (object))
+ object = XCAR (object);
}
else
- object = access_keymap (map, key, 0, 0);
+ /* Invalid keymap */
+ return object;
}
- /* If the keymap contents looks like (STRING . DEFN),
- use DEFN.
+ /* If the keymap contents looks like (STRING . DEFN), use DEFN.
Keymap alist elements like (CHAR MENUSTRING . DEFN)
will be used by HierarKey menus. */
- else if (CONSP (object)
- && STRINGP (XCONS (object)->car))
+ else if (STRINGP (XCAR (object)))
{
- object = XCONS (object)->cdr;
+ object = XCDR (object);
/* Also remove a menu help string, if any,
following the menu item name. */
- if (CONSP (object) && STRINGP (XCONS (object)->car))
- object = XCONS (object)->cdr;
+ if (CONSP (object) && STRINGP (XCAR (object)))
+ object = XCDR (object);
/* Also remove the sublist that caches key equivalences, if any. */
- if (CONSP (object)
- && CONSP (XCONS (object)->car))
+ if (CONSP (object) && CONSP (XCAR (object)))
{
Lisp_Object carcar;
- carcar = XCONS (XCONS (object)->car)->car;
+ carcar = XCAR (XCAR (object));
if (NILP (carcar) || VECTORP (carcar))
- object = XCONS (object)->cdr;
+ object = XCDR (object);
}
}
+ /* If the contents are (KEYMAP . ELEMENT), go indirect. */
else
- /* Anything else is really the value. */
- return object;
+ {
+ register Lisp_Object map;
+ map = get_keymap_1 (Fcar_safe (object), 0, autoload);
+ if (NILP (map))
+ /* Invalid keymap */
+ return object;
+ else
+ {
+ Lisp_Object key;
+ key = Fcdr (object);
+ if (INTEGERP (key) && (XINT (key) & meta_modifier))
+ {
+ object = access_keymap (map, meta_prefix_char, 0, 0);
+ map = get_keymap_1 (object, 0, autoload);
+ object = access_keymap (map, make_number (XINT (key)
+ & ~meta_modifier),
+ 0, 0);
+ }
+ else
+ object = access_keymap (map, key, 0, 0);
+ }
+ }
}
}
register Lisp_Object def;
{
/* If we are preparing to dump, and DEF is a menu element
- with a menu item string, copy it to ensure it is not pure. */
- if (CONSP (def) && PURE_P (def) && STRINGP (XCONS (def)->car))
- def = Fcons (XCONS (def)->car, XCONS (def)->cdr);
+ with a menu item indicator, copy it to ensure it is not pure. */
+ if (CONSP (def) && PURE_P (def)
+ && (EQ (XCAR (def), Qmenu_item) || STRINGP (XCAR (def))))
+ def = Fcons (XCAR (def), XCDR (def));
- if (!CONSP (keymap) || ! EQ (XCONS (keymap)->car, Qkeymap))
+ if (!CONSP (keymap) || ! EQ (XCAR (keymap), Qkeymap))
error ("attempt to define a key in a non-keymap");
/* If idx is a list (some sort of mouse click, perhaps?),
Lisp_Object insertion_point;
insertion_point = keymap;
- for (tail = XCONS (keymap)->cdr; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = XCDR (keymap); CONSP (tail); tail = XCDR (tail))
{
Lisp_Object elt;
- elt = XCONS (tail)->car;
+ elt = XCAR (tail);
if (VECTORP (elt))
{
if (NATNUMP (idx) && XFASTINT (idx) < XVECTOR (elt)->size)
}
else if (CONSP (elt))
{
- if (EQ (idx, XCONS (elt)->car))
+ if (EQ (idx, XCAR (elt)))
{
- XCONS (elt)->cdr = def;
+ XCDR (elt) = def;
return def;
}
}
keymap_end:
/* We have scanned the entire keymap, and not found a binding for
IDX. Let's add one. */
- XCONS (insertion_point)->cdr
- = Fcons (Fcons (idx, def), XCONS (insertion_point)->cdr);
+ XCDR (insertion_point)
+ = Fcons (Fcons (idx, def), XCDR (insertion_point));
}
return def;
}
-Lisp_Object
+void
copy_keymap_1 (chartable, idx, elt)
Lisp_Object chartable, idx, elt;
{
copy = Fcopy_alist (get_keymap (keymap));
- for (tail = copy; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = copy; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object elt;
- elt = XCONS (tail)->car;
+ elt = XCAR (tail);
if (CHAR_TABLE_P (elt))
{
- Lisp_Object *indices
- = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object));
+ Lisp_Object indices[3];
elt = Fcopy_sequence (elt);
- XCONS (tail)->car = elt;
+ XCAR (tail) = elt;
map_char_table (copy_keymap_1, Qnil, elt, elt, 0, indices);
}
int i;
elt = Fcopy_sequence (elt);
- XCONS (tail)->car = elt;
+ XCAR (tail) = elt;
for (i = 0; i < XVECTOR (elt)->size; i++)
if (!SYMBOLP (XVECTOR (elt)->contents[i])
XVECTOR (elt)->contents[i]
= Fcopy_keymap (XVECTOR (elt)->contents[i]);
}
- else if (CONSP (elt))
+ else if (CONSP (elt) && CONSP (XCDR (elt)))
{
- /* Skip the optional menu string. */
- if (CONSP (XCONS (elt)->cdr)
- && STRINGP (XCONS (XCONS (elt)->cdr)->car))
- {
- Lisp_Object tem;
-
- /* Copy the cell, since copy-alist didn't go this deep. */
- XCONS (elt)->cdr = Fcons (XCONS (XCONS (elt)->cdr)->car,
- XCONS (XCONS (elt)->cdr)->cdr);
- elt = XCONS (elt)->cdr;
+ Lisp_Object tem;
+ tem = XCDR (elt);
- /* Also skip the optional menu help string. */
- if (CONSP (XCONS (elt)->cdr)
- && STRINGP (XCONS (XCONS (elt)->cdr)->car))
+ /* Is this a new format menu item. */
+ if (EQ (XCAR (tem),Qmenu_item))
+ {
+ /* Copy cell with menu-item marker. */
+ XCDR (elt)
+ = Fcons (XCAR (tem), XCDR (tem));
+ elt = XCDR (elt);
+ tem = XCDR (elt);
+ if (CONSP (tem))
+ {
+ /* Copy cell with menu-item name. */
+ XCDR (elt)
+ = Fcons (XCAR (tem), XCDR (tem));
+ elt = XCDR (elt);
+ tem = XCDR (elt);
+ };
+ if (CONSP (tem))
+ {
+ /* Copy cell with binding and if the binding is a keymap,
+ copy that. */
+ XCDR (elt)
+ = Fcons (XCAR (tem), XCDR (tem));
+ elt = XCDR (elt);
+ tem = XCAR (elt);
+ if (!(SYMBOLP (tem) || NILP (Fkeymapp (tem))))
+ XCAR (elt) = Fcopy_keymap (tem);
+ tem = XCDR (elt);
+ if (CONSP (tem) && CONSP (XCAR (tem)))
+ /* Delete cache for key equivalences. */
+ XCDR (elt) = XCDR (tem);
+ }
+ }
+ else
+ {
+ /* It may be an old fomat menu item.
+ Skip the optional menu string.
+ */
+ if (STRINGP (XCAR (tem)))
{
- XCONS (elt)->cdr = Fcons (XCONS (XCONS (elt)->cdr)->car,
- XCONS (XCONS (elt)->cdr)->cdr);
- elt = XCONS (elt)->cdr;
+ /* Copy the cell, since copy-alist didn't go this deep. */
+ XCDR (elt)
+ = Fcons (XCAR (tem), XCDR (tem));
+ elt = XCDR (elt);
+ tem = XCDR (elt);
+ /* Also skip the optional menu help string. */
+ if (CONSP (tem) && STRINGP (XCAR (tem)))
+ {
+ XCDR (elt)
+ = Fcons (XCAR (tem), XCDR (tem));
+ elt = XCDR (elt);
+ tem = XCDR (elt);
+ }
+ /* There may also be a list that caches key equivalences.
+ Just delete it for the new keymap. */
+ if (CONSP (tem)
+ && CONSP (XCAR (tem))
+ && (NILP (XCAR (XCAR (tem)))
+ || VECTORP (XCAR (XCAR (tem)))))
+ XCDR (elt) = XCDR (tem);
}
- /* There may also be a list that caches key equivalences.
- Just delete it for the new keymap. */
- if (CONSP (XCONS (elt)->cdr)
- && CONSP (XCONS (XCONS (elt)->cdr)->car)
- && (NILP (tem = XCONS (XCONS (XCONS (elt)->cdr)->car)->car)
- || VECTORP (tem)))
- XCONS (elt)->cdr = XCONS (XCONS (elt)->cdr)->cdr;
+ if (CONSP (elt)
+ && ! SYMBOLP (XCDR (elt))
+ && ! NILP (Fkeymapp (XCDR (elt))))
+ XCDR (elt) = Fcopy_keymap (XCDR (elt));
}
- if (CONSP (elt)
- && ! SYMBOLP (XCONS (elt)->cdr)
- && ! NILP (Fkeymapp (XCONS (elt)->cdr)))
- XCONS (elt)->cdr = Fcopy_keymap (XCONS (elt)->cdr);
+
}
}
-
+
return copy;
}
\f
{
register int idx;
register Lisp_Object c;
- register Lisp_Object tem;
register Lisp_Object cmd;
int metized = 0;
int meta_bit;
Lisp_Object accept_default;
{
register int idx;
- register Lisp_Object tem;
register Lisp_Object cmd;
register Lisp_Object c;
int metized = 0;
make it define this key. */
Lisp_Object tail;
- for (tail = Fcdr (keymap); CONSP (tail); tail = XCONS (tail)->cdr)
- if (EQ (XCONS (tail)->car, Qkeymap))
+ for (tail = Fcdr (keymap); CONSP (tail); tail = XCDR (tail))
+ if (EQ (XCAR (tail), Qkeymap))
break;
if (!NILP (tail))
Lisp_Object **modeptr, **mapptr;
{
int i = 0;
+ int list_number = 0;
Lisp_Object alist, assoc, var, val;
+ Lisp_Object lists[2];
+
+ lists[0] = Vminor_mode_overriding_map_alist;
+ lists[1] = Vminor_mode_map_alist;
+
+ for (list_number = 0; list_number < 2; list_number++)
+ for (alist = lists[list_number];
+ CONSP (alist);
+ alist = XCDR (alist))
+ if ((assoc = XCAR (alist), CONSP (assoc))
+ && (var = XCAR (assoc), SYMBOLP (var))
+ && (val = find_symbol_value (var), ! EQ (val, Qunbound))
+ && ! NILP (val))
+ {
+ Lisp_Object temp;
- for (alist = Vminor_mode_map_alist;
- CONSP (alist);
- alist = XCONS (alist)->cdr)
- if ((assoc = XCONS (alist)->car, CONSP (assoc))
- && (var = XCONS (assoc)->car, SYMBOLP (var))
- && (val = find_symbol_value (var), ! EQ (val, Qunbound))
- && ! NILP (val))
- {
- Lisp_Object temp;
+ /* If a variable has an entry in Vminor_mode_overriding_map_alist,
+ and also an entry in Vminor_mode_map_alist,
+ ignore the latter. */
+ if (list_number == 1)
+ {
+ val = assq_no_quit (var, lists[0]);
+ if (!NILP (val))
+ break;
+ }
- if (i >= cmm_size)
- {
- Lisp_Object *newmodes, *newmaps;
+ if (i >= cmm_size)
+ {
+ Lisp_Object *newmodes, *newmaps;
- if (cmm_maps)
- {
- BLOCK_INPUT;
- cmm_size *= 2;
- newmodes
- = (Lisp_Object *) realloc (cmm_modes,
- cmm_size * sizeof (Lisp_Object));
- newmaps
- = (Lisp_Object *) realloc (cmm_maps,
- cmm_size * sizeof (Lisp_Object));
- UNBLOCK_INPUT;
- }
- else
- {
- BLOCK_INPUT;
- cmm_size = 30;
- newmodes
- = (Lisp_Object *) malloc (cmm_size * sizeof (Lisp_Object));
- newmaps
- = (Lisp_Object *) malloc (cmm_size * sizeof (Lisp_Object));
- UNBLOCK_INPUT;
- }
+ if (cmm_maps)
+ {
+ BLOCK_INPUT;
+ cmm_size *= 2;
+ newmodes
+ = (Lisp_Object *) realloc (cmm_modes,
+ cmm_size * sizeof (Lisp_Object));
+ newmaps
+ = (Lisp_Object *) realloc (cmm_maps,
+ cmm_size * sizeof (Lisp_Object));
+ UNBLOCK_INPUT;
+ }
+ else
+ {
+ BLOCK_INPUT;
+ cmm_size = 30;
+ newmodes
+ = (Lisp_Object *) malloc (cmm_size * sizeof (Lisp_Object));
+ newmaps
+ = (Lisp_Object *) malloc (cmm_size * sizeof (Lisp_Object));
+ UNBLOCK_INPUT;
+ }
- if (newmaps && newmodes)
- {
- cmm_modes = newmodes;
- cmm_maps = newmaps;
- }
- else
- break;
- }
+ if (newmaps && newmodes)
+ {
+ cmm_modes = newmodes;
+ cmm_maps = newmaps;
+ }
+ else
+ break;
+ }
- /* Get the keymap definition--or nil if it is not defined. */
- temp = internal_condition_case_1 (Findirect_function,
- XCONS (assoc)->cdr,
- Qerror, current_minor_maps_error);
- if (!NILP (temp))
- {
- cmm_modes[i] = var;
- cmm_maps [i] = temp;
- i++;
- }
- }
+ /* Get the keymap definition--or nil if it is not defined. */
+ temp = internal_condition_case_1 (Findirect_function,
+ XCDR (assoc),
+ Qerror, current_minor_maps_error);
+ if (!NILP (temp))
+ {
+ cmm_modes[i] = var;
+ cmm_maps [i] = temp;
+ i++;
+ }
+ }
if (modeptr) *modeptr = cmm_modes;
if (mapptr) *mapptr = cmm_maps;
return Flist (j, maps);
}
-DEFUN ("define-prefix-command", Fdefine_prefix_command, Sdefine_prefix_command, 1, 2, 0,
+DEFUN ("define-prefix-command", Fdefine_prefix_command, Sdefine_prefix_command, 1, 3, 0,
"Define COMMAND as a prefix command. COMMAND should be a symbol.\n\
A new sparse keymap is stored as COMMAND's function definition and its value.\n\
If a second optional argument MAPVAR is given, the map is stored as\n\
its value instead of as COMMAND's value; but COMMAND is still defined\n\
-as a function.")
- (command, mapvar)
- Lisp_Object command, mapvar;
+as a function.\n\
+The third optional argument NAME, if given, supplies a menu name\n\
+string for the map. This is required to use the keymap as a menu.")
+ (command, mapvar, name)
+ Lisp_Object command, mapvar, name;
{
Lisp_Object map;
- map = Fmake_sparse_keymap (Qnil);
+ map = Fmake_sparse_keymap (name);
Ffset (command, map);
if (!NILP (mapvar))
Fset (mapvar, map);
\f
/* Help functions for describing and documenting keymaps. */
-static Lisp_Object accessible_keymaps_char_table ();
+static void accessible_keymaps_char_table ();
/* This function cannot GC. */
we don't have to deal with the possibility of a string. */
if (STRINGP (prefix))
{
- int i;
+ int i, i_byte, c;
Lisp_Object copy;
copy = Fmake_vector (make_number (XSTRING (prefix)->size), Qnil);
- for (i = 0; i < XSTRING (prefix)->size; i++)
+ for (i = 0, i_byte = 0; i < XSTRING (prefix)->size;)
{
- int c = XSTRING (prefix)->data[i];
- if (c & 0200)
- c ^= 0200 | meta_modifier;
- XVECTOR (copy)->contents[i] = make_number (c);
+ int i_before = i;
+ if (STRING_MULTIBYTE (prefix))
+ FETCH_STRING_CHAR_ADVANCE (c, prefix, i, i_byte);
+ else
+ {
+ c = XSTRING (prefix)->data[i++];
+ if (c & 0200)
+ c ^= 0200 | meta_modifier;
+ }
+ XVECTOR (copy)->contents[i_before] = make_number (c);
}
prefix = copy;
}
This is a breadth-first traversal, where tail is the queue of
nodes, and maps accumulates a list of all nodes visited. */
- for (tail = maps; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = maps; CONSP (tail); tail = XCDR (tail))
{
register Lisp_Object thisseq, thismap;
Lisp_Object last;
&& XINT (last) >= prefixlen
&& EQ (Faref (thisseq, last), meta_prefix_char));
- for (; CONSP (thismap); thismap = XCONS (thismap)->cdr)
+ for (; CONSP (thismap); thismap = XCDR (thismap))
{
Lisp_Object elt;
- elt = XCONS (thismap)->car;
+ elt = XCAR (thismap);
QUIT;
if (CHAR_TABLE_P (elt))
{
- Lisp_Object *indices
- = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object));
+ Lisp_Object indices[3];
map_char_table (accessible_keymaps_char_table, Qnil,
elt, Fcons (maps, Fcons (tail, thisseq)),
/* This new sequence is the same length as
thisseq, so stick it in the list right
after this one. */
- XCONS (tail)->cdr
- = Fcons (Fcons (tem, cmd), XCONS (tail)->cdr);
+ XCDR (tail)
+ = Fcons (Fcons (tem, cmd), XCDR (tail));
}
else
{
}
else if (CONSP (elt))
{
- register Lisp_Object cmd, tem, filter;
+ register Lisp_Object cmd, tem;
- cmd = get_keyelt (XCONS (elt)->cdr, 0);
+ cmd = get_keyelt (XCDR (elt), 0);
/* Ignore definitions that aren't keymaps themselves. */
tem = Fkeymapp (cmd);
if (!NILP (tem))
if (NILP (tem))
{
/* Let elt be the event defined by this map entry. */
- elt = XCONS (elt)->car;
+ elt = XCAR (elt);
/* If the last key in thisseq is meta-prefix-char, and
this entry is a binding for an ascii keystroke,
/* This new sequence is the same length as
thisseq, so stick it in the list right
after this one. */
- XCONS (tail)->cdr
- = Fcons (Fcons (tem, cmd), XCONS (tail)->cdr);
+ XCDR (tail)
+ = Fcons (Fcons (tem, cmd), XCDR (tail));
}
else
nconc2 (tail,
/* Now find just the maps whose access prefixes start with PREFIX. */
good_maps = Qnil;
- for (; CONSP (maps); maps = XCONS (maps)->cdr)
+ for (; CONSP (maps); maps = XCDR (maps))
{
Lisp_Object elt, thisseq;
- elt = XCONS (maps)->car;
- thisseq = XCONS (elt)->car;
+ elt = XCAR (maps);
+ thisseq = XCAR (elt);
/* The access prefix must be at least as long as PREFIX,
and the first elements must match those of PREFIX. */
if (XINT (Flength (thisseq)) >= prefixlen)
return Fnreverse (good_maps);
}
-static Lisp_Object
+static void
accessible_keymaps_char_table (args, index, cmd)
Lisp_Object args, index, cmd;
{
Lisp_Object maps, tail, thisseq;
if (NILP (cmd))
- return Qnil;
+ return;
- maps = XCONS (args)->car;
- tail = XCONS (XCONS (args)->cdr)->car;
- thisseq = XCONS (XCONS (args)->cdr)->cdr;
+ maps = XCAR (args);
+ tail = XCAR (XCDR (args));
+ thisseq = XCDR (XCDR (args));
tem = Fkeymapp (cmd);
if (!NILP (tem))
nconc2 (tail, Fcons (Fcons (tem, cmd), Qnil));
}
}
- return Qnil;
}
\f
Lisp_Object Qsingle_key_description, Qkey_description;
Lisp_Object keys;
{
int len;
- int i;
+ int i, i_byte;
Lisp_Object sep;
Lisp_Object *args;
{
Lisp_Object vector;
vector = Fmake_vector (Flength (keys), Qnil);
- for (i = 0; i < XSTRING (keys)->size; i++)
+ for (i = 0, i_byte = 0; i < XSTRING (keys)->size; )
{
- if (XSTRING (keys)->data[i] & 0x80)
- XSETFASTINT (XVECTOR (vector)->contents[i],
- meta_modifier | (XSTRING (keys)->data[i] & ~0x80));
+ int c;
+ int i_before = i;
+
+ if (STRING_MULTIBYTE (keys))
+ FETCH_STRING_CHAR_ADVANCE (c, keys, i, i_byte);
else
- XSETFASTINT (XVECTOR (vector)->contents[i],
- XSTRING (keys)->data[i]);
+ {
+ c = XSTRING (keys)->data[i++];
+ if (c & 0200)
+ c ^= 0200 | meta_modifier;
+ }
+
+ XSETFASTINT (XVECTOR (vector)->contents[i_before], c);
}
keys = vector;
}
- else if (!VECTORP (keys))
- keys = wrong_type_argument (Qarrayp, keys);
- /* In effect, this computes
- (mapconcat 'single-key-description keys " ")
- but we shouldn't use mapconcat because it can do GC. */
+ if (VECTORP (keys))
+ {
+ /* In effect, this computes
+ (mapconcat 'single-key-description keys " ")
+ but we shouldn't use mapconcat because it can do GC. */
- len = XVECTOR (keys)->size;
- sep = build_string (" ");
- /* This has one extra element at the end that we don't pass to Fconcat. */
- args = (Lisp_Object *) alloca (len * 2 * sizeof (Lisp_Object));
+ len = XVECTOR (keys)->size;
+ sep = build_string (" ");
+ /* This has one extra element at the end that we don't pass to Fconcat. */
+ args = (Lisp_Object *) alloca (len * 2 * sizeof (Lisp_Object));
- for (i = 0; i < len; i++)
+ for (i = 0; i < len; i++)
+ {
+ args[i * 2] = Fsingle_key_description (XVECTOR (keys)->contents[i]);
+ args[i * 2 + 1] = sep;
+ }
+ }
+ else if (CONSP (keys))
{
- args[i * 2] = Fsingle_key_description (XVECTOR (keys)->contents[i]);
- args[i * 2 + 1] = sep;
+ /* In effect, this computes
+ (mapconcat 'single-key-description keys " ")
+ but we shouldn't use mapconcat because it can do GC. */
+
+ len = XFASTINT (Flength (keys));
+ sep = build_string (" ");
+ /* This has one extra element at the end that we don't pass to Fconcat. */
+ args = (Lisp_Object *) alloca (len * 2 * sizeof (Lisp_Object));
+
+ for (i = 0; i < len; i++)
+ {
+ args[i * 2] = Fsingle_key_description (XCAR (keys));
+ args[i * 2 + 1] = sep;
+ keys = XCDR (keys);
+ }
}
+ else
+ keys = wrong_type_argument (Qarrayp, keys);
return Fconcat (len * 2 - 1, args);
}
*p++ = 'L';
}
else if (c == ' ')
- {
+ {
*p++ = 'S';
*p++ = 'P';
*p++ = 'C';
}
- else if (c < 256)
+ else if (c < 128
+ || (NILP (current_buffer->enable_multibyte_characters)
+ && SINGLE_BYTE_CHAR_P (c)))
*p++ = c;
- else if (c < 512)
- {
- *p++ = '\\';
- *p++ = (7 & (c >> 6)) + '0';
- *p++ = (7 & (c >> 3)) + '0';
- *p++ = (7 & (c >> 0)) + '0';
- }
else
{
- *p++ = '\\';
- *p++ = (7 & (c >> 15)) + '0';
- *p++ = (7 & (c >> 12)) + '0';
- *p++ = (7 & (c >> 9)) + '0';
- *p++ = (7 & (c >> 6)) + '0';
- *p++ = (7 & (c >> 3)) + '0';
- *p++ = (7 & (c >> 0)) + '0';
+ if (! NILP (current_buffer->enable_multibyte_characters))
+ c = unibyte_char_to_multibyte (c);
+
+ if (NILP (current_buffer->enable_multibyte_characters)
+ || SINGLE_BYTE_CHAR_P (c)
+ || ! char_valid_p (c, 0))
+ {
+ int bit_offset;
+ *p++ = '\\';
+ /* The biggest character code uses 19 bits. */
+ for (bit_offset = 18; bit_offset >= 0; bit_offset -= 3)
+ {
+ if (c >= (1 << bit_offset))
+ *p++ = ((c & (7 << bit_offset)) >> bit_offset) + '0';
+ }
+ }
+ else
+ {
+ unsigned char work[4], *str;
+ int i = CHAR_STRING (c, work, str);
+ bcopy (str, p, i);
+ p += i;
+ }
}
return p;
(key)
Lisp_Object key;
{
- char tem[20];
+ if (CONSP (key) && lucid_event_type_list_p (key))
+ key = Fevent_convert_list (key);
key = EVENT_HEAD (key);
if (INTEGERP (key)) /* Normal character */
{
- *push_key_description (XUINT (key), tem) = 0;
- return build_string (tem);
+ unsigned int charset, c1, c2;
+ int without_bits = XINT (key) & ~((-1) << CHARACTERBITS);
+
+ if (SINGLE_BYTE_CHAR_P (without_bits))
+ charset = 0;
+ else
+ SPLIT_NON_ASCII_CHAR (without_bits, charset, c1, c2);
+
+ if (charset
+ && CHARSET_DEFINED_P (charset)
+ && ((c1 >= 0 && c1 < 32)
+ || (c2 >= 0 && c2 < 32)))
+ {
+ /* Handle a generic character. */
+ Lisp_Object name;
+ name = CHARSET_TABLE_INFO (charset, CHARSET_LONG_NAME_IDX);
+ CHECK_STRING (name, 0);
+ return concat2 (build_string ("Character set "), name);
+ }
+ else
+ {
+ char tem[30];
+
+ *push_key_description (XUINT (key), tem) = 0;
+ return build_string (tem);
+ }
}
else if (SYMBOLP (key)) /* Function key or event-symbol */
return Fsymbol_name (key);
if (!SINGLE_BYTE_CHAR_P (XFASTINT (character)))
{
- char *str;
+ unsigned char *str;
int len = non_ascii_char_to_string (XFASTINT (character), tem, &str);
- return make_string (str, len);
+ return make_multibyte_string (str, 1, len);
}
*push_text_char_description (XINT (character) & 0377, tem) = 0;
/* where-is - finding a command in a set of keymaps. */
static Lisp_Object where_is_internal_1 ();
-static Lisp_Object where_is_internal_2 ();
+static void where_is_internal_2 ();
/* This function can GC if Flookup_key autoloads any keymaps. */
{
Lisp_Object maps;
Lisp_Object found, sequences;
+ Lisp_Object keymap1;
int keymap_specified = !NILP (keymap);
struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5;
/* 1 means ignore all menu bindings entirely. */
int nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii);
+ /* Find keymaps accessible from `keymap' or the current
+ context. But don't muck with the value of `keymap',
+ because `where_is_internal_1' uses it to check for
+ shadowed bindings. */
+ keymap1 = keymap;
if (! keymap_specified)
{
#ifdef USE_TEXT_PROPERTIES
- keymap = get_local_map (PT, current_buffer);
+ keymap1 = get_local_map (PT, current_buffer);
#else
- keymap = current_buffer->keymap;
+ keymap1 = current_buffer->keymap;
#endif
}
-
- if (!NILP (keymap))
- maps = nconc2 (Faccessible_keymaps (get_keymap (keymap), Qnil),
+
+ if (!NILP (keymap1))
+ maps = nconc2 (Faccessible_keymaps (get_keymap (keymap1), Qnil),
Faccessible_keymaps (get_keymap (current_global_map),
Qnil));
else
minors = Fnreverse (Fcurrent_minor_mode_maps ());
while (!NILP (minors))
{
- maps = nconc2 (Faccessible_keymaps (get_keymap (XCONS (minors)->car),
+ maps = nconc2 (Faccessible_keymaps (get_keymap (XCAR (minors)),
Qnil),
maps);
- minors = XCONS (minors)->cdr;
+ minors = XCDR (minors);
}
}
advance map to the next element until i indicates that we
have finished off the vector. */
Lisp_Object elt, key, binding;
- elt = XCONS (map)->car;
- map = XCONS (map)->cdr;
+ elt = XCAR (map);
+ map = XCDR (map);
sequences = Qnil;
}
else if (CHAR_TABLE_P (elt))
{
- Lisp_Object *indices
- = (Lisp_Object *) alloca (3 * sizeof (Lisp_Object));
+ Lisp_Object indices[3];
Lisp_Object args;
+
args = Fcons (Fcons (Fcons (definition, noindirect),
Fcons (keymap, Qnil)),
Fcons (Fcons (this, last),
map_char_table (where_is_internal_2, Qnil, elt, args,
0, indices);
- sequences = XCONS (XCONS (XCONS (args)->car)->cdr)->cdr;
+ sequences = XCDR (XCDR (XCAR (args)));
}
else if (CONSP (elt))
{
Lisp_Object sequence;
- key = XCONS (elt)->car;
- binding = XCONS (elt)->cdr;
+ key = XCAR (elt);
+ binding = XCDR (elt);
sequence = where_is_internal_1 (binding, key, definition,
noindirect, keymap, this,
}
- for (; ! NILP (sequences); sequences = XCONS (sequences)->cdr)
+ for (; ! NILP (sequences); sequences = XCDR (sequences))
{
Lisp_Object sequence;
- sequence = XCONS (sequences)->car;
+ sequence = XCAR (sequences);
/* It is a true unshadowed match. Record it, unless it's already
been seen (as could happen when inheriting keymaps). */
Since map_char_table doesn't really use the return value from this function,
we the result append to RESULT, the slot in ARGS. */
-static Lisp_Object
+static void
where_is_internal_2 (args, key, binding)
Lisp_Object args, key, binding;
{
Lisp_Object result, sequence;
int nomenus, last_is_meta;
- result = XCONS (XCONS (XCONS (args)->car)->cdr)->cdr;
- definition = XCONS (XCONS (XCONS (args)->car)->car)->car;
- noindirect = XCONS (XCONS (XCONS (args)->car)->car)->cdr;
- keymap = XCONS (XCONS (XCONS (args)->car)->cdr)->car;
- this = XCONS (XCONS (XCONS (args)->cdr)->car)->car;
- last = XCONS (XCONS (XCONS (args)->cdr)->car)->cdr;
- nomenus = XFASTINT (XCONS (XCONS (XCONS (args)->cdr)->cdr)->car);
- last_is_meta = XFASTINT (XCONS (XCONS (XCONS (args)->cdr)->cdr)->cdr);
+ result = XCDR (XCDR (XCAR (args)));
+ definition = XCAR (XCAR (XCAR (args)));
+ noindirect = XCDR (XCAR (XCAR (args)));
+ keymap = XCAR (XCDR (XCAR (args)));
+ this = XCAR (XCAR (XCDR (args)));
+ last = XCDR (XCAR (XCDR (args)));
+ nomenus = XFASTINT (XCAR (XCDR (XCDR (args))));
+ last_is_meta = XFASTINT (XCDR (XCDR (XCDR (args))));
sequence = where_is_internal_1 (binding, key, definition, noindirect, keymap,
this, last, nomenus, last_is_meta);
if (!NILP (sequence))
- XCONS (XCONS (XCONS (args)->car)->cdr)->cdr
+ XCDR (XCDR (XCAR (args)))
= Fcons (sequence, result);
-
- return Qnil;
}
static Lisp_Object
else
break;
}
- /* If the contents are (STRING ...), reject. */
+ /* If the contents are (menu-item ...) or (STRING ...), reject. */
if (CONSP (definition)
- && STRINGP (XCONS (definition)->car))
+ && (EQ (XCAR (definition),Qmenu_item)
+ || STRINGP (XCAR (definition))))
return Qnil;
}
else
\f
/* describe-bindings - summarizing all the bindings in a set of keymaps. */
-DEFUN ("describe-bindings", Fdescribe_bindings, Sdescribe_bindings, 0, 1, "",
+DEFUN ("describe-bindings-internal", Fdescribe_bindings_internal, Sdescribe_bindings_internal, 0, 2, "",
"Show a list of all defined keys, and their definitions.\n\
-The list is put in a buffer, which is displayed.\n\
-An optional argument PREFIX, if non-nil, should be a key sequence;\n\
+We put that list in a buffer, and display the buffer.\n\
+\n\
+The optional argument MENUS, if non-nil, says to mention menu bindings.\n\
+\(Ordinarily these are omitted from the output.)\n\
+The optional argument PREFIX, if non-nil, should be a key sequence;\n\
then we display only bindings that start with that prefix.")
- (prefix)
- Lisp_Object prefix;
+ (menus, prefix)
+ Lisp_Object menus, prefix;
{
register Lisp_Object thisbuf;
XSETBUFFER (thisbuf, current_buffer);
internal_with_output_to_temp_buffer ("*Help*",
describe_buffer_bindings,
- Fcons (thisbuf, prefix));
+ list3 (thisbuf, prefix, menus));
return Qnil;
}
-/* ARG is (BUFFER . PREFIX). */
+/* ARG is (BUFFER PREFIX MENU-FLAG). */
static Lisp_Object
describe_buffer_bindings (arg)
Lisp_Object arg;
{
Lisp_Object descbuf, prefix, shadow;
+ int nomenu;
register Lisp_Object start1;
struct gcpro gcpro1;
char *alternate_heading
= "\
-Alternate Characters (use anywhere the nominal character is listed):\n\
-nominal alternate\n\
-------- ---------\n";
+Keyboard translations:\n\n\
+You type Translation\n\
+-------- -----------\n";
+
+ descbuf = XCAR (arg);
+ arg = XCDR (arg);
+ prefix = XCAR (arg);
+ arg = XCDR (arg);
+ nomenu = NILP (XCAR (arg));
- descbuf = XCONS (arg)->car;
- prefix = XCONS (arg)->cdr;
shadow = Qnil;
GCPRO1 (shadow);
for (c = 0; c < translate_len; c++)
if (translate[c] != c)
{
- char buf[20];
+ char buf[30];
char *bufend;
if (alternate_heading)
if (!NILP (Vkey_translation_map))
describe_map_tree (Vkey_translation_map, 0, Qnil, prefix,
- "Key translations", 0, 1, 0);
+ "Key translations", nomenu, 1, 0);
{
int i, nmaps;
p += sizeof (" Minor Mode Bindings") - 1;
*p = 0;
- describe_map_tree (maps[i], 1, shadow, prefix, title, 0, 0, 0);
+ describe_map_tree (maps[i], 1, shadow, prefix, title, nomenu, 0, 0);
shadow = Fcons (maps[i], shadow);
}
}
if (!NILP (start1))
{
describe_map_tree (start1, 1, shadow, prefix,
- "Major Mode Bindings", 0, 0, 0);
+ "Major Mode Bindings", nomenu, 0, 0);
shadow = Fcons (start1, shadow);
}
describe_map_tree (current_global_map, 1, shadow, prefix,
- "Global Bindings", 0, 0, 1);
+ "Global Bindings", nomenu, 0, 1);
/* Print the function-key-map translations under this prefix. */
if (!NILP (Vfunction_key_map))
describe_map_tree (Vfunction_key_map, 0, Qnil, prefix,
- "Function key map translations", 0, 1, 0);
+ "Function key map translations", nomenu, 1, 0);
call0 (intern ("help-mode"));
Fset_buffer (descbuf);
int transl;
int always_title;
{
- Lisp_Object maps, seen, sub_shadows;
+ Lisp_Object maps, orig_maps, seen, sub_shadows;
struct gcpro gcpro1, gcpro2, gcpro3;
int something = 0;
char *key_heading
key binding\n\
--- -------\n";
- maps = Faccessible_keymaps (startmap, prefix);
+ orig_maps = maps = Faccessible_keymaps (startmap, prefix);
seen = Qnil;
sub_shadows = Qnil;
GCPRO3 (maps, seen, sub_shadows);
Lisp_Object list;
/* Delete from MAPS each element that is for the menu bar. */
- for (list = maps; !NILP (list); list = XCONS (list)->cdr)
+ for (list = maps; !NILP (list); list = XCDR (list))
{
Lisp_Object elt, prefix, tem;
sub_shadows = Qnil;
- for (tail = shadow; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = shadow; CONSP (tail); tail = XCDR (tail))
{
Lisp_Object shmap;
- shmap = XCONS (tail)->car;
+ shmap = XCAR (tail);
/* If the sequence by which we reach this keymap is zero-length,
then the shadow map for this keymap is just SHADOW. */
sub_shadows = Fcons (shmap, sub_shadows);
}
- describe_map (Fcdr (elt), Fcar (elt),
+ /* Maps we have already listed in this loop shadow this map. */
+ for (tail = orig_maps; ! EQ (tail, maps); tail = XCDR (tail))
+ {
+ Lisp_Object tem;
+ tem = Fequal (Fcar (XCAR (tail)), prefix);
+ if (! NILP (tem))
+ sub_shadows = Fcons (XCDR (XCAR (tail)), sub_shadows);
+ }
+
+ describe_map (Fcdr (elt), prefix,
transl ? describe_translation : describe_command,
partial, sub_shadows, &seen, nomenu);
{
Lisp_Object tail, value;
- for (tail = shadow; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = shadow; CONSP (tail); tail = XCDR (tail))
{
- value = Flookup_key (XCONS (tail)->car, key, flag);
+ value = Flookup_key (XCAR (tail), key, flag);
if (!NILP (value))
return value;
}
describe_map (map, keys, elt_describer, partial, shadow, seen, nomenu)
register Lisp_Object map;
Lisp_Object keys;
- int (*elt_describer) ();
+ void (*elt_describer) P_ ((Lisp_Object));
int partial;
Lisp_Object shadow;
Lisp_Object *seen;
GCPRO3 (elt_prefix, definition, kludge);
- for (tail = map; CONSP (tail); tail = XCONS (tail)->cdr)
+ for (tail = map; CONSP (tail); tail = XCDR (tail))
{
QUIT;
- if (VECTORP (XCONS (tail)->car)
- || CHAR_TABLE_P (XCONS (tail)->car))
- describe_vector (XCONS (tail)->car,
+ if (VECTORP (XCAR (tail))
+ || CHAR_TABLE_P (XCAR (tail)))
+ describe_vector (XCAR (tail),
elt_prefix, elt_describer, partial, shadow, map,
(int *)0, 0);
- else if (CONSP (XCONS (tail)->car))
+ else if (CONSP (XCAR (tail)))
{
- event = XCONS (XCONS (tail)->car)->car;
+ event = XCAR (XCAR (tail));
/* Ignore bindings whose "keys" are not really valid events.
(We get these in the frames and buffers menu.) */
if (nomenu && EQ (event, Qmenu_bar))
continue;
- definition = get_keyelt (XCONS (XCONS (tail)->car)->cdr, 0);
+ definition = get_keyelt (XCDR (XCAR (tail)), 0);
/* Don't show undefined commands or suppressed commands. */
if (NILP (definition)) continue;
for alignment purposes. */
(*elt_describer) (definition);
}
- else if (EQ (XCONS (tail)->car, Qkeymap))
+ else if (EQ (XCAR (tail), Qkeymap))
{
/* The same keymap might be in the structure twice, if we're
using an inherited keymap. So skip anything we've already
encountered. */
tem = Fassq (tail, *seen);
- if (CONSP (tem) && !NILP (Fequal (XCONS (tem)->car, keys)))
+ if (CONSP (tem) && !NILP (Fequal (XCAR (tem), keys)))
break;
*seen = Fcons (Fcons (tail, keys), *seen);
}
UNGCPRO;
}
-static int
+static void
describe_vector_princ (elt)
Lisp_Object elt;
{
indices at higher levels in this char-table,
and CHAR_TABLE_DEPTH says how many levels down we have gone. */
+void
describe_vector (vector, elt_prefix, elt_describer,
partial, shadow, entire_map,
indices, char_table_depth)
register Lisp_Object vector;
Lisp_Object elt_prefix;
- int (*elt_describer) ();
+ void (*elt_describer) P_ ((Lisp_Object));
int partial;
Lisp_Object shadow;
Lisp_Object entire_map;
Lisp_Object suppress;
Lisp_Object kludge;
int first = 1;
- struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
+ struct gcpro gcpro1, gcpro2, gcpro3;
/* Range of elements to be handled. */
int from, to;
- /* Flag to tell if we should handle multibyte characters. */
- int multibyte = !NILP (current_buffer->enable_multibyte_characters);
/* A flag to tell if a leaf in this level of char-table is not a
generic character (i.e. a complete multibyte character). */
int complete_char;
insert_string ("<");
tem2 = CHARSET_TABLE_INFO (i - 128, CHARSET_SHORT_NAME_IDX);
if (STRINGP (tem2))
- insert_from_string (tem2, 0 , XSTRING (tem2)->size, 0);
+ insert_from_string (tem2, 0, 0, XSTRING (tem2)->size,
+ STRING_BYTES (XSTRING (tem2)), 0);
else
insert ("?", 1);
insert (">", 1);
/* If we find a sub char-table within a char-table,
scan it recursively; it defines the details for
a character set or a portion of a character set. */
- if (multibyte && CHAR_TABLE_P (vector) && SUB_CHAR_TABLE_P (definition))
+ if (CHAR_TABLE_P (vector) && SUB_CHAR_TABLE_P (definition))
{
insert ("\n", 1);
describe_vector (definition, elt_prefix, elt_describer,
return apropos_accumulate;
}
\f
+void
syms_of_keymap ()
{
- Lisp_Object tem;
-
Qkeymap = intern ("keymap");
staticpro (&Qkeymap);
in the list takes precedence.");
Vminor_mode_map_alist = Qnil;
+ DEFVAR_LISP ("minor-mode-overriding-map-alist", &Vminor_mode_overriding_map_alist,
+ "Alist of keymaps to use for minor modes, in current major mode.\n\
+This variable is a alist just like `minor-mode-map-alist', and it is\n\
+used the same way (and before `minor-mode-map-alist'); however,\n\
+it is provided for major modes to bind locally.");
+ Vminor_mode_overriding_map_alist = Qnil;
+
DEFVAR_LISP ("function-key-map", &Vfunction_key_map,
"Keymap mapping ASCII function key sequences onto their preferred forms.\n\
This allows Emacs to recognize function keys sent from ASCII\n\
Qnon_ascii = intern ("non-ascii");
staticpro (&Qnon_ascii);
+ Qmenu_item = intern ("menu-item");
+ staticpro (&Qmenu_item);
+
defsubr (&Skeymapp);
defsubr (&Skeymap_parent);
defsubr (&Sset_keymap_parent);
defsubr (&Ssingle_key_description);
defsubr (&Stext_char_description);
defsubr (&Swhere_is_internal);
- defsubr (&Sdescribe_bindings);
+ defsubr (&Sdescribe_bindings_internal);
defsubr (&Sapropos_internal);
}
+void
keys_of_keymap ()
{
- Lisp_Object tem;
-
initial_define_key (global_map, 033, "ESC-prefix");
initial_define_key (global_map, Ctl('X'), "Control-X-prefix");
}