aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1993-06-15 06:26:00 +0000
committerRichard M. Stallman1993-06-15 06:26:00 +0000
commitc07aec9773d9b595200422b1225cc5ffe591e4e0 (patch)
treeeff186a4b6f390301acb0c002c2d44d7bbf27bf5 /src
parent0df8950e08c052ee296aa21891931e08cb0ec759 (diff)
downloademacs-c07aec9773d9b595200422b1225cc5ffe591e4e0.tar.gz
emacs-c07aec9773d9b595200422b1225cc5ffe591e4e0.zip
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')
-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;
81extern Lisp_Object meta_prefix_char; 81extern Lisp_Object meta_prefix_char;
82 82
83void describe_map_tree (); 83void describe_map_tree ();
84static Lisp_Object define_as_prefix ();
84static Lisp_Object describe_buffer_bindings (); 85static Lisp_Object describe_buffer_bindings ();
85static void describe_command (); 86static void describe_command ();
86static void describe_map (); 87static void describe_map ();
@@ -255,14 +256,20 @@ get_keymap (object)
255 bindings; any key left unmentioned by other tables and bindings is 256 bindings; any key left unmentioned by other tables and bindings is
256 given the binding of Qt. 257 given the binding of Qt.
257 258
258 If T_OK is zero, bindings for Qt are not treated specially. */ 259 If T_OK is zero, bindings for Qt are not treated specially.
260
261 If NOINHERIT, don't accept a subkeymap found in an inherited keymap. */
259 262
260Lisp_Object 263Lisp_Object
261access_keymap (map, idx, t_ok) 264access_keymap (map, idx, t_ok, noinherit)
262 Lisp_Object map; 265 Lisp_Object map;
263 Lisp_Object idx; 266 Lisp_Object idx;
264 int t_ok; 267 int t_ok;
268 int noinherit;
265{ 269{
270 int noprefix = 0;
271 Lisp_Object val;
272
266 /* If idx is a list (some sort of mouse click, perhaps?), 273 /* If idx is a list (some sort of mouse click, perhaps?),
267 the index we want to use is the car of the list, which 274 the index we want to use is the car of the list, which
268 ought to be a symbol. */ 275 ought to be a symbol. */
@@ -287,9 +294,21 @@ access_keymap (map, idx, t_ok)
287 294
288 switch (XTYPE (binding)) 295 switch (XTYPE (binding))
289 { 296 {
297 case Lisp_Symbol:
298 /* If NOINHERIT, stop finding prefix definitions
299 after we pass a second occurrence of the `keymap' symbol. */
300 if (noinherit && EQ (binding, Qkeymap) && ! EQ (tail, map))
301 noprefix = 1;
302 break;
303
290 case Lisp_Cons: 304 case Lisp_Cons:
291 if (EQ (XCONS (binding)->car, idx)) 305 if (EQ (XCONS (binding)->car, idx))
292 return XCONS (binding)->cdr; 306 {
307 val = XCONS (binding)->cdr;
308 if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
309 return Qnil;
310 return val;
311 }
293 if (t_ok && EQ (XCONS (binding)->car, Qt)) 312 if (t_ok && EQ (XCONS (binding)->car, Qt))
294 t_binding = XCONS (binding)->cdr; 313 t_binding = XCONS (binding)->cdr;
295 break; 314 break;
@@ -298,7 +317,12 @@ access_keymap (map, idx, t_ok)
298 if (XTYPE (idx) == Lisp_Int 317 if (XTYPE (idx) == Lisp_Int
299 && XINT (idx) >= 0 318 && XINT (idx) >= 0
300 && XINT (idx) < XVECTOR (binding)->size) 319 && XINT (idx) < XVECTOR (binding)->size)
301 return XVECTOR (binding)->contents[XINT (idx)]; 320 {
321 val = XVECTOR (binding)->contents[XINT (idx)];
322 if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
323 return Qnil;
324 return val;
325 }
302 break; 326 break;
303 } 327 }
304 328
@@ -330,7 +354,7 @@ get_keyelt (object)
330 map = get_keymap_1 (Fcar_safe (object), 0, 0); 354 map = get_keymap_1 (Fcar_safe (object), 0, 0);
331 tem = Fkeymapp (map); 355 tem = Fkeymapp (map);
332 if (!NILP (tem)) 356 if (!NILP (tem))
333 object = access_keymap (map, Fcdr (object), 0); 357 object = access_keymap (map, Fcdr (object), 0, 0);
334 358
335 /* If the keymap contents looks like (STRING . DEFN), 359 /* If the keymap contents looks like (STRING . DEFN),
336 use DEFN. 360 use DEFN.
@@ -552,13 +576,11 @@ the front of KEYMAP.")
552 if (idx == length) 576 if (idx == length)
553 RETURN_UNGCPRO (store_in_keymap (keymap, c, def)); 577 RETURN_UNGCPRO (store_in_keymap (keymap, c, def));
554 578
555 cmd = get_keyelt (access_keymap (keymap, c, 0)); 579 cmd = get_keyelt (access_keymap (keymap, c, 0, 1));
556 580
581 /* If this key is undefined, make it a prefix. */
557 if (NILP (cmd)) 582 if (NILP (cmd))
558 { 583 cmd = define_as_prefix (keymap, c);
559 cmd = Fmake_sparse_keymap (Qnil);
560 store_in_keymap (keymap, c, cmd);
561 }
562 584
563 keymap = get_keymap_1 (cmd, 0, 1); 585 keymap = get_keymap_1 (cmd, 0, 1);
564 if (NILP (keymap)) 586 if (NILP (keymap))
@@ -640,7 +662,7 @@ recognize the default bindings, just as `read-key-sequence' does.")
640 idx++; 662 idx++;
641 } 663 }
642 664
643 cmd = get_keyelt (access_keymap (keymap, c, t_ok)); 665 cmd = get_keyelt (access_keymap (keymap, c, t_ok, 0));
644 if (idx == length) 666 if (idx == length)
645 return cmd; 667 return cmd;
646 668
@@ -652,6 +674,42 @@ recognize the default bindings, just as `read-key-sequence' does.")
652 } 674 }
653} 675}
654 676
677/* Make KEYMAP define event C as a keymap (i.e., as a prefix).
678 Assume that currently it does not define C at all.
679 Return the keymap. */
680
681static Lisp_Object
682define_as_prefix (keymap, c)
683 Lisp_Object keymap, c;
684{
685 Lisp_Object inherit, cmd;
686
687 cmd = Fmake_sparse_keymap (Qnil);
688 /* If this key is defined as a prefix in an inherited keymap,
689 make it a prefix in this map, and make its definition
690 inherit the other prefix definition. */
691 inherit = access_keymap (keymap, c, 0, 0);
692 if (NILP (inherit))
693 {
694 /* If there's an inherited keymap
695 and it doesn't define this key,
696 make it define this key. */
697 Lisp_Object tail;
698
699 for (tail = Fcdr (keymap); CONSP (tail); tail = XCONS (tail)->cdr)
700 if (EQ (XCONS (tail)->car, Qkeymap))
701 break;
702
703 if (!NILP (tail))
704 inherit = define_as_prefix (tail, c);
705 }
706
707 cmd = nconc2 (cmd, inherit);
708 store_in_keymap (keymap, c, cmd);
709
710 return cmd;
711}
712
655/* Append a key to the end of a key sequence. We always make a vector. */ 713/* Append a key to the end of a key sequence. We always make a vector. */
656 714
657Lisp_Object 715Lisp_Object