Mercurial > emacs
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 |