summaryrefslogtreecommitdiff
path: root/src/keymap.c
diff options
context:
space:
mode:
authorRichard M. Stallman <rms@gnu.org>1993-06-15 06:26:00 +0000
committerRichard M. Stallman <rms@gnu.org>1993-06-15 06:26:00 +0000
commitc07aec9773d9b595200422b1225cc5ffe591e4e0 (patch)
treeeff186a4b6f390301acb0c002c2d44d7bbf27bf5 /src/keymap.c
parent0df8950e08c052ee296aa21891931e08cb0ec759 (diff)
downloademacs-c07aec9773d9b595200422b1225cc5ffe591e4e0.tar.gz
Make prefix keys work with keymap inheritance
by creating an inheritance structure for each subkeymap that we create in the inheriting keymap. (access_keymap): New arg NOINHERIT. All calls changed. (define_as_prefix): New function. (Fdefine_key): Use them.
Diffstat (limited to 'src/keymap.c')
-rw-r--r--src/keymap.c80
1 files changed, 69 insertions, 11 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 79c2836b905..e08a285ae6c 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -81,6 +81,7 @@ Lisp_Object Qkeymapp, Qkeymap, Qnon_ascii;
extern Lisp_Object meta_prefix_char;
void describe_map_tree ();
+static Lisp_Object define_as_prefix ();
static Lisp_Object describe_buffer_bindings ();
static void describe_command ();
static void describe_map ();
@@ -255,14 +256,20 @@ get_keymap (object)
bindings; any key left unmentioned by other tables and bindings is
given the binding of Qt.
- If T_OK is zero, bindings for Qt are not treated specially. */
+ If T_OK is zero, bindings for Qt are not treated specially.
+
+ If NOINHERIT, don't accept a subkeymap found in an inherited keymap. */
Lisp_Object
-access_keymap (map, idx, t_ok)
+access_keymap (map, idx, t_ok, noinherit)
Lisp_Object map;
Lisp_Object idx;
int t_ok;
+ int noinherit;
{
+ int noprefix = 0;
+ Lisp_Object val;
+
/* If idx is a list (some sort of mouse click, perhaps?),
the index we want to use is the car of the list, which
ought to be a symbol. */
@@ -287,9 +294,21 @@ access_keymap (map, idx, t_ok)
switch (XTYPE (binding))
{
+ case Lisp_Symbol:
+ /* If NOINHERIT, stop finding prefix definitions
+ after we pass a second occurrence of the `keymap' symbol. */
+ if (noinherit && EQ (binding, Qkeymap) && ! EQ (tail, map))
+ noprefix = 1;
+ break;
+
case Lisp_Cons:
if (EQ (XCONS (binding)->car, idx))
- return XCONS (binding)->cdr;
+ {
+ val = XCONS (binding)->cdr;
+ if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
+ return Qnil;
+ return val;
+ }
if (t_ok && EQ (XCONS (binding)->car, Qt))
t_binding = XCONS (binding)->cdr;
break;
@@ -298,7 +317,12 @@ access_keymap (map, idx, t_ok)
if (XTYPE (idx) == Lisp_Int
&& XINT (idx) >= 0
&& XINT (idx) < XVECTOR (binding)->size)
- return XVECTOR (binding)->contents[XINT (idx)];
+ {
+ val = XVECTOR (binding)->contents[XINT (idx)];
+ if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
+ return Qnil;
+ return val;
+ }
break;
}
@@ -330,7 +354,7 @@ get_keyelt (object)
map = get_keymap_1 (Fcar_safe (object), 0, 0);
tem = Fkeymapp (map);
if (!NILP (tem))
- object = access_keymap (map, Fcdr (object), 0);
+ object = access_keymap (map, Fcdr (object), 0, 0);
/* If the keymap contents looks like (STRING . DEFN),
use DEFN.
@@ -552,13 +576,11 @@ the front of KEYMAP.")
if (idx == length)
RETURN_UNGCPRO (store_in_keymap (keymap, c, def));
- cmd = get_keyelt (access_keymap (keymap, c, 0));
+ cmd = get_keyelt (access_keymap (keymap, c, 0, 1));
+ /* If this key is undefined, make it a prefix. */
if (NILP (cmd))
- {
- cmd = Fmake_sparse_keymap (Qnil);
- store_in_keymap (keymap, c, cmd);
- }
+ cmd = define_as_prefix (keymap, c);
keymap = get_keymap_1 (cmd, 0, 1);
if (NILP (keymap))
@@ -640,7 +662,7 @@ recognize the default bindings, just as `read-key-sequence' does.")
idx++;
}
- cmd = get_keyelt (access_keymap (keymap, c, t_ok));
+ cmd = get_keyelt (access_keymap (keymap, c, t_ok, 0));
if (idx == length)
return cmd;
@@ -652,6 +674,42 @@ recognize the default bindings, just as `read-key-sequence' does.")
}
}
+/* Make KEYMAP define event C as a keymap (i.e., as a prefix).
+ Assume that currently it does not define C at all.
+ Return the keymap. */
+
+static Lisp_Object
+define_as_prefix (keymap, c)
+ Lisp_Object keymap, c;
+{
+ Lisp_Object inherit, cmd;
+
+ cmd = Fmake_sparse_keymap (Qnil);
+ /* If this key is defined as a prefix in an inherited keymap,
+ make it a prefix in this map, and make its definition
+ inherit the other prefix definition. */
+ inherit = access_keymap (keymap, c, 0, 0);
+ if (NILP (inherit))
+ {
+ /* If there's an inherited keymap
+ and it doesn't define this key,
+ make it define this key. */
+ Lisp_Object tail;
+
+ for (tail = Fcdr (keymap); CONSP (tail); tail = XCONS (tail)->cdr)
+ if (EQ (XCONS (tail)->car, Qkeymap))
+ break;
+
+ if (!NILP (tail))
+ inherit = define_as_prefix (tail, c);
+ }
+
+ cmd = nconc2 (cmd, inherit);
+ store_in_keymap (keymap, c, cmd);
+
+ return cmd;
+}
+
/* Append a key to the end of a key sequence. We always make a vector. */
Lisp_Object