X-Git-Url: https://git.hcoop.net/bpt/emacs.git/blobdiff_plain/8e4dfd54039beee8118648b00be9a5c128cd23e1..3d24868836b773b9a698eb1f34e3903462f14843:/src/keymap.c diff --git a/src/keymap.c b/src/keymap.c index 5282711bac..6f3cd35b87 100644 --- a/src/keymap.c +++ b/src/keymap.c @@ -25,6 +25,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "commands.h" #include "buffer.h" #include "keyboard.h" +#include "termhooks.h" +#include "blockinput.h" #define min(a, b) ((a) < (b) ? (a) : (b)) @@ -71,11 +73,11 @@ Lisp_Object Vminor_mode_map_alist; documentation. */ Lisp_Object Vfunction_key_map; -Lisp_Object Qkeymapp, Qkeymap; - -/* A char over 0200 in a key sequence - is equivalent to prefixing with this character. */ +Lisp_Object Qkeymapp, Qkeymap, Qnon_ascii; +/* 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 + character. */ extern Lisp_Object meta_prefix_char; void describe_map_tree (); @@ -88,7 +90,7 @@ static void describe_map_2 (); 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 128-element vector which holds the bindings for the ASCII\n\ +VECTOR is a vector which 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\ @@ -168,10 +170,11 @@ synkey (frommap, fromchar, tomap, tochar) DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0, "Return t if ARG is a keymap.\n\ \n\ -A keymap is list (keymap . ALIST), a list (keymap VECTOR . ALIST),\n\ +A keymap is a list (keymap . ALIST),\n\ or a symbol whose function definition is a keymap is itself a keymap.\n\ ALIST elements look like (CHAR . DEFN) or (SYMBOL . DEFN);\n\ -VECTOR is a 128-element vector of bindings for ASCII characters.") +a vector of densely packed bindings for small character codes\n\ +is also allowed as an element.") (object) Lisp_Object object; { @@ -265,13 +268,9 @@ access_keymap (map, idx, t_ok) ought to be a symbol. */ idx = EVENT_HEAD (idx); - if (XTYPE (idx) == Lisp_Int - && (XINT (idx) < 0 || XINT (idx) >= DENSE_TABLE_SIZE)) - error ("only ASCII characters may be looked up in keymaps"); - /* If idx is a symbol, it might have modifiers, which need to be put in the canonical order. */ - else if (XTYPE (idx) == Lisp_Symbol) + if (XTYPE (idx) == Lisp_Symbol) idx = reorder_modifiers (idx); { @@ -292,8 +291,9 @@ access_keymap (map, idx, t_ok) break; case Lisp_Vector: - if (XVECTOR (binding)->size == DENSE_TABLE_SIZE - && XTYPE (idx) == Lisp_Int) + if (XTYPE (idx) == Lisp_Int + && XINT (idx) >= 0 + && XINT (idx) < XVECTOR (binding)->size) return XVECTOR (binding)->contents[XINT (idx)]; break; } @@ -364,13 +364,9 @@ store_in_keymap (keymap, idx, def) ought to be a symbol. */ idx = EVENT_HEAD (idx); - if (XTYPE (idx) == Lisp_Int - && (XINT (idx) < 0 || XINT (idx) >= DENSE_TABLE_SIZE)) - error ("only ASCII characters may be used as keymap indices"); - /* If idx is a symbol, it might have modifiers, which need to be put in the canonical order. */ - else if (XTYPE (idx) == Lisp_Symbol) + if (XTYPE (idx) == Lisp_Symbol) idx = reorder_modifiers (idx); @@ -393,9 +389,8 @@ store_in_keymap (keymap, idx, def) switch (XTYPE (elt)) { case Lisp_Vector: - if (XVECTOR (elt)->size != DENSE_TABLE_SIZE) - break; - if (XTYPE (idx) == Lisp_Int) + if (XTYPE (idx) == Lisp_Int + && XINT (idx) >= 0 && XINT (idx) < XVECTOR (elt)->size) { XVECTOR (elt)->contents[XFASTINT (idx)] = def; return def; @@ -453,15 +448,14 @@ is not copied.") { Lisp_Object elt = XCONS (tail)->car; - if (XTYPE (elt) == Lisp_Vector - && XVECTOR (elt)->size == DENSE_TABLE_SIZE) + if (XTYPE (elt) == Lisp_Vector) { int i; elt = Fcopy_sequence (elt); XCONS (tail)->car = elt; - for (i = 0; i < DENSE_TABLE_SIZE; i++) + for (i = 0; i < XVECTOR (elt)->size; i++) if (XTYPE (XVECTOR (elt)->contents[i]) != Lisp_Symbol && Fkeymapp (XVECTOR (elt)->contents[i])) XVECTOR (elt)->contents[i] = @@ -506,6 +500,7 @@ the front of KEYMAP.") register Lisp_Object tem; register Lisp_Object cmd; int metized = 0; + int meta_bit; int length; struct gcpro gcpro1, gcpro2, gcpro3; @@ -521,13 +516,18 @@ the front of KEYMAP.") GCPRO3 (keymap, key, def); + if (XTYPE (key) == Lisp_Vector) + meta_bit = meta_modifier; + else + meta_bit = 0x80; + idx = 0; while (1) { c = Faref (key, make_number (idx)); if (XTYPE (c) == Lisp_Int - && XINT (c) >= 0200 + && (XINT (c) & meta_bit) && !metized) { c = meta_prefix_char; @@ -536,7 +536,7 @@ the front of KEYMAP.") else { if (XTYPE (c) == Lisp_Int) - XSETINT (c, XINT (c) & 0177); + XSETINT (c, XINT (c) & ~meta_bit); metized = 0; idx++; @@ -555,24 +555,38 @@ the front of KEYMAP.") keymap = get_keymap_1 (cmd, 0, 1); if (NILP (keymap)) - error ("Key sequence %s uses invalid prefix characters", - XSTRING (key)->data); + { + /* We must use Fkey_description rather than just passing key to + error; key might be a vector, not a string. */ + Lisp_Object description = Fkey_description (key); + + error ("Key sequence %s uses invalid prefix characters", + XSTRING (description)->data); + } } } /* Value is number if KEY is too long; NIL if valid but has no definition. */ -DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 2, 0, +DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0, "In keymap KEYMAP, look up key sequence KEY. Return the definition.\n\ nil means undefined. See doc of `define-key' for kinds of definitions.\n\ +\n\ A number as value means KEY is \"too long\";\n\ that is, characters or symbols in it except for the last one\n\ fail to be a valid sequence of prefix characters in KEYMAP.\n\ The number is how many characters at the front of KEY\n\ -it takes to reach a non-prefix command.") - (keymap, key) +it takes to reach a non-prefix command.\n\ +\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\ +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) register Lisp_Object keymap; Lisp_Object key; + Lisp_Object accept_default; { register int idx; register Lisp_Object tem; @@ -580,6 +594,8 @@ it takes to reach a non-prefix command.") register Lisp_Object c; int metized = 0; int length; + int t_ok = ! NILP (accept_default); + int meta_bit; keymap = get_keymap (keymap); @@ -591,13 +607,18 @@ it takes to reach a non-prefix command.") if (length == 0) return keymap; + if (XTYPE (key) == Lisp_Vector) + meta_bit = meta_modifier; + else + meta_bit = 0x80; + idx = 0; while (1) { c = Faref (key, make_number (idx)); if (XTYPE (c) == Lisp_Int - && XINT (c) >= 0200 + && (XINT (c) & meta_bit) && !metized) { c = meta_prefix_char; @@ -606,13 +627,13 @@ it takes to reach a non-prefix command.") else { if (XTYPE (c) == Lisp_Int) - XSETINT (c, XINT (c) & 0177); + XSETINT (c, XINT (c) & ~meta_bit); metized = 0; idx++; } - cmd = get_keyelt (access_keymap (keymap, c, 0)); + cmd = get_keyelt (access_keymap (keymap, c, t_ok)); if (idx == length) return cmd; @@ -624,9 +645,8 @@ it takes to reach a non-prefix command.") } } -/* Append a key to the end of a key sequence. If key_sequence is a - string and key is a character, the result will be another string; - otherwise, it will be a vector. */ +/* Append a key to the end of a key sequence. We always make a vector. */ + Lisp_Object append_key (key_sequence, key) Lisp_Object key_sequence, key; @@ -635,17 +655,8 @@ append_key (key_sequence, key) args[0] = key_sequence; - if (XTYPE (key_sequence) == Lisp_String - && XTYPE (key) == Lisp_Int) - { - args[1] = Fchar_to_string (key); - return Fconcat (2, args); - } - else - { - args[1] = Fcons (key, Qnil); - return Fvconcat (2, args); - } + args[1] = Fcons (key, Qnil); + return Fvconcat (2, args); } @@ -694,13 +705,17 @@ current_minor_maps (modeptr, mapptr) if (cmm_maps) { + BLOCK_INPUT; newmodes = (Lisp_Object *) realloc (cmm_modes, cmm_size *= 2); newmaps = (Lisp_Object *) realloc (cmm_maps, cmm_size); + UNBLOCK_INPUT; } else { + BLOCK_INPUT; newmodes = (Lisp_Object *) malloc (cmm_size = 30); newmaps = (Lisp_Object *) malloc (cmm_size); + UNBLOCK_INPUT; } if (newmaps && newmodes) @@ -712,7 +727,7 @@ current_minor_maps (modeptr, mapptr) break; } cmm_modes[i] = var; - cmm_maps [i] = XCONS (assoc)->cdr; + cmm_maps [i] = Findirect_function (XCONS (assoc)->cdr); i++; } @@ -721,11 +736,17 @@ current_minor_maps (modeptr, mapptr) return i; } -DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 1, 0, +DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 2, 0, "Return the binding for command KEY in current keymaps.\n\ -KEY is a string, a sequence of keystrokes.\n\ -The binding is probably a symbol with a function definition.") - (key) +KEY is a string or vector, a sequence of keystrokes.\n\ +The binding is probably a symbol with a function definition.\n\ +\n\ +Normally, `key-binding' 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\ +third optional argument ACCEPT-DEFAULT is non-nil, `key-binding' will\n\ +recognize the default bindings, just as `read-key-sequence' does.") + (key, accept_default) Lisp_Object key; { Lisp_Object *maps, value; @@ -735,52 +756,58 @@ The binding is probably a symbol with a function definition.") for (i = 0; i < nmaps; i++) if (! NILP (maps[i])) { - value = Flookup_key (maps[i], key); + value = Flookup_key (maps[i], key, accept_default); if (! NILP (value) && XTYPE (value) != Lisp_Int) return value; } if (! NILP (current_buffer->keymap)) { - value = Flookup_key (current_buffer->keymap, key); + value = Flookup_key (current_buffer->keymap, key, accept_default); if (! NILP (value) && XTYPE (value) != Lisp_Int) return value; } - value = Flookup_key (current_global_map, key); + value = Flookup_key (current_global_map, key, accept_default); if (! NILP (value) && XTYPE (value) != Lisp_Int) return value; return Qnil; } -DEFUN ("local-key-binding", Flocal_key_binding, Slocal_key_binding, 1, 1, 0, +DEFUN ("local-key-binding", Flocal_key_binding, Slocal_key_binding, 1, 2, 0, "Return the binding for command KEYS in current local keymap only.\n\ KEYS is a string, a sequence of keystrokes.\n\ -The binding is probably a symbol with a function definition.") - (keys) - Lisp_Object keys; +The binding is probably a symbol with a function definition.\n\ +\n\ +If optional argument ACCEPT-DEFAULT is non-nil, recognize default\n\ +bindings; see the description of `lookup-key' for more details about this.") + (keys, accept_default) + Lisp_Object keys, accept_default; { register Lisp_Object map; map = current_buffer->keymap; if (NILP (map)) return Qnil; - return Flookup_key (map, keys); + return Flookup_key (map, keys, accept_default); } -DEFUN ("global-key-binding", Fglobal_key_binding, Sglobal_key_binding, 1, 1, 0, +DEFUN ("global-key-binding", Fglobal_key_binding, Sglobal_key_binding, 1, 2, 0, "Return the binding for command KEYS in current global keymap only.\n\ KEYS is a string, a sequence of keystrokes.\n\ The binding is probably a symbol with a function definition.\n\ This function's return values are the same as those of lookup-key\n\ -(which see).") - (keys) - Lisp_Object keys; +(which see).\n\ +\n\ +If optional argument ACCEPT-DEFAULT is non-nil, recognize default\n\ +bindings; see the description of `lookup-key' for more details about this.") + (keys, accept_default) + Lisp_Object keys, accept_default; { - return Flookup_key (current_global_map, keys); + return Flookup_key (current_global_map, keys, accept_default); } -DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 1, 0, +DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 2, 0, "Find the visible minor mode bindings of KEY.\n\ Return an alist of pairs (MODENAME . BINDING), where MODENAME is the\n\ the symbol which names the minor mode binding KEY, and BINDING is\n\ @@ -788,8 +815,12 @@ KEY's definition in that mode. In particular, if KEY has no\n\ minor-mode bindings, return nil. If the first binding is a\n\ non-prefix, all subsequent bindings will be omitted, since they would\n\ be ignored. Similarly, the list doesn't include non-prefix bindings\n\ -that come after prefix bindings.") - (key) +that come after prefix bindings.\n\ +\n\ +If optional argument ACCEPT-DEFAULT is non-nil, recognize default\n\ +bindings; see the description of `lookup-key' for more details about this.") + (key, accept_default) + Lisp_Object key, accept_default; { Lisp_Object *modes, *maps; int nmaps; @@ -800,7 +831,7 @@ that come after prefix bindings.") for (i = j = 0; i < nmaps; i++) if (! NILP (maps[i]) - && ! NILP (binding = Flookup_key (maps[i], key)) + && ! NILP (binding = Flookup_key (maps[i], key, accept_default)) && XTYPE (binding) != Lisp_Int) { if (! NILP (get_keymap (binding))) @@ -879,7 +910,7 @@ KEY is a string representing a sequence of keystrokes.") } DEFUN ("define-prefix-command", Fdefine_prefix_command, Sdefine_prefix_command, 1, 2, 0, - "Define COMMAND as a prefix command.\n\ + "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\ @@ -958,7 +989,9 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).") { Lisp_Object maps, tail; - maps = Fcons (Fcons (build_string (""), get_keymap (startmap)), Qnil); + maps = Fcons (Fcons (Fmake_vector (make_number (0), Qnil), + get_keymap (startmap)), + Qnil); /* For each map in the list maps, look at any other maps it points to, @@ -988,7 +1021,7 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).") register int i; /* Vector keymap. Scan all the elements. */ - for (i = 0; i < DENSE_TABLE_SIZE; i++) + for (i = 0; i < XVECTOR (elt)->size; i++) { register Lisp_Object tem; register Lisp_Object cmd; @@ -1010,14 +1043,16 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).") keymap table. */ if (is_metized) { + int meta_bit = meta_modifier; tem = Fcopy_sequence (thisseq); - Faset (tem, last, make_number (i | 0200)); + + Faset (tem, last, make_number (i | meta_bit)); /* 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); + XCONS (tail)->cdr + = Fcons (Fcons (tem, cmd), XCONS (tail)->cdr); } else { @@ -1051,7 +1086,8 @@ so that the KEYS increase in length. The first element is (\"\" . KEYMAP).") if (is_metized && XTYPE (elt) == Lisp_Int) { tem = Fcopy_sequence (thisseq); - Faset (tem, last, make_number (XINT (elt) | 0200)); + Faset (tem, last, + make_number (XINT (elt) | meta_modifier)); /* This new sequence is the same length as thisseq, so stick it in the list right @@ -1081,6 +1117,22 @@ spaces are put between sequence elements, etc.") (keys) Lisp_Object keys; { + if (XTYPE (keys) == Lisp_String) + { + Lisp_Object vector; + int i; + vector = Fmake_vector (Flength (keys), Qnil); + for (i = 0; i < XSTRING (keys)->size; i++) + { + if (XSTRING (keys)->data[i] & 0x80) + XFASTINT (XVECTOR (vector)->contents[i]) + = meta_modifier | (XSTRING (keys)->data[i] & ~0x80); + else + XFASTINT (XVECTOR (vector)->contents[i]) + = XSTRING (keys)->data[i]; + } + keys = vector; + } return Fmapconcat (Qsingle_key_description, keys, build_string (" ")); } @@ -1089,11 +1141,44 @@ push_key_description (c, p) register unsigned int c; register char *p; { - if (c >= 0200) + /* Clear all the meaningless bits above the meta bit. */ + c &= meta_modifier | ~ - meta_modifier; + + if (c & alt_modifier) + { + *p++ = 'A'; + *p++ = '-'; + c -= alt_modifier; + } + if (c & ctrl_modifier) + { + *p++ = 'C'; + *p++ = '-'; + c -= ctrl_modifier; + } + if (c & hyper_modifier) + { + *p++ = 'H'; + *p++ = '-'; + c -= hyper_modifier; + } + if (c & meta_modifier) { *p++ = 'M'; *p++ = '-'; - c -= 0200; + c -= meta_modifier; + } + if (c & shift_modifier) + { + *p++ = 'S'; + *p++ = '-'; + c -= shift_modifier; + } + if (c & super_modifier) + { + *p++ = 's'; + *p++ = '-'; + c -= super_modifier; } if (c < 040) { @@ -1103,7 +1188,7 @@ push_key_description (c, p) *p++ = 'S'; *p++ = 'C'; } - else if (c == Ctl('I')) + else if (c == '\t') { *p++ = 'T'; *p++ = 'A'; @@ -1143,8 +1228,18 @@ push_key_description (c, p) *p++ = 'P'; *p++ = 'C'; } - else + else if (c < 256) *p++ = c; + 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'; + } return p; } @@ -1155,16 +1250,14 @@ Control characters turn into C-whatever, etc.") (key) Lisp_Object key; { - register unsigned char c; - char tem[6]; + char tem[20]; key = EVENT_HEAD (key); switch (XTYPE (key)) { case Lisp_Int: /* Normal character */ - c = XINT (key) & 0377; - *push_key_description (c, tem) = 0; + *push_key_description (XUINT (key), tem) = 0; return build_string (tem); case Lisp_Symbol: /* Function key or event-symbol */ @@ -1215,6 +1308,28 @@ Control characters turn into \"^char\", etc.") return build_string (tem); } + +/* Return non-zero if SEQ contains only ASCII characters, perhaps with + a meta bit. */ +static int +ascii_sequence_p (seq) + Lisp_Object seq; +{ + Lisp_Object i; + int len = XINT (Flength (seq)); + + for (XFASTINT (i) = 0; XFASTINT (i) < len; XFASTINT (i)++) + { + Lisp_Object elt = Faref (seq, i); + + if (XTYPE (elt) != Lisp_Int + || (XUINT (elt) & ~CHAR_META) >= 0x80) + return 0; + } + + return 1; +} + /* where-is - finding a command in a set of keymaps. */ @@ -1223,9 +1338,12 @@ DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0, If KEYMAP is nil, search only KEYMAP1.\n\ If KEYMAP1 is nil, use the current global map.\n\ \n\ -If optional 4th arg FIRSTONLY is non-nil,\n\ -return a string representing the first key sequence found,\n\ -rather than a list of all possible key sequences.\n\ +If optional 4th arg FIRSTONLY is non-nil, return a string representing\n\ +the first key sequence found, rather than a list of all possible key\n\ +sequences. If FIRSTONLY is t, avoid key sequences which use non-ASCII\n\ +keys and therefore may not be usable on ASCII terminals. If FIRSTONLY\n\ +is the symbol `non-ascii', return the first binding found, no matter\n\ +what its components.\n\ \n\ If optional 5th arg NOINDIRECT is non-nil, don't follow indirections\n\ to other keymaps or slots. This makes it possible to search for an\n\ @@ -1296,7 +1414,7 @@ indirect definition itself.") /* If we've just finished scanning a vector, advance map to the next element, and reset i in anticipation of the next vector we may find. */ - if (i >= DENSE_TABLE_SIZE) + if (i >= XVECTOR (elt)->size) { map = XCONS (map)->cdr; i = 0; @@ -1340,7 +1458,7 @@ indirect definition itself.") if (XTYPE (key) == Lisp_Int && last_is_meta) { sequence = Fcopy_sequence (this); - Faset (sequence, last, make_number (XINT (key) | 0200)); + Faset (sequence, last, make_number (XINT (key) | meta_modifier)); } else sequence = append_key (this, key); @@ -1356,7 +1474,7 @@ indirect definition itself.") means undefined. */ if (!NILP (local_keymap)) { - binding = Flookup_key (local_keymap, sequence); + binding = Flookup_key (local_keymap, sequence, Qnil); if (!NILP (binding) && XTYPE (binding) != Lisp_Int) { if (XTYPE (definition) == Lisp_Cons) @@ -1373,13 +1491,28 @@ indirect definition itself.") } /* It is a true unshadowed match. Record it. */ + found = Fcons (sequence, found); - if (!NILP (firstonly)) + /* If firstonly is Qnon_ascii, then we can return the first + binding we find. If firstonly is not Qnon_ascii but not + nil, then we should return the first ascii-only binding + we find. */ + if (EQ (firstonly, Qnon_ascii)) + return sequence; + else if (! NILP (firstonly) && ascii_sequence_p (sequence)) return sequence; - found = Fcons (sequence, found); } } - return Fnreverse (found); + + found = Fnreverse (found); + + /* firstonly may have been t, but we may have gone all the way through + the keymaps without finding an all-ASCII key sequence. So just + return the best we could find. */ + if (! NILP (firstonly)) + return Fcar (found); + + return found; } /* Return a string listing the keys and buttons that run DEFINITION. */ @@ -1567,7 +1700,7 @@ describe_map_tree (startmap, partial, shadow) what we should use. */ else { - sh = Flookup_key (shadow, Fcar (elt)); + sh = Flookup_key (shadow, Fcar (elt), Qt); if (XTYPE (sh) == Lisp_Int) sh = Qnil; } @@ -1621,8 +1754,12 @@ describe_map (map, keys, partial, shadow) register Lisp_Object keysdesc; if (!NILP (keys) && XFASTINT (Flength (keys)) > 0) - keysdesc = concat2 (Fkey_description (keys), - build_string (" ")); + { + Lisp_Object tem; + /* Call Fkey_description first, to avoid GC bug for the other string. */ + tem = Fkey_description (keys); + keysdesc = concat2 (tem, build_string (" ")); + } else keysdesc = Qnil; @@ -1685,7 +1822,7 @@ describe_map_2 (keymap, elt_prefix, elt_describer, partial, shadow) Lisp_Object tem; XVECTOR (kludge)->contents[0] = tem1; - tem = Flookup_key (shadow, kludge); + tem = Flookup_key (shadow, kludge, Qt); if (!NILP (tem)) continue; } @@ -1726,7 +1863,7 @@ This is text showing the elements of vector matched against indices.") Lisp_Object vector; { CHECK_VECTOR (vector, 0); - describe_vector (vector, Qnil, describe_vector_princ, 0, Qnil, Qnil); + describe_vector (vector, Qnil, describe_vector_princ, 0, Qnil); } describe_vector (vector, elt_prefix, elt_describer, partial, shadow) @@ -1756,7 +1893,7 @@ describe_vector (vector, elt_prefix, elt_describer, partial, shadow) if (partial) suppress = intern ("suppress-keymap"); - for (i = 0; i < DENSE_TABLE_SIZE; i++) + for (i = 0; i < XVECTOR (vector)->size; i++) { QUIT; tem1 = get_keyelt (XVECTOR (vector)->contents[i]); @@ -1778,7 +1915,7 @@ describe_vector (vector, elt_prefix, elt_describer, partial, shadow) Lisp_Object tem; XVECTOR (kludge)->contents[0] = make_number (i); - tem = Flookup_key (shadow, kludge); + tem = Flookup_key (shadow, kludge, Qt); if (!NILP (tem)) continue; } @@ -1801,7 +1938,7 @@ describe_vector (vector, elt_prefix, elt_describer, partial, shadow) insert1 (this); /* Find all consecutive characters that have the same definition. */ - while (i + 1 < DENSE_TABLE_SIZE + while (i + 1 < XVECTOR (vector)->size && (tem2 = get_keyelt (XVECTOR (vector)->contents[i+1]), EQ (tem2, tem1))) i++; @@ -1939,6 +2076,9 @@ key, typing `ESC O P x' would return [pf1 x]."); Qkeymapp = intern ("keymapp"); staticpro (&Qkeymapp); + Qnon_ascii = intern ("non-ascii"); + staticpro (&Qnon_ascii); + defsubr (&Skeymapp); defsubr (&Smake_keymap); defsubr (&Smake_sparse_keymap);