summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Blandy <jimb@redhat.com>1992-10-31 05:24:47 +0000
committerJim Blandy <jimb@redhat.com>1992-10-31 05:24:47 +0000
commitd09b20248ddfb6ffc73afb1ab51485f3d12d2c68 (patch)
tree619edda1474c4bf2c030254a84e1080bee549caf
parent5bb46ecf6c71724e39f2cd482d9018a354966533 (diff)
downloademacs-d09b20248ddfb6ffc73afb1ab51485f3d12d2c68.tar.gz
emacs-d09b20248ddfb6ffc73afb1ab51485f3d12d2c68.tar.bz2
emacs-d09b20248ddfb6ffc73afb1ab51485f3d12d2c68.zip
* keymap.c (Fdefine_key, Flookup_key, describe_map): Don't assume
that Flength returns an integer. * keymap.c: Deal with autoloaded keymaps properly. (get_keymap_1): Renamed to inner_get_keymap; made static. New argument AUTOLOAD says to pursue autoloads if non-zero. (Fkeymapp, get_keymap, get_keyelt, Flookup_key): Ask get_keymap_1 not to perform autoloads. (Fdefine_key): Ask get_keymap_1 to perform autoloads. Since autoloading may GC, remember that we have to GCPRO our local variables now. (Fminor_mode_key_binding): Call get_keymap instead of calling get_keymap_1 with equivalent arguments.
-rw-r--r--src/keymap.c73
1 files changed, 52 insertions, 21 deletions
diff --git a/src/keymap.c b/src/keymap.c
index a4105aeada1..6275fa990e2 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -175,34 +175,65 @@ VECTOR is a 128-element vector of bindings for ASCII characters.")
(object)
Lisp_Object object;
{
- return (NILP (get_keymap_1 (object, 0)) ? Qnil : Qt);
+ return (NILP (get_keymap_1 (object, 0, 0)) ? Qnil : Qt);
}
/* Check that OBJECT is a keymap (after dereferencing through any
- symbols). If it is, return it; otherwise, return nil, or signal an
- error if ERROR != 0. */
+ symbols). If it is, return it.
+
+ If AUTOLOAD is non-zero and OBJECT is a symbol whose function value
+ is an autoload form, do the autoload and try again.
+
+ ERROR controls how we respond if OBJECT isn't a keymap.
+ If ERROR is non-zero, signal an error; otherwise, just return Qnil.
+
+ Note that most of the time, we don't want to pursue autoloads.
+ Functions like Faccessible_keymaps which scan entire keymap trees
+ shouldn't load every autoloaded keymap. I'm not sure about this,
+ but it seems to me that only read_key_sequence, Flookup_key, and
+ Fdefine_key should cause keymaps to be autoloaded. */
+
Lisp_Object
-get_keymap_1 (object, error)
+get_keymap_1 (object, error, autoload)
Lisp_Object object;
- int error;
+ int error, autoload;
{
- register Lisp_Object tem;
+ Lisp_Object tem;
+ autoload_retry:
tem = indirect_function (object);
if (CONSP (tem) && EQ (XCONS (tem)->car, Qkeymap))
return tem;
+ /* Should we do an autoload? */
+ if (autoload
+ && XTYPE (object) == Lisp_Symbol
+ && CONSP (tem)
+ && EQ (XCONS (tem)->car, Qautoload))
+ {
+ struct gcpro gcpro1, gcpro2;
+
+ GCPRO2 (tem, object)
+ do_autoload (tem, object);
+ UNGCPRO;
+
+ goto autoload_retry;
+ }
+
if (error)
wrong_type_argument (Qkeymapp, object);
else
return Qnil;
}
+
+/* Follow any symbol chaining, and return the keymap denoted by OBJECT.
+ If OBJECT doesn't denote a keymap at all, signal an error. */
Lisp_Object
get_keymap (object)
Lisp_Object object;
{
- return get_keymap_1 (object, 1);
+ return get_keymap_1 (object, 0, 0);
}
@@ -285,7 +316,7 @@ get_keyelt (object)
register Lisp_Object map, tem;
/* If the contents are (KEYMAP . ELEMENT), go indirect. */
- map = get_keymap_1 (Fcar_safe (object), 0);
+ map = get_keymap_1 (Fcar_safe (object), 0, 0);
tem = Fkeymapp (map);
if (!NILP (tem))
object = access_keymap (map, Fcdr (object), 0);
@@ -459,7 +490,7 @@ DEF is anything that can be a key's definition:\n\
If KEYMAP is a sparse keymap, the pair binding KEY to DEF is added at\n\
the front of KEYMAP.")
(keymap, key, def)
- register Lisp_Object keymap;
+ Lisp_Object keymap;
Lisp_Object key;
Lisp_Object def;
{
@@ -469,6 +500,7 @@ the front of KEYMAP.")
register Lisp_Object cmd;
int metized = 0;
int length;
+ struct gcpro gcpro1, gcpro2, gcpro3;
keymap = get_keymap (keymap);
@@ -476,10 +508,12 @@ the front of KEYMAP.")
&& XTYPE (key) != Lisp_String)
key = wrong_type_argument (Qarrayp, key);
- length = Flength (key);
+ length = XFASTINT (Flength (key));
if (length == 0)
return Qnil;
+ GCPRO3 (keymap, key, def);
+
idx = 0;
while (1)
{
@@ -502,7 +536,7 @@ the front of KEYMAP.")
}
if (idx == length)
- return store_in_keymap (keymap, c, def);
+ RETURN_UNGCPRO (store_in_keymap (keymap, c, def));
cmd = get_keyelt (access_keymap (keymap, c, 0));
@@ -512,12 +546,10 @@ the front of KEYMAP.")
store_in_keymap (keymap, c, cmd);
}
- tem = Fkeymapp (cmd);
- if (NILP (tem))
+ keymap = get_keymap_1 (cmd, 0, 1);
+ if (NILP (keymap))
error ("Key sequence %s uses invalid prefix characters",
XSTRING (key)->data);
-
- keymap = get_keymap (cmd);
}
}
@@ -548,7 +580,7 @@ it takes to reach a non-prefix command.")
&& XTYPE (key) != Lisp_String)
key = wrong_type_argument (Qarrayp, key);
- length = Flength (key);
+ length = XFASTINT (Flength (key));
if (length == 0)
return keymap;
@@ -577,11 +609,10 @@ it takes to reach a non-prefix command.")
if (idx == length)
return cmd;
- tem = Fkeymapp (cmd);
- if (NILP (tem))
+ keymap = get_keymap_1 (cmd, 0, 0);
+ if (NILP (keymap))
return make_number (idx);
- keymap = get_keymap (cmd);
QUIT;
}
}
@@ -765,7 +796,7 @@ that come after prefix bindings.")
&& ! NILP (binding = Flookup_key (maps[i], key))
&& XTYPE (binding) != Lisp_Int)
{
- if (! NILP (get_keymap_1 (binding, 0)))
+ if (! NILP (get_keymap (binding)))
maps[j++] = Fcons (modes[i], binding);
else if (j == 0)
return Fcons (Fcons (modes[i], binding), Qnil);
@@ -1582,7 +1613,7 @@ describe_map (map, keys, partial, shadow)
{
register Lisp_Object keysdesc;
- if (!NILP (keys) && Flength (keys) > 0)
+ if (!NILP (keys) && XFASTINT (Flength (keys)) > 0)
keysdesc = concat2 (Fkey_description (keys),
build_string (" "));
else