/* Manipulation of keymaps
Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
1998, 1999, 2000, 2001, 2002, 2003, 2004,
- 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include <stdio.h>
+#include <setjmp.h>
#if HAVE_ALLOCA_H
# include <alloca.h>
#endif
Lisp_Object Vdefine_key_rebound_commands;
Lisp_Object Qkeymapp, Qkeymap, Qnon_ascii, Qmenu_item, Qremap;
+Lisp_Object QCadvertised_binding;
/* Alist of elements like (DEL . "\d"). */
static Lisp_Object exclude_keys;
Lisp_Object string;
{
if (!NILP (string))
- return Fcons (Qkeymap, Fcons (string, Qnil));
+ {
+ if (!NILP (Vpurify_flag))
+ string = Fpurecopy (string);
+ return Fcons (Qkeymap, Fcons (string, Qnil));
+ }
return Fcons (Qkeymap, Qnil);
}
int key;
char *defname;
{
- store_in_keymap (keymap, make_number (key), intern (defname));
+ store_in_keymap (keymap, make_number (key), intern_c_string (defname));
}
void
char *keyname;
char *defname;
{
- store_in_keymap (keymap, intern (keyname), intern (defname));
+ store_in_keymap (keymap, intern_c_string (keyname), intern_c_string (defname));
}
DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
goto autoload_retry;
}
else
- return Qt;
+ return object;
}
}
}
/* If a mouse click position is given, our variables are based on
the buffer clicked on, not the current buffer. So we may have to
switch the buffer here. */
-
+
if (CONSP (position))
{
Lisp_Object window;
-
+
window = POSN_WINDOW (position);
-
+
if (WINDOWP (window)
&& BUFFERP (XWINDOW (window)->buffer)
&& XBUFFER (XWINDOW (window)->buffer) != current_buffer)
would not be a problem here, but it is easier to keep
things the same.
*/
-
+
record_unwind_protect (Fset_buffer, Fcurrent_buffer ());
-
+
set_buffer_internal (XBUFFER (XWINDOW (window)->buffer));
}
}
- keymaps = Fcons (current_global_map, Qnil);
+ keymaps = Fcons (current_global_map, Qnil);
if (!NILP (olp))
{
/* Get the buffer local maps, possibly overriden by text or
overlay properties */
- local_map = get_local_map (pt, current_buffer, Qlocal_map);
- keymap = get_local_map (pt, current_buffer, Qkeymap);
+ local_map = get_local_map (pt, current_buffer, Qlocal_map);
+ keymap = get_local_map (pt, current_buffer, Qkeymap);
if (CONSP (position))
{
/* For a mouse click, get the local text-property keymap
of the place clicked on, rather than point. */
-
+
if (POSN_INBUFFER_P (position))
{
Lisp_Object pos;
{
local_map = get_local_map (XINT (pos),
current_buffer, Qlocal_map);
-
+
keymap = get_local_map (XINT (pos),
current_buffer, Qkeymap);
}
string displayed via the `display' property,
consider `local-map' and `keymap' properties of
that string. */
-
+
if (string = POSN_STRING (position),
(CONSP (string) && STRINGP (XCAR (string))))
{
Lisp_Object pos, map;
-
+
pos = XCDR (string);
string = XCAR (string);
if (INTEGERP (pos)
keymap = map;
}
}
-
+
}
if (!NILP (local_map))
Lisp_Object args, void *data));
/* 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. */
+ Returns the first non-nil binding found in any of those maps.
+ If REMAP is true, pass the result of the lookup through command
+ remapping before returning it. */
static Lisp_Object
-shadow_lookup (shadow, key, flag)
- Lisp_Object shadow, key, flag;
+shadow_lookup (Lisp_Object shadow, Lisp_Object key, Lisp_Object flag,
+ int remap)
{
Lisp_Object tail, value;
return Qnil;
}
else if (!NILP (value))
- return value;
+ {
+ Lisp_Object remapping;
+ if (remap && SYMBOLP (value)
+ && (remapping = Fcommand_remapping (value, Qnil, shadow),
+ !NILP (remapping)))
+ return remapping;
+ else
+ return value;
+ }
}
return Qnil;
}
}
if (nomenus && !noindirect)
- /* Remember for which keymaps this cache was built.
- We do it here (late) because we want to keep where_is_cache_keymaps
- set to t while the cache isn't fully filled. */
- where_is_cache_keymaps = keymaps;
-
- return data.sequences;
+ { /* Remember for which keymaps this cache was built.
+ We do it here (late) because we want to keep where_is_cache_keymaps
+ set to t while the cache isn't fully filled. */
+ where_is_cache_keymaps = keymaps;
+ /* During cache-filling, data.sequences is not filled by
+ where_is_internal_1. */
+ return Fgethash (definition, where_is_cache, Qnil);
+ }
+ else
+ return data.sequences;
}
static Lisp_Object Vwhere_is_preferred_modifier;
/* The keymaps in which to search. */
Lisp_Object keymaps;
/* Potentially relevant bindings in "shortest to longest" order. */
- Lisp_Object sequences = Qnil,
+ Lisp_Object sequences = Qnil;
/* Actually relevant bindings. */
Lisp_Object found = Qnil;
/* 1 means ignore all menu bindings entirely. */
because remapping is not done recursively by Fcommand_remapping: you
can't remap and remapped command. */
int remapped = 0;
+ Lisp_Object tem;
/* Refresh the C version of the modifier preference. */
where_is_preferred_modifier
&& !NILP (Fcommand_remapping (definition, Qnil, keymaps)))
RETURN_UNGCPRO (Qnil);
+ if (SYMBOLP (definition)
+ && !NILP (firstonly)
+ && !NILP (tem = Fget (definition, QCadvertised_binding)))
+ {
+ /* We have a list of advertized bindings. */
+ while (CONSP (tem))
+ if (EQ (shadow_lookup (keymaps, XCAR (tem), Qnil, 0), definition))
+ return XCAR (tem);
+ else
+ tem = XCDR (tem);
+ if (EQ (shadow_lookup (keymaps, tem, Qnil, 0), definition))
+ return tem;
+ }
+
sequences = Freverse (where_is_internal (definition, keymaps,
!NILP (noindirect), nomenus));
- while (CONSP (sequences))
+ while (CONSP (sequences)
+ /* If we're at the end of the `sequences' list and we haven't
+ considered remapped sequences yet, copy them over and
+ process them. */
+ || (!remapped && (sequences = remapped_sequences,
+ remapped = 1),
+ CONSP (sequences)))
{
Lisp_Object sequence, function;
-
+
sequence = XCAR (sequences);
sequences = XCDR (sequences);
- if (NILP (sequences) && !remapped)
- {
- sequences = remapped_sequences;
- remapped = 1;
- }
-
/* Verify that this key binding is not shadowed by another
binding for the same key, before we say it exists.
Either nil or number as value from Flookup_key
means undefined. */
- if (!EQ (shadow_lookup (keymaps, sequence, Qnil), definition))
+ if (NILP (Fequal (shadow_lookup (keymaps, sequence, Qnil, remapped),
+ definition)))
continue;
/* If the current sequence is a command remapping with
{
Lisp_Object seqs = where_is_internal (function, keymaps,
!NILP (noindirect), nomenus);
- Lisp_Object args[2];
- args[0] = Freverse (seqs);
- args[1] = remapped_sequences;
- remapped_sequences = Fnconc (2, args);
+ remapped_sequences = nconc2 (Freverse (seqs), remapped_sequences);
continue;
}
Faset (sequence, make_number (ASIZE (sequence) - 1),
build_string ("(any string)"));
}
-
+
/* It is a true unshadowed match. Record it, unless it's already
been seen (as could happen when inheriting keymaps). */
if (NILP (Fmember (sequence, found)))
found = Fcons (sequence, found);
-
+
/* 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
Lisp_Object sequence;
/* Search through indirections unless that's not wanted. */
- if (noindirect)
+ if (!noindirect)
binding = get_keyelt (binding, 0);
/* End this iteration if this element does not match
ASET (kludge, 0, event);
if (!NILP (shadow))
{
- tem = shadow_lookup (shadow, kludge, Qt);
+ tem = shadow_lookup (shadow, kludge, Qt, 0);
if (!NILP (tem))
{
/* If both bindings are keymaps, this key is a prefix key,
{
Lisp_Object tem;
- tem = shadow_lookup (shadow, kludge, Qt);
+ tem = shadow_lookup (shadow, kludge, Qt, 0);
if (!NILP (tem))
{
void
syms_of_keymap ()
{
- Qkeymap = intern ("keymap");
+ Qkeymap = intern_c_string ("keymap");
staticpro (&Qkeymap);
staticpro (&apropos_predicate);
staticpro (&apropos_accumulate);
apropos_predicate = Qnil;
apropos_accumulate = Qnil;
- Qkeymap_canonicalize = intern ("keymap-canonicalize");
+ Qkeymap_canonicalize = intern_c_string ("keymap-canonicalize");
staticpro (&Qkeymap_canonicalize);
/* Now we are ready to set up this property, so we can
pointed to by a C variable */
global_map = Fmake_keymap (Qnil);
- Fset (intern ("global-map"), global_map);
+ Fset (intern_c_string ("global-map"), global_map);
current_global_map = global_map;
staticpro (&global_map);
staticpro (¤t_global_map);
meta_map = Fmake_keymap (Qnil);
- Fset (intern ("esc-map"), meta_map);
- Ffset (intern ("ESC-prefix"), meta_map);
+ Fset (intern_c_string ("esc-map"), meta_map);
+ Ffset (intern_c_string ("ESC-prefix"), meta_map);
control_x_map = Fmake_keymap (Qnil);
- Fset (intern ("ctl-x-map"), control_x_map);
- Ffset (intern ("Control-X-prefix"), control_x_map);
+ Fset (intern_c_string ("ctl-x-map"), control_x_map);
+ Ffset (intern_c_string ("Control-X-prefix"), control_x_map);
exclude_keys
- = Fcons (Fcons (build_string ("DEL"), build_string ("\\d")),
- Fcons (Fcons (build_string ("TAB"), build_string ("\\t")),
- Fcons (Fcons (build_string ("RET"), build_string ("\\r")),
- Fcons (Fcons (build_string ("ESC"), build_string ("\\e")),
- Fcons (Fcons (build_string ("SPC"), build_string (" ")),
+ = 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 (" ")),
Qnil)))));
staticpro (&exclude_keys);
where_is_preferred_modifier = 0;
staticpro (&Vmouse_events);
- Vmouse_events = Fcons (intern ("menu-bar"),
- Fcons (intern ("tool-bar"),
- Fcons (intern ("header-line"),
- Fcons (intern ("mode-line"),
- Fcons (intern ("mouse-1"),
- Fcons (intern ("mouse-2"),
- Fcons (intern ("mouse-3"),
- Fcons (intern ("mouse-4"),
- Fcons (intern ("mouse-5"),
- Qnil)))))))));
-
-
- Qsingle_key_description = intern ("single-key-description");
+ Vmouse_events = pure_cons (intern_c_string ("menu-bar"),
+ pure_cons (intern_c_string ("tool-bar"),
+ pure_cons (intern_c_string ("header-line"),
+ pure_cons (intern_c_string ("mode-line"),
+ pure_cons (intern_c_string ("mouse-1"),
+ pure_cons (intern_c_string ("mouse-2"),
+ pure_cons (intern_c_string ("mouse-3"),
+ pure_cons (intern_c_string ("mouse-4"),
+ pure_cons (intern_c_string ("mouse-5"),
+ Qnil)))))))));
+
+
+ Qsingle_key_description = intern_c_string ("single-key-description");
staticpro (&Qsingle_key_description);
- Qkey_description = intern ("key-description");
+ Qkey_description = intern_c_string ("key-description");
staticpro (&Qkey_description);
- Qkeymapp = intern ("keymapp");
+ Qkeymapp = intern_c_string ("keymapp");
staticpro (&Qkeymapp);
- Qnon_ascii = intern ("non-ascii");
+ Qnon_ascii = intern_c_string ("non-ascii");
staticpro (&Qnon_ascii);
- Qmenu_item = intern ("menu-item");
+ Qmenu_item = intern_c_string ("menu-item");
staticpro (&Qmenu_item);
- Qremap = intern ("remap");
+ Qremap = intern_c_string ("remap");
staticpro (&Qremap);
+ QCadvertised_binding = intern_c_string (":advertised-binding");
+ staticpro (&QCadvertised_binding);
+
command_remapping_vector = Fmake_vector (make_number (2), Qremap);
staticpro (&command_remapping_vector);