You should have received a copy of the GNU General Public License
along with GNU Emacs; see the file COPYING. If not, write to
-the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+Boston, MA 02111-1307, USA. */
#include <config.h>
#include "keyboard.h"
#include "termhooks.h"
#include "blockinput.h"
+#include "puresize.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
documentation. */
Lisp_Object Vfunction_key_map;
+/* Keymap mapping ASCII function key sequences onto their preferred forms. */
+Lisp_Object Vkey_translation_map;
+
+/* A list of all commands given new bindings since a certain time
+ when nil was stored here.
+ This is used to speed up recomputation of menu key equivalents
+ when Emacs starts up. t means don't record anything here. */
+Lisp_Object Vdefine_key_rebound_commands;
+
Lisp_Object Qkeymapp, Qkeymap, Qnon_ascii;
/* A char with the CHAR_META bit set in a vector or the 0200 bit set
extern Lisp_Object Voverriding_local_map;
-void describe_map_tree ();
static Lisp_Object define_as_prefix ();
static Lisp_Object describe_buffer_bindings ();
-static void describe_command ();
+static void describe_command (), describe_translation ();
static void describe_map ();
\f
/* Keymap object support - constructors and predicates. */
#endif /* 0 */
DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
- "Return t if ARG is a keymap.\n\
+ "Return t if OBJECT is a keymap.\n\
\n\
A keymap is a list (keymap . ALIST),\n\
or a symbol whose function definition is itself a keymap.\n\
{
return get_keymap_1 (object, 1, 0);
}
+\f
+/* Return the parent map of the keymap MAP, or nil if it has none.
+ We assume that MAP is a valid keymap. */
+
+DEFUN ("keymap-parent", Fkeymap_parent, Skeymap_parent, 1, 1, 0,
+ "Return the parent keymap of KEYMAP.")
+ (keymap)
+ Lisp_Object keymap;
+{
+ Lisp_Object list;
+
+ keymap = get_keymap_1 (keymap, 1, 1);
+
+ /* Skip past the initial element `keymap'. */
+ list = XCONS (keymap)->cdr;
+ for (; CONSP (list); list = XCONS (list)->cdr)
+ {
+ /* See if there is another `keymap'. */
+ if (EQ (Qkeymap, XCONS (list)->car))
+ return list;
+ }
+
+ return Qnil;
+}
+
+/* Set the parent keymap of MAP to PARENT. */
+
+DEFUN ("set-keymap-parent", Fset_keymap_parent, Sset_keymap_parent, 2, 2, 0,
+ "Modify KEYMAP to set its parent map to PARENT.\n\
+PARENT should be nil or another keymap.")
+ (keymap, parent)
+ Lisp_Object keymap, parent;
+{
+ Lisp_Object list, prev;
+ int i;
+
+ keymap = get_keymap_1 (keymap, 1, 1);
+ if (!NILP (parent))
+ parent = get_keymap_1 (parent, 1, 1);
+
+ /* Skip past the initial element `keymap'. */
+ prev = keymap;
+ while (1)
+ {
+ list = XCONS (prev)->cdr;
+ /* If there is a parent keymap here, replace it.
+ If we came to the end, add the parent in PREV. */
+ if (! CONSP (list) || EQ (Qkeymap, XCONS (list)->car))
+ {
+ /* If we already have the right parent, return now
+ so that we avoid the loops below. */
+ if (EQ (XCONS (prev)->cdr, parent))
+ return parent;
+
+ XCONS (prev)->cdr = parent;
+ break;
+ }
+ prev = list;
+ }
+
+ /* Scan through for submaps, and set their parents too. */
+
+ for (list = XCONS (keymap)->cdr; CONSP (list); list = XCONS (list)->cdr)
+ {
+ /* Stop the scan when we come to the parent. */
+ if (EQ (XCONS (list)->car, Qkeymap))
+ break;
+
+ /* If this element holds a prefix map, deal with it. */
+ if (CONSP (XCONS (list)->car)
+ && CONSP (XCONS (XCONS (list)->car)->cdr))
+ fix_submap_inheritance (keymap, XCONS (XCONS (list)->car)->car,
+ XCONS (XCONS (list)->car)->cdr);
+
+ if (VECTORP (XCONS (list)->car))
+ for (i = 0; i < XVECTOR (XCONS (list)->car)->size; i++)
+ if (CONSP (XVECTOR (XCONS (list)->car)->contents[i]))
+ fix_submap_inheritance (keymap, make_number (i),
+ XVECTOR (XCONS (list)->car)->contents[i]);
+ }
+
+ return parent;
+}
+
+/* EVENT is defined in MAP as a prefix, and SUBMAP is its definition.
+ if EVENT is also a prefix in MAP's parent,
+ make sure that SUBMAP inherits that definition as its own parent. */
+
+fix_submap_inheritance (map, event, submap)
+ Lisp_Object map, event, submap;
+{
+ Lisp_Object map_parent, parent_entry;
+
+ /* SUBMAP is a cons that we found as a key binding.
+ Discard the other things found in a menu key binding. */
+
+ if (CONSP (submap)
+ && STRINGP (XCONS (submap)->car))
+ {
+ submap = XCONS (submap)->cdr;
+ /* Also remove a menu help string, if any,
+ following the menu item name. */
+ if (CONSP (submap) && STRINGP (XCONS (submap)->car))
+ submap = XCONS (submap)->cdr;
+ /* Also remove the sublist that caches key equivalences, if any. */
+ if (CONSP (submap)
+ && CONSP (XCONS (submap)->car))
+ {
+ Lisp_Object carcar;
+ carcar = XCONS (XCONS (submap)->car)->car;
+ if (NILP (carcar) || VECTORP (carcar))
+ submap = XCONS (submap)->cdr;
+ }
+ }
+
+ /* If it isn't a keymap now, there's no work to do. */
+ if (! CONSP (submap)
+ || ! EQ (XCONS (submap)->car, Qkeymap))
+ return;
+
+ map_parent = Fkeymap_parent (map);
+ if (! NILP (map_parent))
+ parent_entry = access_keymap (map_parent, event, 0, 0);
+ else
+ parent_entry = Qnil;
+ /* If 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)))
+ parent_entry = Qnil;
+ if (! EQ (parent_entry, submap))
+ Fset_keymap_parent (submap, parent_entry);
+}
+\f
/* Look up IDX in MAP. IDX may be any sort of event.
Note that this does only one level of lookup; IDX must be a single
event, not a sequence.
val = XCONS (binding)->cdr;
if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
return Qnil;
+ if (CONSP (val))
+ fix_submap_inheritance (map, idx, val);
return val;
}
if (t_ok && EQ (XCONS (binding)->car, Qt))
val = XVECTOR (binding)->contents[XFASTINT (idx)];
if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
return Qnil;
+ if (CONSP (val))
+ fix_submap_inheritance (map, idx, val);
return val;
}
}
{
/* 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 (!NILP (Vpurify_flag) && CONSP (def)
- && STRINGP (XCONS (def)->car))
+ if (CONSP (def) && PURE_P (def) && STRINGP (XCONS (def)->car))
def = Fcons (XCONS (def)->car, XCONS (def)->cdr);
if (!CONSP (keymap) || ! EQ (XCONS (keymap)->car, Qkeymap))
if (length == 0)
return Qnil;
+ if (SYMBOLP (def) && !EQ (Vdefine_key_rebound_commands, Qt))
+ Vdefine_key_rebound_commands = Fcons (def, Vdefine_key_rebound_commands);
+
GCPRO3 (keymap, key, def);
if (VECTORP (key))
c = Faref (key, make_number (idx));
if (CONSP (c) && lucid_event_type_list_p (c))
- c = convert_event_type_list (c);
+ c = Fevent_convert_list (c);
if (INTEGERP (c)
&& (XINT (c) & meta_bit)
\n\
Normally, `lookup-key' ignores bindings for t, which act as default\n\
bindings, used when nothing else in the keymap applies; this makes it\n\
-useable as a general function for probing keymaps. However, if the\n\
+usable as a general function for probing keymaps. However, if the\n\
third optional argument ACCEPT-DEFAULT is non-nil, `lookup-key' will\n\
recognize the default bindings, just as `read-key-sequence' does.")
(keymap, key, accept_default)
c = Faref (key, make_number (idx));
if (CONSP (c) && lucid_event_type_list_p (c))
- c = convert_event_type_list (c);
+ c = Fevent_convert_list (c);
if (INTEGERP (c)
&& (XINT (c) & meta_bit)
make it a prefix in this map, and make its definition
inherit the other prefix definition. */
inherit = access_keymap (keymap, c, 0, 0);
+#if 0
+ /* This code is needed to do the right thing in the following case:
+ keymap A inherits from B,
+ you define KEY as a prefix in A,
+ then later you define KEY as a prefix in B.
+ We want the old prefix definition in A to inherit from that in B.
+ It is hard to do that retroactively, so this code
+ creates the prefix in B right away.
+
+ But it turns out that this code causes problems immediately
+ when the prefix in A is defined: it causes B to define KEY
+ as a prefix with no subcommands.
+
+ So I took out this code. */
if (NILP (inherit))
{
/* If there's an inherited keymap
if (!NILP (tail))
inherit = define_as_prefix (tail, c);
}
+#endif
cmd = nconc2 (cmd, inherit);
store_in_keymap (keymap, c, cmd);
static Lisp_Object *cmm_modes, *cmm_maps;
static int cmm_size;
+/* Error handler used in current_minor_maps. */
+static Lisp_Object
+current_minor_maps_error ()
+{
+ return Qnil;
+}
+
/* Store a pointer to an array of the keymaps of the currently active
minor modes in *buf, and return the number of maps it contains.
&& (val = find_symbol_value (var), ! EQ (val, Qunbound))
&& ! NILP (val))
{
+ Lisp_Object temp;
+
if (i >= cmm_size)
{
Lisp_Object *newmodes, *newmaps;
else
break;
}
- cmm_modes[i] = var;
- cmm_maps [i] = Findirect_function (XCONS (assoc)->cdr);
- i++;
+
+ /* 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++;
+ }
}
if (modeptr) *modeptr = cmm_modes;
GCPRO1 (key);
- if (!NILP (Voverriding_local_map))
+ if (!NILP (current_kboard->Voverriding_terminal_local_map))
+ {
+ value = Flookup_key (current_kboard->Voverriding_terminal_local_map,
+ key, accept_default);
+ if (! NILP (value) && !INTEGERP (value))
+ RETURN_UNGCPRO (value);
+ }
+ else if (!NILP (Voverriding_local_map))
{
value = Flookup_key (Voverriding_local_map, key, accept_default);
if (! NILP (value) && !INTEGERP (value))
}
else
{
+ Lisp_Object local;
+
nmaps = current_minor_maps (0, &maps);
/* Note that all these maps are GCPRO'd
in the places where we found them. */
RETURN_UNGCPRO (value);
}
- if (! NILP (current_buffer->keymap))
+ local = get_local_map (PT, current_buffer);
+
+ if (! NILP (local))
{
- value = Flookup_key (current_buffer->keymap, key, accept_default);
+ value = Flookup_key (local, key, accept_default);
if (! NILP (value) && !INTEGERP (value))
RETURN_UNGCPRO (value);
}
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.")
- (name, mapvar)
- Lisp_Object name, mapvar;
+ (command, mapvar)
+ Lisp_Object command, mapvar;
{
Lisp_Object map;
map = Fmake_sparse_keymap (Qnil);
- Ffset (name, map);
+ Ffset (command, map);
if (!NILP (mapvar))
Fset (mapvar, map);
else
- Fset (name, map);
- return name;
+ Fset (command, map);
+ return command;
}
DEFUN ("use-global-map", Fuse_global_map, Suse_global_map, 1, 1, 0,
{
keymap = get_keymap (keymap);
current_global_map = keymap;
- record_asynch_buffer_change ();
return Qnil;
}
keymap = get_keymap (keymap);
current_buffer->keymap = keymap;
- record_asynch_buffer_change ();
return Qnil;
}
"Find all keymaps accessible via prefix characters from KEYMAP.\n\
Returns a list of elements of the form (KEYS . MAP), where the sequence\n\
KEYS starting from KEYMAP gets you to MAP. These elements are ordered\n\
-so that the KEYS increase in length. The first element is (\"\" . KEYMAP).\n\
+so that the KEYS increase in length. The first element is ([] . KEYMAP).\n\
An optional argument PREFIX, if non-nil, should be a key sequence;\n\
then the value includes only maps for prefixes that start with PREFIX.")
- (startmap, prefix)
- Lisp_Object startmap, prefix;
+ (keymap, prefix)
+ Lisp_Object keymap, prefix;
{
Lisp_Object maps, good_maps, tail;
int prefixlen = 0;
/* If a prefix was specified, start with the keymap (if any) for
that prefix, so we don't waste time considering other prefixes. */
Lisp_Object tem;
- tem = Flookup_key (startmap, prefix, Qt);
+ tem = Flookup_key (keymap, prefix, Qt);
/* Flookup_key may give us nil, or a number,
if the prefix is not defined in this particular map.
It might even give us a list that isn't a keymap. */
}
else
maps = Fcons (Fcons (Fmake_vector (make_number (0), Qnil),
- get_keymap (startmap)),
+ get_keymap (keymap)),
Qnil);
/* For each map in the list maps,
/* This function cannot GC. */
DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, 1, 1, 0,
- "Return a pretty description of file-character CHAR.\n\
+ "Return a pretty description of file-character CHARACTER.\n\
Control characters turn into \"^char\", etc.")
- (chr)
- Lisp_Object chr;
+ (character)
+ Lisp_Object character;
{
char tem[6];
- CHECK_NUMBER (chr, 0);
+ CHECK_NUMBER (character, 0);
- *push_text_char_description (XINT (chr) & 0377, tem) = 0;
+ *push_text_char_description (XINT (character) & 0377, tem) = 0;
return build_string (tem);
}
Fset_buffer (Vstandard_output);
/* Report on alternates for keys. */
- if (STRINGP (Vkeyboard_translate_table))
+ if (STRINGP (Vkeyboard_translate_table) && !NILP (prefix))
{
int c;
unsigned char *translate = XSTRING (Vkeyboard_translate_table)->data;
insert ("\n", 1);
}
+ if (!NILP (Vkey_translation_map))
+ describe_map_tree (Vkey_translation_map, 0, Qnil, prefix,
+ "Key translations", 0, 1, 0);
+
{
int i, nmaps;
Lisp_Object *modes, *maps;
/* Temporarily switch to descbuf, so that we can get that buffer's
minor modes correctly. */
Fset_buffer (descbuf);
- if (!NILP (Voverriding_local_map))
+
+ if (!NILP (current_kboard->Voverriding_terminal_local_map)
+ || !NILP (Voverriding_local_map))
nmaps = 0;
else
nmaps = current_minor_maps (&modes, &maps);
p += sizeof (" Minor Mode Bindings") - 1;
*p = 0;
- describe_map_tree (maps[i], 0, shadow, prefix, title, 0);
+ describe_map_tree (maps[i], 0, shadow, prefix, title, 0, 0, 0);
shadow = Fcons (maps[i], shadow);
}
}
/* Print the (major mode) local map. */
- if (!NILP (Voverriding_local_map))
+ if (!NILP (current_kboard->Voverriding_terminal_local_map))
+ start1 = current_kboard->Voverriding_terminal_local_map;
+ else if (!NILP (Voverriding_local_map))
start1 = Voverriding_local_map;
else
start1 = XBUFFER (descbuf)->keymap;
if (!NILP (start1))
{
describe_map_tree (start1, 0, shadow, prefix,
- "Major Mode Bindings", 0);
+ "Major Mode Bindings", 0, 0, 0);
shadow = Fcons (start1, shadow);
}
describe_map_tree (current_global_map, 0, shadow, prefix,
- "Global Bindings", 0);
+ "Global Bindings", 0, 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);
call0 (intern ("help-mode"));
Fset_buffer (descbuf);
return Qnil;
}
-/* Insert a desription of the key bindings in STARTMAP,
+/* Insert a description of the key bindings in STARTMAP,
followed by those of all maps reachable through STARTMAP.
If PARTIAL is nonzero, omit certain "uninteresting" commands
(such as `undefined').
PREFIX, if non-nil, says mention only keys that start with PREFIX.
TITLE, if not 0, is a string to insert at the beginning.
TITLE should not end with a colon or a newline; we supply that.
- If NOMENU is not 0, then omit menu-bar commands. */
+ If NOMENU is not 0, then omit menu-bar commands.
+
+ If TRANSL is nonzero, the definitions are actually key translations
+ so print strings and vectors differently.
+
+ If ALWAYS_TITLE is nonzero, print the title even if there are no maps
+ to look through. */
void
-describe_map_tree (startmap, partial, shadow, prefix, title, nomenu)
+describe_map_tree (startmap, partial, shadow, prefix, title, nomenu, transl,
+ always_title)
Lisp_Object startmap, shadow, prefix;
int partial;
char *title;
int nomenu;
+ int transl;
+ int always_title;
{
Lisp_Object maps, seen, sub_shadows;
struct gcpro gcpro1, gcpro2, gcpro3;
}
}
- if (!NILP (maps))
+ if (!NILP (maps) || always_title)
{
if (title)
{
sub_shadows = Fcons (shmap, sub_shadows);
}
- describe_map (Fcdr (elt), Fcar (elt), describe_command,
- partial, sub_shadows, &seen);
+ describe_map (Fcdr (elt), Fcar (elt),
+ transl ? describe_translation : describe_command,
+ partial, sub_shadows, &seen, nomenu);
skip: ;
}
UNGCPRO;
}
+static int previous_description_column;
+
static void
describe_command (definition)
Lisp_Object definition;
{
register Lisp_Object tem1;
+ int column = current_column ();
+ int description_column;
- Findent_to (make_number (16), make_number (1));
+ /* If column 16 is no good, go to col 32;
+ but don't push beyond that--go to next line instead. */
+ if (column > 30)
+ {
+ insert_char ('\n');
+ description_column = 32;
+ }
+ else if (column > 14 || (column > 10 && previous_description_column == 32))
+ description_column = 32;
+ else
+ description_column = 16;
+
+ Findent_to (make_number (description_column), make_number (1));
+ previous_description_column = description_column;
if (SYMBOLP (definition))
{
insert1 (tem1);
insert_string ("\n");
}
- else if (STRINGP (definition))
+ else if (STRINGP (definition) || VECTORP (definition))
insert_string ("Keyboard Macro\n");
else
{
}
}
+static void
+describe_translation (definition)
+ Lisp_Object definition;
+{
+ register Lisp_Object tem1;
+
+ Findent_to (make_number (16), make_number (1));
+
+ if (SYMBOLP (definition))
+ {
+ XSETSTRING (tem1, XSYMBOL (definition)->name);
+ insert1 (tem1);
+ insert_string ("\n");
+ }
+ else if (STRINGP (definition) || VECTORP (definition))
+ {
+ insert1 (Fkey_description (definition));
+ insert_string ("\n");
+ }
+ else
+ {
+ tem1 = Fkeymapp (definition);
+ if (!NILP (tem1))
+ insert_string ("Prefix Command\n");
+ else
+ insert_string ("??\n");
+ }
+}
+
/* Like Flookup_key, but uses a list of keymaps SHADOW instead of a single map.
Returns the first non-nil binding found in any of those maps. */
/* Describe the contents of map MAP, assuming that this map itself is
reached by the sequence of prefix keys KEYS (a string or vector).
- PARTIAL, SHADOW are as in `describe_map_tree' above. */
+ PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */
static void
-describe_map (map, keys, elt_describer, partial, shadow, seen)
+describe_map (map, keys, elt_describer, partial, shadow, seen, nomenu)
register Lisp_Object map;
Lisp_Object keys;
int (*elt_describer) ();
int partial;
Lisp_Object shadow;
Lisp_Object *seen;
+ int nomenu;
{
Lisp_Object elt_prefix;
Lisp_Object tail, definition, event;
if (VECTORP (XCONS (tail)->car))
describe_vector (XCONS (tail)->car,
- elt_prefix, elt_describer, partial, shadow);
+ elt_prefix, elt_describer, partial, shadow, map);
else if (CONSP (XCONS (tail)->car))
{
event = XCONS (XCONS (tail)->car)->car;
if (! (SYMBOLP (event) || INTEGERP (event)))
continue;
+ if (nomenu && EQ (event, Qmenu_bar))
+ continue;
+
definition = get_keyelt (XCONS (XCONS (tail)->car)->cdr, 0);
/* Don't show undefined commands or suppressed commands. */
if (first)
{
+ previous_description_column = 0;
insert ("\n", 1);
first = 0;
}
int count = specpdl_ptr - specpdl;
specbind (Qstandard_output, Fcurrent_buffer ());
- CHECK_VECTOR (vector, 0);
- describe_vector (vector, Qnil, describe_vector_princ, 0, Qnil);
+ CHECK_VECTOR_OR_CHAR_TABLE (vector, 0);
+ describe_vector (vector, Qnil, describe_vector_princ, 0, Qnil, Qnil);
return unbind_to (count, Qnil);
}
-describe_vector (vector, elt_prefix, elt_describer, partial, shadow)
+/* Insert in the current buffer a description of the contents of VECTOR.
+ We call ELT_DESCRIBER to insert the description of one value found
+ in VECTOR.
+
+ ELT_PREFIX describes what "comes before" the keys or indices defined
+ by this vector.
+
+ If the vector is in a keymap, ELT_PREFIX is a prefix key which
+ leads to this keymap.
+
+ If the vector is a chartable, ELT_PREFIX is the vector
+ of bytes that lead to the character set or portion of a character
+ set described by this chartable.
+
+ If PARTIAL is nonzero, it means do not mention suppressed commands
+ (that assumes the vector is in a keymap).
+
+ SHADOW is a list of keymaps that shadow this map.
+ If it is non-nil, then we look up the key in those maps
+ and we don't mention it now if it is defined by any of them.
+
+ ENTIRE_MAP is the keymap in which this vector appears.
+ If the definition in effect in the whole map does not match
+ the one in this vector, we ignore this one. */
+
+describe_vector (vector, elt_prefix, elt_describer,
+ partial, shadow, entire_map)
register Lisp_Object vector;
Lisp_Object elt_prefix;
int (*elt_describer) ();
int partial;
Lisp_Object shadow;
+ Lisp_Object entire_map;
{
Lisp_Object this;
Lisp_Object dummy;
- Lisp_Object tem1, tem2;
+ Lisp_Object definition;
+ Lisp_Object tem2;
register int i;
Lisp_Object suppress;
Lisp_Object kludge;
+ Lisp_Object chartable_kludge;
int first = 1;
- struct gcpro gcpro1, gcpro2, gcpro3;
+ int size;
+ struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
- tem1 = Qnil;
+ definition = Qnil;
+ chartable_kludge = Qnil;
/* This vector gets used to present single keys to Flookup_key. Since
that is done once per vector element, we don't want to cons up a
fresh vector every time. */
kludge = Fmake_vector (make_number (1), Qnil);
- GCPRO3 (elt_prefix, tem1, kludge);
+ GCPRO4 (elt_prefix, definition, kludge, chartable_kludge);
if (partial)
suppress = intern ("suppress-keymap");
- for (i = 0; i < XVECTOR (vector)->size; i++)
+ /* This does the right thing for char-tables as well as ordinary vectors. */
+ size = XFASTINT (Flength (vector));
+
+ for (i = 0; i < size; i++)
{
QUIT;
- tem1 = get_keyelt (XVECTOR (vector)->contents[i], 0);
+ definition = get_keyelt (XVECTOR (vector)->contents[i], 0);
- if (NILP (tem1)) continue;
+ if (NILP (definition)) continue;
/* Don't mention suppressed commands. */
- if (SYMBOLP (tem1) && partial)
+ if (SYMBOLP (definition) && partial)
{
- this = Fget (tem1, suppress);
+ this = Fget (definition, suppress);
if (!NILP (this))
continue;
}
- /* If this command in this map is shadowed by some other map,
- ignore it. */
+ /* If this binding is shadowed by some other map, ignore it. */
if (!NILP (shadow))
{
Lisp_Object tem;
if (!NILP (tem)) continue;
}
+ /* Ignore this definition if it is shadowed by an earlier
+ one in the same keymap. */
+ if (!NILP (entire_map))
+ {
+ Lisp_Object tem;
+
+ XVECTOR (kludge)->contents[0] = make_number (i);
+ tem = Flookup_key (entire_map, kludge, Qt);
+
+ if (! EQ (tem, definition))
+ continue;
+ }
+
+ /* If we find a 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 (CHAR_TABLE_P (vector) && CHAR_TABLE_P (definition))
+ {
+ int outer_level
+ = !NILP (elt_prefix) ? XVECTOR (elt_prefix)->size : 0;
+ if (NILP (chartable_kludge))
+ {
+ chartable_kludge
+ = Fmake_vector (make_number (outer_level + 1), Qnil);
+ if (outer_level != 0)
+ bcopy (XVECTOR (elt_prefix)->contents,
+ XVECTOR (chartable_kludge)->contents,
+ outer_level * sizeof (Lisp_Object));
+ }
+ XVECTOR (chartable_kludge)->contents[outer_level]
+ = make_number (i);
+ describe_vector (definition, chartable_kludge, elt_describer,
+ partial, shadow, entire_map);
+ continue;
+ }
+
if (first)
{
insert ("\n", 1);
first = 0;
}
- /* Output the prefix that applies to every entry in this map. */
- if (!NILP (elt_prefix))
- insert1 (elt_prefix);
+ if (CHAR_TABLE_P (vector))
+ {
+ if (!NILP (elt_prefix))
+ {
+ /* Must combine elt_prefix with i to produce a character
+ code, then insert that character's description. */
+ }
+ else
+ {
+ /* Get the string to describe the character I, and print it. */
+ XSETFASTINT (dummy, i);
+
+ /* THIS gets the string to describe the character DUMMY. */
+ this = Fsingle_key_description (dummy);
+ insert1 (this);
+ }
+ }
+ else
+ {
+ /* Output the prefix that applies to every entry in this map. */
+ if (!NILP (elt_prefix))
+ insert1 (elt_prefix);
- /* Get the string to describe the character I, and print it. */
- XSETFASTINT (dummy, i);
+ /* Get the string to describe the character I, and print it. */
+ XSETFASTINT (dummy, i);
- /* THIS gets the string to describe the character DUMMY. */
- this = Fsingle_key_description (dummy);
- insert1 (this);
+ /* THIS gets the string to describe the character DUMMY. */
+ this = Fsingle_key_description (dummy);
+ insert1 (this);
+ }
/* Find all consecutive characters that have the same definition. */
while (i + 1 < XVECTOR (vector)->size
&& (tem2 = get_keyelt (XVECTOR (vector)->contents[i+1], 0),
- EQ (tem2, tem1)))
+ EQ (tem2, definition)))
i++;
/* If we have a range of more than one character,
if (i != XINT (dummy))
{
insert (" .. ", 4);
- if (!NILP (elt_prefix))
- insert1 (elt_prefix);
+ if (CHAR_TABLE_P (vector))
+ {
+ if (!NILP (elt_prefix))
+ {
+ /* Must combine elt_prefix with i to produce a character
+ code, then insert that character's description. */
+ }
+ else
+ {
+ XSETFASTINT (dummy, i);
- XSETFASTINT (dummy, i);
- insert1 (Fsingle_key_description (dummy));
+ this = Fsingle_key_description (dummy);
+ insert1 (this);
+ }
+ }
+ else
+ {
+ if (!NILP (elt_prefix))
+ insert1 (elt_prefix);
+
+ XSETFASTINT (dummy, i);
+ insert1 (Fsingle_key_description (dummy));
+ }
}
/* Print a description of the definition of this character.
elt_describer will take care of spacing out far enough
for alignment purposes. */
- (*elt_describer) (tem1);
+ (*elt_describer) (definition);
}
UNGCPRO;
DEFUN ("apropos-internal", Fapropos_internal, Sapropos_internal, 1, 2, 0,
"Show all symbols whose names contain match for REGEXP.\n\
-If optional 2nd arg PRED is non-nil, (funcall PRED SYM) is done\n\
+If optional 2nd arg PREDICATE is non-nil, (funcall PREDICATE SYMBOL) is done\n\
for each symbol and a symbol is mentioned only if that returns non-nil.\n\
Return list of symbols found.")
- (string, pred)
- Lisp_Object string, pred;
+ (regexp, predicate)
+ Lisp_Object regexp, predicate;
{
struct gcpro gcpro1, gcpro2;
- CHECK_STRING (string, 0);
- apropos_predicate = pred;
+ CHECK_STRING (regexp, 0);
+ apropos_predicate = predicate;
GCPRO2 (apropos_predicate, apropos_accumulate);
apropos_accumulate = Qnil;
- map_obarray (Vobarray, apropos_accum, string);
+ map_obarray (Vobarray, apropos_accum, regexp);
apropos_accumulate = Fsort (apropos_accumulate, Qstring_lessp);
UNGCPRO;
return apropos_accumulate;
Fset (intern ("ctl-x-map"), control_x_map);
Ffset (intern ("Control-X-prefix"), control_x_map);
+ DEFVAR_LISP ("define-key-rebound-commands", &Vdefine_key_rebound_commands,
+ "List of commands given new key bindings recently.\n\
+This is used for internal purposes during Emacs startup;\n\
+don't alter it yourself.");
+ Vdefine_key_rebound_commands = Qt;
+
DEFVAR_LISP ("minibuffer-local-map", &Vminibuffer_local_map,
"Default keymap to use when reading from the minibuffer.");
Vminibuffer_local_map = Fmake_sparse_keymap (Qnil);
key, typing `ESC O P x' would return [f1 x].");
Vfunction_key_map = Fmake_sparse_keymap (Qnil);
+ DEFVAR_LISP ("key-translation-map", &Vkey_translation_map,
+ "Keymap of key translations that can override keymaps.\n\
+This keymap works like `function-key-map', but comes after that,\n\
+and applies even for keys that have ordinary bindings.");
+ Vkey_translation_map = Qnil;
+
Qsingle_key_description = intern ("single-key-description");
staticpro (&Qsingle_key_description);
staticpro (&Qnon_ascii);
defsubr (&Skeymapp);
+ defsubr (&Skeymap_parent);
+ defsubr (&Sset_keymap_parent);
defsubr (&Smake_keymap);
defsubr (&Smake_sparse_keymap);
defsubr (&Scopy_keymap);