comparison src/keymap.c @ 32476:9b2a0dc393a4

* keymap.c (access_keymap): Add AUTOLOAD parameter. Do the meta->esc mapping. Call get_keyelt before returning. Start scanning from the second element (the first is always `keymap') to make it easier to detect when we reach a parent map. Handle the case of inheriting from a symbol whose function is a map. (Fkeymap_parent): Also handle the `inherit from symbol' case. (fix_submap_inheritance, Fdefine_key): Update call to access_keymap. (get_keyelt, Flookup_key): Update call to access_keymap. Remove the meta->esc mappings. (define_as_prefix): Delete old disabled code. (menu_item_p): New function. (where_is_internal_1): Skip over the few remaining menu items. * lisp.h (access_keymap): Update prototype. * keyboard.c (read_char, menu_bar_items, tool_bar_items): Update call to access_keymap. (follow_key, read_key_sequence): Update calls to access_keymap. Remove the meta->esc mappings.
author Stefan Monnier <monnier@iro.umontreal.ca>
date Sun, 15 Oct 2000 03:31:21 +0000
parents a48fcf036df1
children a7703eb49693
comparison
equal deleted inserted replaced
32475:753586cbb758 32476:9b2a0dc393a4
300 /* See if there is another `keymap'. */ 300 /* See if there is another `keymap'. */
301 if (KEYMAPP (list)) 301 if (KEYMAPP (list))
302 return list; 302 return list;
303 } 303 }
304 304
305 return Qnil; 305 return get_keymap_1(list, 0, autoload);
306 } 306 }
307 307
308 308
309 /* Check whether MAP is one of MAPS parents. */ 309 /* Check whether MAP is one of MAPS parents. */
310 int 310 int
411 if (NILP (submap)) 411 if (NILP (submap))
412 return; 412 return;
413 413
414 map_parent = Fkeymap_parent (map); 414 map_parent = Fkeymap_parent (map);
415 if (! NILP (map_parent)) 415 if (! NILP (map_parent))
416 parent_entry = get_keyelt (access_keymap (map_parent, event, 0, 0), 0); 416 parent_entry = access_keymap (map_parent, event, 0, 0, 0);
417 else 417 else
418 parent_entry = Qnil; 418 parent_entry = Qnil;
419 419
420 /* If MAP's parent has something other than a keymap, 420 /* If MAP's parent has something other than a keymap,
421 our own submap shadows it completely, so use nil as SUBMAP's parent. */ 421 our own submap shadows it completely, so use nil as SUBMAP's parent. */
453 If T_OK is zero, bindings for Qt are not treated specially. 453 If T_OK is zero, bindings for Qt are not treated specially.
454 454
455 If NOINHERIT, don't accept a subkeymap found in an inherited keymap. */ 455 If NOINHERIT, don't accept a subkeymap found in an inherited keymap. */
456 456
457 Lisp_Object 457 Lisp_Object
458 access_keymap (map, idx, t_ok, noinherit) 458 access_keymap (map, idx, t_ok, noinherit, autoload)
459 Lisp_Object map; 459 Lisp_Object map;
460 Lisp_Object idx; 460 Lisp_Object idx;
461 int t_ok; 461 int t_ok;
462 int noinherit; 462 int noinherit;
463 int autoload;
463 { 464 {
464 int noprefix = 0; 465 int noprefix = 0;
465 Lisp_Object val; 466 Lisp_Object val;
466 467
467 /* If idx is a list (some sort of mouse click, perhaps?), 468 /* If idx is a list (some sort of mouse click, perhaps?),
476 else if (INTEGERP (idx)) 477 else if (INTEGERP (idx))
477 /* Clobber the high bits that can be present on a machine 478 /* Clobber the high bits that can be present on a machine
478 with more than 24 bits of integer. */ 479 with more than 24 bits of integer. */
479 XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1))); 480 XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1)));
480 481
482 /* Handle the special meta -> esc mapping. */
483 if (INTEGERP (idx) && XUINT (idx) & meta_modifier)
484 {
485 map = get_keymap_1 (access_keymap
486 (map, meta_prefix_char, t_ok, noinherit, autoload),
487 0, autoload);
488 XSETINT (idx, XFASTINT (idx) & ~meta_modifier);
489 }
490
481 { 491 {
482 Lisp_Object tail; 492 Lisp_Object tail;
483 Lisp_Object t_binding; 493 Lisp_Object t_binding;
484 494
485 t_binding = Qnil; 495 t_binding = Qnil;
486 for (tail = map; CONSP (tail); tail = XCDR (tail)) 496 for (tail = XCDR (map);
497 CONSP (tail) || (tail = get_keymap_1(tail, 0, autoload), CONSP (tail));
498 tail = XCDR (tail))
487 { 499 {
488 Lisp_Object binding; 500 Lisp_Object binding;
489 501
490 binding = XCAR (tail); 502 binding = XCAR (tail);
491 if (SYMBOLP (binding)) 503 if (SYMBOLP (binding))
492 { 504 {
493 /* If NOINHERIT, stop finding prefix definitions 505 /* If NOINHERIT, stop finding prefix definitions
494 after we pass a second occurrence of the `keymap' symbol. */ 506 after we pass a second occurrence of the `keymap' symbol. */
495 if (noinherit && EQ (binding, Qkeymap) && ! EQ (tail, map)) 507 if (noinherit && EQ (binding, Qkeymap))
496 noprefix = 1; 508 noprefix = 1;
497 } 509 }
498 else if (CONSP (binding)) 510 else if (CONSP (binding))
499 { 511 {
500 if (EQ (XCAR (binding), idx)) 512 if (EQ (XCAR (binding), idx))
502 val = XCDR (binding); 514 val = XCDR (binding);
503 if (noprefix && KEYMAPP (val)) 515 if (noprefix && KEYMAPP (val))
504 return Qnil; 516 return Qnil;
505 if (CONSP (val)) 517 if (CONSP (val))
506 fix_submap_inheritance (map, idx, val); 518 fix_submap_inheritance (map, idx, val);
507 return val; 519 return get_keyelt (val, autoload);
508 } 520 }
509 if (t_ok && EQ (XCAR (binding), Qt)) 521 if (t_ok && EQ (XCAR (binding), Qt))
510 t_binding = XCDR (binding); 522 t_binding = XCDR (binding);
511 } 523 }
512 else if (VECTORP (binding)) 524 else if (VECTORP (binding))
516 val = XVECTOR (binding)->contents[XFASTINT (idx)]; 528 val = XVECTOR (binding)->contents[XFASTINT (idx)];
517 if (noprefix && KEYMAPP (val)) 529 if (noprefix && KEYMAPP (val))
518 return Qnil; 530 return Qnil;
519 if (CONSP (val)) 531 if (CONSP (val))
520 fix_submap_inheritance (map, idx, val); 532 fix_submap_inheritance (map, idx, val);
521 return val; 533 return get_keyelt (val, autoload);
522 } 534 }
523 } 535 }
524 else if (CHAR_TABLE_P (binding)) 536 else if (CHAR_TABLE_P (binding))
525 { 537 {
526 /* Character codes with modifiers 538 /* Character codes with modifiers
534 val = Faref (binding, idx); 546 val = Faref (binding, idx);
535 if (noprefix && KEYMAPP (val)) 547 if (noprefix && KEYMAPP (val))
536 return Qnil; 548 return Qnil;
537 if (CONSP (val)) 549 if (CONSP (val))
538 fix_submap_inheritance (map, idx, val); 550 fix_submap_inheritance (map, idx, val);
539 return val; 551 return get_keyelt (val, autoload);
540 } 552 }
541 } 553 }
542 554
543 QUIT; 555 QUIT;
544 } 556 }
545 557
546 return t_binding; 558 return get_keyelt (t_binding, autoload);
547 } 559 }
548 } 560 }
549 561
550 /* Given OBJECT which was found in a slot in a keymap, 562 /* Given OBJECT which was found in a slot in a keymap,
551 trace indirect definitions to get the actual definition of that slot. 563 trace indirect definitions to get the actual definition of that slot.
633 645
634 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ 646 /* If the contents are (KEYMAP . ELEMENT), go indirect. */
635 else 647 else
636 { 648 {
637 Lisp_Object map; 649 Lisp_Object map;
638
639 map = get_keymap_1 (Fcar_safe (object), 0, autoload); 650 map = get_keymap_1 (Fcar_safe (object), 0, autoload);
640 if (NILP (map)) 651 return (NILP (map) ? object /* Invalid keymap */
641 /* Invalid keymap */ 652 : access_keymap (map, Fcdr (object), 0, 0, autoload));
642 return object;
643 else
644 {
645 Lisp_Object key;
646 key = Fcdr (object);
647 if (INTEGERP (key) && (XUINT (key) & meta_modifier))
648 {
649 object = access_keymap (map, meta_prefix_char, 0, 0);
650 map = get_keymap_1 (object, 0, autoload);
651 object = access_keymap (map, make_number (XINT (key)
652 & ~meta_modifier),
653 0, 0);
654 }
655 else
656 object = access_keymap (map, key, 0, 0);
657 }
658 } 653 }
659 } 654 }
660 } 655 }
661 656
662 static Lisp_Object 657 static Lisp_Object
971 error ("Key sequence contains invalid events"); 966 error ("Key sequence contains invalid events");
972 967
973 if (idx == length) 968 if (idx == length)
974 RETURN_UNGCPRO (store_in_keymap (keymap, c, def)); 969 RETURN_UNGCPRO (store_in_keymap (keymap, c, def));
975 970
976 cmd = get_keyelt (access_keymap (keymap, c, 0, 1), 1); 971 cmd = access_keymap (keymap, c, 0, 1, 1);
977 972
978 /* If this key is undefined, make it a prefix. */ 973 /* If this key is undefined, make it a prefix. */
979 if (NILP (cmd)) 974 if (NILP (cmd))
980 cmd = define_as_prefix (keymap, c); 975 cmd = define_as_prefix (keymap, c);
981 976
1012 Lisp_Object accept_default; 1007 Lisp_Object accept_default;
1013 { 1008 {
1014 register int idx; 1009 register int idx;
1015 register Lisp_Object cmd; 1010 register Lisp_Object cmd;
1016 register Lisp_Object c; 1011 register Lisp_Object c;
1017 int metized = 0;
1018 int length; 1012 int length;
1019 int t_ok = ! NILP (accept_default); 1013 int t_ok = ! NILP (accept_default);
1020 int meta_bit;
1021 struct gcpro gcpro1; 1014 struct gcpro gcpro1;
1022 1015
1023 keymap = get_keymap_1 (keymap, 1, 1); 1016 keymap = get_keymap_1 (keymap, 1, 1);
1024 1017
1025 if (!VECTORP (key) && !STRINGP (key)) 1018 if (!VECTORP (key) && !STRINGP (key))
1027 1020
1028 length = XFASTINT (Flength (key)); 1021 length = XFASTINT (Flength (key));
1029 if (length == 0) 1022 if (length == 0)
1030 return keymap; 1023 return keymap;
1031 1024
1032 if (VECTORP (key))
1033 meta_bit = meta_modifier;
1034 else
1035 meta_bit = 0x80;
1036
1037 GCPRO1 (key); 1025 GCPRO1 (key);
1038 1026
1039 idx = 0; 1027 idx = 0;
1040 while (1) 1028 while (1)
1041 { 1029 {
1042 c = Faref (key, make_number (idx)); 1030 c = Faref (key, make_number (idx++));
1043 1031
1044 if (CONSP (c) && lucid_event_type_list_p (c)) 1032 if (CONSP (c) && lucid_event_type_list_p (c))
1045 c = Fevent_convert_list (c); 1033 c = Fevent_convert_list (c);
1046 1034
1047 if (INTEGERP (c) 1035 /* Turn the 8th bit of string chars into a meta modifier. */
1048 && (XINT (c) & meta_bit) 1036 if (XINT (c) & 0x80 && STRINGP (key))
1049 && !metized) 1037 XSETINT (c, (XINT (c) | meta_modifier) & ~0x80);
1050 { 1038
1051 c = meta_prefix_char; 1039 cmd = access_keymap (keymap, c, t_ok, 0, 1);
1052 metized = 1;
1053 }
1054 else
1055 {
1056 if (INTEGERP (c))
1057 XSETINT (c, XINT (c) & ~meta_bit);
1058
1059 metized = 0;
1060 idx++;
1061 }
1062
1063 cmd = get_keyelt (access_keymap (keymap, c, t_ok, 0), 1);
1064 if (idx == length) 1040 if (idx == length)
1065 RETURN_UNGCPRO (cmd); 1041 RETURN_UNGCPRO (cmd);
1066 1042
1067 keymap = get_keymap_1 (cmd, 0, 1); 1043 keymap = get_keymap_1 (cmd, 0, 1);
1068 if (NILP (keymap)) 1044 if (NILP (keymap))
1078 1054
1079 static Lisp_Object 1055 static Lisp_Object
1080 define_as_prefix (keymap, c) 1056 define_as_prefix (keymap, c)
1081 Lisp_Object keymap, c; 1057 Lisp_Object keymap, c;
1082 { 1058 {
1083 Lisp_Object inherit, cmd; 1059 Lisp_Object cmd;
1084 1060
1085 cmd = Fmake_sparse_keymap (Qnil); 1061 cmd = Fmake_sparse_keymap (Qnil);
1086 /* If this key is defined as a prefix in an inherited keymap, 1062 /* If this key is defined as a prefix in an inherited keymap,
1087 make it a prefix in this map, and make its definition 1063 make it a prefix in this map, and make its definition
1088 inherit the other prefix definition. */ 1064 inherit the other prefix definition. */
1089 inherit = access_keymap (keymap, c, 0, 0); 1065 cmd = nconc2 (cmd, access_keymap (keymap, c, 0, 0, 0));
1090 #if 0
1091 /* This code is needed to do the right thing in the following case:
1092 keymap A inherits from B,
1093 you define KEY as a prefix in A,
1094 then later you define KEY as a prefix in B.
1095 We want the old prefix definition in A to inherit from that in B.
1096 It is hard to do that retroactively, so this code
1097 creates the prefix in B right away.
1098
1099 But it turns out that this code causes problems immediately
1100 when the prefix in A is defined: it causes B to define KEY
1101 as a prefix with no subcommands.
1102
1103 So I took out this code. */
1104 if (NILP (inherit))
1105 {
1106 /* If there's an inherited keymap
1107 and it doesn't define this key,
1108 make it define this key. */
1109 Lisp_Object tail;
1110
1111 for (tail = Fcdr (keymap); CONSP (tail); tail = XCDR (tail))
1112 if (EQ (XCAR (tail), Qkeymap))
1113 break;
1114
1115 if (!NILP (tail))
1116 inherit = define_as_prefix (tail, c);
1117 }
1118 #endif
1119
1120 cmd = nconc2 (cmd, inherit);
1121 store_in_keymap (keymap, c, cmd); 1066 store_in_keymap (keymap, c, cmd);
1122 1067
1123 return cmd; 1068 return cmd;
1124 } 1069 }
1125 1070
2080 static Lisp_Object where_is_internal_1 (); 2025 static Lisp_Object where_is_internal_1 ();
2081 static void where_is_internal_2 (); 2026 static void where_is_internal_2 ();
2082 2027
2083 /* This function can GC if Flookup_key autoloads any keymaps. */ 2028 /* This function can GC if Flookup_key autoloads any keymaps. */
2084 2029
2030 static INLINE int
2031 menu_item_p (item)
2032 Lisp_Object item;
2033 {
2034 return (CONSP (item)
2035 && (EQ (XCAR (item),Qmenu_item)
2036 || STRINGP (XCAR (item))));
2037 }
2038
2085 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 4, 0, 2039 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 4, 0,
2086 "Return list of keys that invoke DEFINITION.\n\ 2040 "Return list of keys that invoke DEFINITION.\n\
2087 If KEYMAP is non-nil, search only KEYMAP and the global keymap.\n\ 2041 If KEYMAP is non-nil, search only KEYMAP and the global keymap.\n\
2088 If KEYMAP is nil, search all the currently active keymaps.\n\ 2042 If KEYMAP is nil, search all the currently active keymaps.\n\
2089 \n\ 2043 \n\
2332 { 2286 {
2333 Lisp_Object sequence; 2287 Lisp_Object sequence;
2334 int keymap_specified = !NILP (keymap); 2288 int keymap_specified = !NILP (keymap);
2335 struct gcpro gcpro1, gcpro2; 2289 struct gcpro gcpro1, gcpro2;
2336 2290
2291 /* Skip left-over menu-items.
2292 These can appear in a keymap bound to a mouse click, for example. */
2293 if (nomenus && menu_item_p (binding))
2294 return Qnil;
2337 /* Search through indirections unless that's not wanted. */ 2295 /* Search through indirections unless that's not wanted. */
2338 if (NILP (noindirect)) 2296 if (NILP (noindirect))
2339 binding = get_keyelt (binding, 0); 2297 binding = get_keyelt (binding, 0);
2340 2298
2341 /* End this iteration if this element does not match 2299 /* End this iteration if this element does not match