/* Manipulation of keymaps
- Copyright (C) 1985-1988, 1993-1995, 1998-2011 Free Software Foundation, Inc.
+ Copyright (C) 1985-1988, 1993-1995, 1998-2012 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <setjmp.h>
#include "lisp.h"
#include "commands.h"
-#include "buffer.h"
#include "character.h"
+#include "buffer.h"
#include "charset.h"
#include "keyboard.h"
#include "frame.h"
/* Which keymaps are reverse-stored in the cache. */
static Lisp_Object where_is_cache_keymaps;
-static Lisp_Object Flookup_key (Lisp_Object, Lisp_Object, Lisp_Object);
static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object);
static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object);
return Fcons (Qkeymap, Qnil);
}
-DEFUN ("make-composed-keymap", Fmake_composed_keymap, Smake_composed_keymap,
- 0, MANY, 0,
- doc: /* Construct and return a new keymap composed of KEYMAPS.
-When looking up a key in the returned map, the key is looked in each
-keymap in turn until a binding is found.
-usage: (make-composed-keymap &rest KEYMAPS) */)
- (ptrdiff_t nargs, Lisp_Object *args)
-{
- return Fcons (Qkeymap, Flist (nargs, args));
-}
-
/* This function is used for installing the standard key bindings
at initialization time.
return def;
}
-static Lisp_Object Fcopy_keymap (Lisp_Object);
-
static Lisp_Object
copy_keymap_item (Lisp_Object elt)
{
}
else
{
- /* It may be an old fomat menu item.
+ /* It may be an old format menu item.
Skip the optional menu string. */
if (STRINGP (XCAR (tem)))
{
binding KEY to DEF is added at the front of KEYMAP. */)
(Lisp_Object keymap, Lisp_Object key, Lisp_Object def)
{
- register int idx;
+ register ptrdiff_t idx;
register Lisp_Object c;
register Lisp_Object cmd;
int metized = 0;
int meta_bit;
- int length;
+ ptrdiff_t length;
struct gcpro gcpro1, gcpro2, gcpro3;
GCPRO3 (keymap, key, def);
if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0)))
{ /* DEF is apparently an XEmacs-style keyboard macro. */
Lisp_Object tmp = Fmake_vector (make_number (ASIZE (def)), Qnil);
- int i = ASIZE (def);
+ ptrdiff_t i = ASIZE (def);
while (--i >= 0)
{
Lisp_Object defi = AREF (def, i);
keymap = get_keymap (cmd, 0, 1);
if (!CONSP (keymap))
- /* We must use Fkey_description rather than just passing key to
- error; key might be a vector, not a string. */
- error ("Key sequence %s starts with non-prefix key %s",
- SDATA (Fkey_description (key, Qnil)),
- SDATA (Fkey_description (Fsubstring (key, make_number (0),
- make_number (idx)),
- Qnil)));
+ {
+ const char *trailing_esc = ((EQ (c, meta_prefix_char) && metized)
+ ? (idx == 0 ? "ESC" : " ESC")
+ : "");
+
+ /* We must use Fkey_description rather than just passing key to
+ error; key might be a vector, not a string. */
+ error ("Key sequence %s starts with non-prefix key %s%s",
+ SDATA (Fkey_description (key, Qnil)),
+ SDATA (Fkey_description (Fsubstring (key, make_number (0),
+ make_number (idx)),
+ Qnil)),
+ trailing_esc);
+ }
}
}
recognize the default bindings, just as `read-key-sequence' does. */)
(Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
{
- register int idx;
+ register ptrdiff_t idx;
register Lisp_Object cmd;
register Lisp_Object c;
- int length;
+ ptrdiff_t length;
int t_ok = !NILP (accept_default);
struct gcpro gcpro1, gcpro2;
some systems, static gets macro-defined to be the empty string.
Ickypoo. */
static Lisp_Object *cmm_modes = NULL, *cmm_maps = NULL;
-static int cmm_size = 0;
+static ptrdiff_t cmm_size = 0;
/* Store a pointer to an array of the currently active minor modes in
*modeptr, a pointer to an array of the keymaps of the currently
loop. Instead, we'll use realloc/malloc and silently truncate the
list, let the key sequence be read, and hope some other piece of
code signals the error. */
-int
+ptrdiff_t
current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr)
{
- int i = 0;
+ ptrdiff_t i = 0;
int list_number = 0;
Lisp_Object alist, assoc, var, val;
Lisp_Object emulation_alists;
if (i >= cmm_size)
{
- int newsize, allocsize;
+ ptrdiff_t newsize, allocsize;
Lisp_Object *newmodes, *newmaps;
+ /* Check for size calculation overflow. Other code
+ (e.g., read_key_sequence) adds 3 to the count
+ later, so subtract 3 from the limit here. */
+ if (min (PTRDIFF_MAX, SIZE_MAX) / (2 * sizeof *newmodes) - 3
+ < cmm_size)
+ break;
+
newsize = cmm_size == 0 ? 30 : cmm_size * 2;
allocsize = newsize * sizeof *newmodes;
/* Use malloc here. See the comment above this function.
Avoid realloc here; it causes spurious traps on GNU/Linux [KFS] */
BLOCK_INPUT;
- newmodes = (Lisp_Object *) malloc (allocsize);
+ newmodes = malloc (allocsize);
if (newmodes)
{
if (cmm_modes)
cmm_modes = newmodes;
}
- newmaps = (Lisp_Object *) malloc (allocsize);
+ newmaps = malloc (allocsize);
if (newmaps)
{
if (cmm_maps)
return i;
}
+/* Return the offset of POSITION, a click position, in the style of
+ the respective argument of Fkey_binding. */
+static ptrdiff_t
+click_position (Lisp_Object position)
+{
+ EMACS_INT pos = (INTEGERP (position) ? XINT (position)
+ : MARKERP (position) ? marker_position (position)
+ : PT);
+ if (! (BEGV <= pos && pos <= ZV))
+ args_out_of_range (Fcurrent_buffer (), position);
+ return pos;
+}
+
DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps,
0, 2, 0,
doc: /* Return a list of the currently active keymaps.
like in the respective argument of `key-binding'. */)
(Lisp_Object olp, Lisp_Object position)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
Lisp_Object keymaps = Fcons (current_global_map, Qnil);
{
Lisp_Object *maps;
int nmaps, i;
- EMACS_INT pt
- = INTEGERP (position) ? XINT (position)
- : MARKERP (position) ? marker_position (position)
- : PT;
+ ptrdiff_t pt = click_position (position);
/* This usually returns the buffer's local map,
but that can be overridden by a `local-map' property. */
Lisp_Object local_map = get_local_map (pt, current_buffer, Qlocal_map);
while (!NILP (tem = Frassq (cmd, maps)))
{
Lisp_Object prefix = XCAR (tem);
- int lim = XINT (Flength (XCAR (tem)));
+ ptrdiff_t lim = XINT (Flength (XCAR (tem)));
if (lim <= XINT (Flength (thisseq)))
{ /* This keymap was already seen with a smaller prefix. */
- int i = 0;
+ ptrdiff_t i = 0;
while (i < lim && EQ (Faref (prefix, make_number (i)),
Faref (thisseq, make_number (i))))
i++;
(Lisp_Object keymap, Lisp_Object prefix)
{
Lisp_Object maps, tail;
- int prefixlen = XINT (Flength (prefix));
+ EMACS_INT prefixlen = XFASTINT (Flength (prefix));
/* no need for gcpro because we don't autoload any keymaps. */
return Qnil;
}
else
- maps = Fcons (Fcons (Fmake_vector (make_number (0), Qnil),
- get_keymap (keymap, 1, 0)),
- Qnil);
+ maps = Fcons (Fcons (zero_vector, get_keymap (keymap, 1, 0)), Qnil);
/* For each map in the list maps,
look at any other maps it points to,
DEFUN ("key-description", Fkey_description, Skey_description, 1, 2, 0,
doc: /* Return a pretty description of key-sequence KEYS.
Optional arg PREFIX is the sequence of keys leading up to KEYS.
-Control characters turn into "C-foo" sequences, meta into "M-foo",
-spaces are put between sequence elements, etc. */)
+For example, [?\C-x ?l] is converted into the string \"C-x l\".
+
+The `kbd' macro is an approximate inverse of this. */)
(Lisp_Object keys, Lisp_Object prefix)
{
- int len = 0;
- int i, i_byte;
+ ptrdiff_t len = 0;
+ EMACS_INT i;
+ ptrdiff_t i_byte;
Lisp_Object *args;
- int size = XINT (Flength (keys));
+ EMACS_INT size = XINT (Flength (keys));
Lisp_Object list;
Lisp_Object sep = build_string (" ");
Lisp_Object key;
+ Lisp_Object result;
int add_meta = 0;
+ USE_SAFE_ALLOCA;
if (!NILP (prefix))
size += XINT (Flength (prefix));
/* This has one extra element at the end that we don't pass to Fconcat. */
- args = (Lisp_Object *) alloca (size * 4 * sizeof (Lisp_Object));
+ if (min (PTRDIFF_MAX, SIZE_MAX) / sizeof (Lisp_Object) / 4 < size)
+ memory_full (SIZE_MAX);
+ SAFE_ALLOCA_LISP (args, size * 4);
/* In effect, this computes
(mapconcat 'single-key-description keys " ")
if (add_meta)
{
args[len] = Fsingle_key_description (meta_prefix_char, Qnil);
- len += 2;
+ result = Fconcat (len + 1, args);
}
else if (len == 0)
- return empty_unibyte_string;
- return Fconcat (len - 1, args);
+ result = empty_unibyte_string;
+ else
+ result = Fconcat (len - 1, args);
+ SAFE_FREE ();
+ return result;
}
if (STRINGP (list))
char *
-push_key_description (register unsigned int c, register char *p, int force_multibyte)
+push_key_description (EMACS_INT ch, char *p, int force_multibyte)
{
- unsigned c2;
+ int c, c2;
/* Clear all the meaningless bits above the meta bit. */
- c &= meta_modifier | ~ - meta_modifier;
+ c = ch & (meta_modifier | ~ - meta_modifier);
c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier
| meta_modifier | shift_modifier | super_modifier);
if (CONSP (key) && lucid_event_type_list_p (key))
key = Fevent_convert_list (key);
+ if (CONSP (key) && INTEGERP (XCAR (key)) && INTEGERP (XCDR (key)))
+ /* An interval from a map-char-table. */
+ return concat3 (Fsingle_key_description (XCAR (key), no_angles),
+ build_string (".."),
+ Fsingle_key_description (XCDR (key), no_angles));
+
key = EVENT_HEAD (key);
- if (INTEGERP (key)) /* Normal character */
+ if (INTEGERP (key)) /* Normal character. */
{
- char tem[KEY_DESCRIPTION_SIZE];
+ char tem[KEY_DESCRIPTION_SIZE], *p;
- *push_key_description (XINT (key), tem, 1) = 0;
- return build_string (tem);
+ p = push_key_description (XINT (key), tem, 1);
+ *p = 0;
+ return make_specified_string (tem, -1, p - tem, 1);
}
- else if (SYMBOLP (key)) /* Function key or event-symbol */
+ else if (SYMBOLP (key)) /* Function key or event-symbol. */
{
if (NILP (no_angles))
{
- char *buffer
- = (char *) alloca (SBYTES (SYMBOL_NAME (key)) + 5);
- sprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key)));
- return build_string (buffer);
+ char *buffer;
+ Lisp_Object result;
+ USE_SAFE_ALLOCA;
+ SAFE_ALLOCA (buffer, char *,
+ sizeof "<>" + SBYTES (SYMBOL_NAME (key)));
+ esprintf (buffer, "<%s>", SDATA (SYMBOL_NAME (key)));
+ result = build_string (buffer);
+ SAFE_FREE ();
+ return result;
}
else
return Fsymbol_name (key);
char str[6];
int c;
- CHECK_NUMBER (character);
+ CHECK_CHARACTER (character);
c = XINT (character);
if (!ASCII_CHAR_P (c))
static int
preferred_sequence_p (Lisp_Object seq)
{
- int i;
- int len = XINT (Flength (seq));
+ EMACS_INT i;
+ EMACS_INT len = XFASTINT (Flength (seq));
int result = 1;
for (i = 0; i < len; i++)
DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0,
doc: /* Return list of keys that invoke DEFINITION.
If KEYMAP is a keymap, search only KEYMAP and the global keymap.
-If KEYMAP is nil, search all the currently active keymaps.
+If KEYMAP is nil, search all the currently active keymaps, except
+ for `overriding-local-map' (which is ignored).
If KEYMAP is a list of keymaps, search only those keymaps.
If optional 3rd arg FIRSTONLY is non-nil, return the first key sequence found,
to other keymaps or slots. This makes it possible to search for an
indirect definition itself.
-If optional 5th arg NO-REMAP is non-nil, don't search for key sequences
-that invoke a command which is remapped to DEFINITION, but include the
-remapped command in the returned list. */)
+The optional 5th arg NO-REMAP alters how command remapping is handled:
+
+- If another command OTHER-COMMAND is remapped to DEFINITION, normally
+ search for the bindings of OTHER-COMMAND and include them in the
+ returned list. But if NO-REMAP is non-nil, include the vector
+ [remap OTHER-COMMAND] in the returned list instead, without
+ searching for those other bindings.
+
+- If DEFINITION is remapped to OTHER-COMMAND, normally return the
+ bindings for OTHER-COMMAND. But if NO-REMAP is non-nil, return the
+ bindings for DEFINITION instead, ignoring its remapping. */)
(Lisp_Object definition, Lisp_Object keymap, Lisp_Object firstonly, Lisp_Object noindirect, Lisp_Object no_remap)
{
/* The keymaps in which to search. */
/* We have a list of advertised bindings. */
while (CONSP (tem))
if (EQ (shadow_lookup (keymaps, XCAR (tem), Qnil, 0), definition))
- return XCAR (tem);
+ RETURN_UNGCPRO (XCAR (tem));
else
tem = XCDR (tem);
if (EQ (shadow_lookup (keymaps, tem, Qnil, 0), definition))
- return tem;
+ RETURN_UNGCPRO (tem);
}
sequences = Freverse (where_is_internal (definition, keymaps,
if (!SYMBOLP (modes[i]))
abort ();
- p = title = (char *) alloca (42 + SCHARS (SYMBOL_NAME (modes[i])));
+ p = title = alloca (42 + SCHARS (SYMBOL_NAME (modes[i])));
*p++ = '\f';
*p++ = '\n';
*p++ = '`';
to look through.
If MENTION_SHADOW is nonzero, then when something is shadowed by SHADOW,
- don't omit it; instead, mention it but say it is shadowed. */
+ don't omit it; instead, mention it but say it is shadowed.
+
+ Any inserted text ends in two newlines (used by `help-make-xrefs'). */
void
describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow,
describe_command (Lisp_Object definition, Lisp_Object args)
{
register Lisp_Object tem1;
- EMACS_INT column = current_column ();
+ ptrdiff_t column = current_column ();
int description_column;
/* If column 16 is no good, go to col 32;
DESCRIBER is the output function used; nil means use `princ'. */)
(Lisp_Object vector, Lisp_Object describer)
{
- int count = SPECPDL_INDEX ();
+ ptrdiff_t count = SPECPDL_INDEX ();
if (NILP (describer))
describer = intern ("princ");
specbind (Qstandard_output, Fcurrent_buffer ());
Ffset (intern_c_string ("Control-X-prefix"), control_x_map);
exclude_keys
- = pure_cons (pure_cons (make_pure_c_string ("DEL"), make_pure_c_string ("\\d")),
- pure_cons (pure_cons (make_pure_c_string ("TAB"), make_pure_c_string ("\\t")),
- pure_cons (pure_cons (make_pure_c_string ("RET"), make_pure_c_string ("\\r")),
- pure_cons (pure_cons (make_pure_c_string ("ESC"), make_pure_c_string ("\\e")),
- pure_cons (pure_cons (make_pure_c_string ("SPC"), make_pure_c_string (" ")),
+ = pure_cons (pure_cons (build_pure_c_string ("DEL"), build_pure_c_string ("\\d")),
+ pure_cons (pure_cons (build_pure_c_string ("TAB"), build_pure_c_string ("\\t")),
+ pure_cons (pure_cons (build_pure_c_string ("RET"), build_pure_c_string ("\\r")),
+ pure_cons (pure_cons (build_pure_c_string ("ESC"), build_pure_c_string ("\\e")),
+ pure_cons (pure_cons (build_pure_c_string ("SPC"), build_pure_c_string (" ")),
Qnil)))));
staticpro (&exclude_keys);
Vemulation_mode_map_alists = Qnil;
DEFVAR_LISP ("where-is-preferred-modifier", Vwhere_is_preferred_modifier,
- doc: /* Preferred modifier to use for `where-is'.
+ doc: /* Preferred modifier key to use for `where-is'.
When a single binding is requested, `where-is' will return one that
-uses this modifier if possible. If nil, or if no such binding exists,
-bindings using keys without modifiers (or only with meta) will be
-preferred. */);
+uses this modifier key if possible. If nil, or if no such binding
+exists, bindings using keys without modifiers (or only with meta) will
+be preferred. */);
Vwhere_is_preferred_modifier = Qnil;
where_is_preferred_modifier = 0;
defsubr (&Sset_keymap_parent);
defsubr (&Smake_keymap);
defsubr (&Smake_sparse_keymap);
- defsubr (&Smake_composed_keymap);
defsubr (&Smap_keymap_internal);
defsubr (&Smap_keymap);
defsubr (&Scopy_keymap);