aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman1996-06-06 20:25:48 +0000
committerRichard M. Stallman1996-06-06 20:25:48 +0000
commit7d58ed9927a9ab6e4220f02975e46e0f39ba05aa (patch)
tree9675d670294bb3b546034325c0a71be6a7024e6e /src
parent1f4cd937080fb5e936e1d7be7c0b023b45bebcb7 (diff)
downloademacs-7d58ed9927a9ab6e4220f02975e46e0f39ba05aa.tar.gz
emacs-7d58ed9927a9ab6e4220f02975e46e0f39ba05aa.zip
(Fkeymap_parent, Fset_keymap_parent): New functions.
(fix_submap_inheritance): New function. (access_keymap): Use fix_submap_inheritance.
Diffstat (limited to 'src')
-rw-r--r--src/keymap.c144
1 files changed, 144 insertions, 0 deletions
diff --git a/src/keymap.c b/src/keymap.c
index 5fd28583573..bb141e84e6c 100644
--- a/src/keymap.c
+++ b/src/keymap.c
@@ -258,8 +258,131 @@ get_keymap (object)
258{ 258{
259 return get_keymap_1 (object, 1, 0); 259 return get_keymap_1 (object, 1, 0);
260} 260}
261
262/* Return the parent map of the keymap MAP, or nil if it has none.
263 We assume that MAP is a valid keymap. */
264
265DEFUN ("keymap-parent", Fkeymap_parent, Skeymap_parent, 1, 1, 0,
266 "Return the parent keymap of KEYMAP.")
267 (keymap)
268 Lisp_Object keymap;
269{
270 Lisp_Object list;
271
272 keymap = get_keymap_1 (keymap, 1, 1);
273
274 /* Skip past the initial element `keymap'. */
275 list = XCONS (keymap)->cdr;
276 for (; CONSP (list); list = XCONS (list)->cdr)
277 {
278 /* See if there is another `keymap'. */
279 if (EQ (Qkeymap, XCONS (list)->car))
280 return list;
281 }
282
283 return Qnil;
284}
285
286/* Set the parent keymap of MAP to PARENT. */
287
288DEFUN ("set-keymap-parent", Fset_keymap_parent, Sset_keymap_parent, 2, 2, 0,
289 "Modify KEYMAP to set its parent map to PARENT.\n\
290PARENT should be nil or another keymap.")
291 (keymap, parent)
292 Lisp_Object keymap, parent;
293{
294 Lisp_Object list, prev;
295 int i;
261 296
297 keymap = get_keymap_1 (keymap, 1, 1);
298 if (!NILP (parent))
299 parent = get_keymap_1 (parent, 1, 1);
262 300
301 /* Skip past the initial element `keymap'. */
302 prev = keymap;
303 while (1)
304 {
305 list = XCONS (prev)->cdr;
306 /* If there is a parent keymap here, replace it.
307 If we came to the end, add the parent in PREV. */
308 if (! CONSP (list) || EQ (Qkeymap, XCONS (list)->car))
309 {
310 XCONS (prev)->cdr = parent;
311 break;
312 }
313 prev = list;
314 }
315
316 /* Scan through for submaps, and set their parents too. */
317
318 for (list = XCONS (keymap)->cdr; CONSP (list); list = XCONS (list)->cdr)
319 {
320 /* Stop the scan when we come to the parent. */
321 if (EQ (XCONS (list)->car, Qkeymap))
322 break;
323
324 /* If this element holds a prefix map, deal with it. */
325 if (CONSP (XCONS (list)->car)
326 && CONSP (XCONS (XCONS (list)->car)->cdr))
327 fix_submap_inheritance (keymap, XCONS (XCONS (list)->car)->car,
328 XCONS (XCONS (list)->car)->cdr);
329
330 if (VECTORP (XCONS (list)->car))
331 for (i = 0; i < XVECTOR (XCONS (list)->car)->size; i++)
332 if (CONSP (XVECTOR (XCONS (list)->car)->contents[i]))
333 fix_submap_inheritance (keymap, make_number (i),
334 XVECTOR (XCONS (list)->car)->contents[i]);
335 }
336
337 return parent;
338}
339
340/* EVENT is defined in MAP as a prefix, and SUBMAP is its definition.
341 if EVENT is also a prefix in MAP's parent,
342 make sure that SUBMAP inherits that definition as its own parent. */
343
344fix_submap_inheritance (map, event, submap)
345 Lisp_Object map, event, submap;
346{
347 Lisp_Object map_parent, parent_entry;
348
349 /* SUBMAP is a cons that we found as a key binding.
350 Discard the other things found in a menu key binding. */
351
352 if (CONSP (submap)
353 && STRINGP (XCONS (submap)->car))
354 {
355 submap = XCONS (submap)->cdr;
356 /* Also remove a menu help string, if any,
357 following the menu item name. */
358 if (CONSP (submap) && STRINGP (XCONS (submap)->car))
359 submap = XCONS (submap)->cdr;
360 /* Also remove the sublist that caches key equivalences, if any. */
361 if (CONSP (submap)
362 && CONSP (XCONS (submap)->car))
363 {
364 Lisp_Object carcar;
365 carcar = XCONS (XCONS (submap)->car)->car;
366 if (NILP (carcar) || VECTORP (carcar))
367 submap = XCONS (submap)->cdr;
368 }
369 }
370
371 /* If it isn't a keymap now, there's no work to do. */
372 if (! CONSP (submap)
373 || ! EQ (XCONS (submap)->car, Qkeymap))
374 return;
375
376 map_parent = Fkeymap_parent (map);
377 if (! NILP (map_parent))
378 parent_entry = access_keymap (map_parent, event, 0, 0);
379 else
380 parent_entry = Qnil;
381
382 if (! EQ (parent_entry, submap))
383 Fset_keymap_parent (submap, parent_entry);
384}
385
263/* Look up IDX in MAP. IDX may be any sort of event. 386/* Look up IDX in MAP. IDX may be any sort of event.
264 Note that this does only one level of lookup; IDX must be a single 387 Note that this does only one level of lookup; IDX must be a single
265 event, not a sequence. 388 event, not a sequence.
@@ -320,6 +443,8 @@ access_keymap (map, idx, t_ok, noinherit)
320 val = XCONS (binding)->cdr; 443 val = XCONS (binding)->cdr;
321 if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap)) 444 if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
322 return Qnil; 445 return Qnil;
446 if (CONSP (val))
447 fix_submap_inheritance (map, idx, val);
323 return val; 448 return val;
324 } 449 }
325 if (t_ok && EQ (XCONS (binding)->car, Qt)) 450 if (t_ok && EQ (XCONS (binding)->car, Qt))
@@ -332,6 +457,8 @@ access_keymap (map, idx, t_ok, noinherit)
332 val = XVECTOR (binding)->contents[XFASTINT (idx)]; 457 val = XVECTOR (binding)->contents[XFASTINT (idx)];
333 if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap)) 458 if (noprefix && CONSP (val) && EQ (XCONS (val)->car, Qkeymap))
334 return Qnil; 459 return Qnil;
460 if (CONSP (val))
461 fix_submap_inheritance (map, idx, val);
335 return val; 462 return val;
336 } 463 }
337 } 464 }
@@ -759,6 +886,20 @@ define_as_prefix (keymap, c)
759 make it a prefix in this map, and make its definition 886 make it a prefix in this map, and make its definition
760 inherit the other prefix definition. */ 887 inherit the other prefix definition. */
761 inherit = access_keymap (keymap, c, 0, 0); 888 inherit = access_keymap (keymap, c, 0, 0);
889#if 0
890 /* This code is needed to do the right thing in the following case:
891 keymap A inherits from B,
892 you define KEY as a prefix in A,
893 then later you define KEY as a prefix in B.
894 We want the old prefix definition in A to inherit from that in B.
895 It is hard to do that retroactively, so this code
896 creates the prefix in B right away.
897
898 But it turns out that this code causes problems immediately
899 when the prefix in A is defined: it causes B to define KEY
900 as a prefix with no subcommands.
901
902 So I took out this code. */
762 if (NILP (inherit)) 903 if (NILP (inherit))
763 { 904 {
764 /* If there's an inherited keymap 905 /* If there's an inherited keymap
@@ -773,6 +914,7 @@ define_as_prefix (keymap, c)
773 if (!NILP (tail)) 914 if (!NILP (tail))
774 inherit = define_as_prefix (tail, c); 915 inherit = define_as_prefix (tail, c);
775 } 916 }
917#endif
776 918
777 cmd = nconc2 (cmd, inherit); 919 cmd = nconc2 (cmd, inherit);
778 store_in_keymap (keymap, c, cmd); 920 store_in_keymap (keymap, c, cmd);
@@ -2648,6 +2790,8 @@ and applies even for keys that have ordinary bindings.");
2648 staticpro (&Qnon_ascii); 2790 staticpro (&Qnon_ascii);
2649 2791
2650 defsubr (&Skeymapp); 2792 defsubr (&Skeymapp);
2793 defsubr (&Skeymap_parent);
2794 defsubr (&Sset_keymap_parent);
2651 defsubr (&Smake_keymap); 2795 defsubr (&Smake_keymap);
2652 defsubr (&Smake_sparse_keymap); 2796 defsubr (&Smake_sparse_keymap);
2653 defsubr (&Scopy_keymap); 2797 defsubr (&Scopy_keymap);