diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 13 | ||||
| -rw-r--r-- | src/keymap.c | 250 |
2 files changed, 105 insertions, 158 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index e9778013345..cc5cfd86b1c 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,16 @@ | |||
| 1 | 2000-10-25 Stefan Monnier <monnier@cs.yale.edu> | ||
| 2 | |||
| 3 | * keymap.c: Use AREF, ASET and ASIZE macros. | ||
| 4 | (Fmake_sparse_keymap): Docstring fix. | ||
| 5 | (synkey): Remove. | ||
| 6 | (shadow_lookup): Move up. | ||
| 7 | Handle the case where lookup-key returns an integer. | ||
| 8 | (where_is_internal_1): Drop arg `keymap'. Don't check shadowing. | ||
| 9 | (where_is_internal_2): Adapt to fewer args for where_is_internal_1. | ||
| 10 | (Fwhere_is_internal): Allow `xkeymap' to be a list of keymaps. | ||
| 11 | Simplify/rewrite the keymap-finding code. | ||
| 12 | Add check for command shadowing, using shadow_lookup. | ||
| 13 | |||
| 1 | 2000-10-24 Stefan Monnier <monnier@cs.yale.edu> | 14 | 2000-10-24 Stefan Monnier <monnier@cs.yale.edu> |
| 2 | 15 | ||
| 3 | * keymap.c (fix_submap_inheritance): Use get_keymap_1 on parent_entry | 16 | * keymap.c (fix_submap_inheritance): Use get_keymap_1 on parent_entry |
diff --git a/src/keymap.c b/src/keymap.c index e1fbb1b3ebc..cd8f1146d37 100644 --- a/src/keymap.c +++ b/src/keymap.c | |||
| @@ -134,7 +134,7 @@ in case you use it as a menu with `x-popup-menu'.") | |||
| 134 | } | 134 | } |
| 135 | 135 | ||
| 136 | DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 1, 0, | 136 | DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 1, 0, |
| 137 | "Construct and return a new sparse-keymap list.\n\ | 137 | "Construct and return a new sparse keymap.\n\ |
| 138 | Its car is `keymap' and its cdr is an alist of (CHAR . DEFINITION),\n\ | 138 | Its car is `keymap' and its cdr is an alist of (CHAR . DEFINITION),\n\ |
| 139 | which binds the character CHAR to DEFINITION, or (SYMBOL . DEFINITION),\n\ | 139 | which binds the character CHAR to DEFINITION, or (SYMBOL . DEFINITION),\n\ |
| 140 | which binds the function key or mouse event SYMBOL to DEFINITION.\n\ | 140 | which binds the function key or mouse event SYMBOL to DEFINITION.\n\ |
| @@ -174,23 +174,6 @@ initial_define_lispy_key (keymap, keyname, defname) | |||
| 174 | store_in_keymap (keymap, intern (keyname), intern (defname)); | 174 | store_in_keymap (keymap, intern (keyname), intern (defname)); |
| 175 | } | 175 | } |
| 176 | 176 | ||
| 177 | /* Define character fromchar in map frommap as an alias for character | ||
| 178 | tochar in map tomap. Subsequent redefinitions of the latter WILL | ||
| 179 | affect the former. */ | ||
| 180 | |||
| 181 | #if 0 | ||
| 182 | void | ||
| 183 | synkey (frommap, fromchar, tomap, tochar) | ||
| 184 | struct Lisp_Vector *frommap, *tomap; | ||
| 185 | int fromchar, tochar; | ||
| 186 | { | ||
| 187 | Lisp_Object v, c; | ||
| 188 | XSETVECTOR (v, tomap); | ||
| 189 | XSETFASTINT (c, tochar); | ||
| 190 | frommap->contents[fromchar] = Fcons (v, c); | ||
| 191 | } | ||
| 192 | #endif /* 0 */ | ||
| 193 | |||
| 194 | DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0, | 177 | DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0, |
| 195 | "Return t if OBJECT is a keymap.\n\ | 178 | "Return t if OBJECT is a keymap.\n\ |
| 196 | \n\ | 179 | \n\ |
| @@ -725,9 +708,9 @@ store_in_keymap (keymap, idx, def) | |||
| 725 | elt = XCAR (tail); | 708 | elt = XCAR (tail); |
| 726 | if (VECTORP (elt)) | 709 | if (VECTORP (elt)) |
| 727 | { | 710 | { |
| 728 | if (NATNUMP (idx) && XFASTINT (idx) < XVECTOR (elt)->size) | 711 | if (NATNUMP (idx) && XFASTINT (idx) < ASIZE (elt)) |
| 729 | { | 712 | { |
| 730 | XVECTOR (elt)->contents[XFASTINT (idx)] = def; | 713 | ASET (elt, XFASTINT (idx), def); |
| 731 | return def; | 714 | return def; |
| 732 | } | 715 | } |
| 733 | insertion_point = tail; | 716 | insertion_point = tail; |
| @@ -755,15 +738,12 @@ store_in_keymap (keymap, idx, def) | |||
| 755 | return def; | 738 | return def; |
| 756 | } | 739 | } |
| 757 | } | 740 | } |
| 758 | else if (SYMBOLP (elt)) | 741 | else if (EQ (elt, Qkeymap)) |
| 759 | { | 742 | /* If we find a 'keymap' symbol in the spine of KEYMAP, |
| 760 | /* If we find a 'keymap' symbol in the spine of KEYMAP, | 743 | then we must have found the start of a second keymap |
| 761 | then we must have found the start of a second keymap | 744 | being used as the tail of KEYMAP, and a binding for IDX |
| 762 | being used as the tail of KEYMAP, and a binding for IDX | 745 | should be inserted before it. */ |
| 763 | should be inserted before it. */ | 746 | goto keymap_end; |
| 764 | if (EQ (elt, Qkeymap)) | ||
| 765 | goto keymap_end; | ||
| 766 | } | ||
| 767 | 747 | ||
| 768 | QUIT; | 748 | QUIT; |
| 769 | } | 749 | } |
| @@ -821,11 +801,10 @@ is not copied.") | |||
| 821 | elt = Fcopy_sequence (elt); | 801 | elt = Fcopy_sequence (elt); |
| 822 | XCAR (tail) = elt; | 802 | XCAR (tail) = elt; |
| 823 | 803 | ||
| 824 | for (i = 0; i < XVECTOR (elt)->size; i++) | 804 | for (i = 0; i < ASIZE (elt); i++) |
| 825 | if (!SYMBOLP (XVECTOR (elt)->contents[i]) | 805 | if (!SYMBOLP (AREF (elt, i)) |
| 826 | && ! NILP (Fkeymapp (XVECTOR (elt)->contents[i]))) | 806 | && ! NILP (Fkeymapp (AREF (elt, i)))) |
| 827 | XVECTOR (elt)->contents[i] | 807 | ASET (elt, i, Fcopy_keymap (AREF (elt, i))); |
| 828 | = Fcopy_keymap (XVECTOR (elt)->contents[i]); | ||
| 829 | } | 808 | } |
| 830 | else if (CONSP (elt) && CONSP (XCDR (elt))) | 809 | else if (CONSP (elt) && CONSP (XCDR (elt))) |
| 831 | { | 810 | { |
| @@ -1501,7 +1480,7 @@ then the value includes only maps for prefixes that start with PREFIX.") | |||
| 1501 | FETCH_STRING_CHAR_ADVANCE (c, prefix, i, i_byte); | 1480 | FETCH_STRING_CHAR_ADVANCE (c, prefix, i, i_byte); |
| 1502 | if (SINGLE_BYTE_CHAR_P (c) && (c & 0200)) | 1481 | if (SINGLE_BYTE_CHAR_P (c) && (c & 0200)) |
| 1503 | c ^= 0200 | meta_modifier; | 1482 | c ^= 0200 | meta_modifier; |
| 1504 | XVECTOR (copy)->contents[i_before] = make_number (c); | 1483 | ASET (copy, i_before, make_number (c)); |
| 1505 | } | 1484 | } |
| 1506 | prefix = copy; | 1485 | prefix = copy; |
| 1507 | } | 1486 | } |
| @@ -1558,12 +1537,12 @@ then the value includes only maps for prefixes that start with PREFIX.") | |||
| 1558 | register int i; | 1537 | register int i; |
| 1559 | 1538 | ||
| 1560 | /* Vector keymap. Scan all the elements. */ | 1539 | /* Vector keymap. Scan all the elements. */ |
| 1561 | for (i = 0; i < XVECTOR (elt)->size; i++) | 1540 | for (i = 0; i < ASIZE (elt); i++) |
| 1562 | { | 1541 | { |
| 1563 | register Lisp_Object tem; | 1542 | register Lisp_Object tem; |
| 1564 | register Lisp_Object cmd; | 1543 | register Lisp_Object cmd; |
| 1565 | 1544 | ||
| 1566 | cmd = get_keyelt (XVECTOR (elt)->contents[i], 0); | 1545 | cmd = get_keyelt (AREF (elt, i), 0); |
| 1567 | if (NILP (cmd)) continue; | 1546 | if (NILP (cmd)) continue; |
| 1568 | tem = Fkeymapp (cmd); | 1547 | tem = Fkeymapp (cmd); |
| 1569 | if (!NILP (tem)) | 1548 | if (!NILP (tem)) |
| @@ -1626,7 +1605,7 @@ then the value includes only maps for prefixes that start with PREFIX.") | |||
| 1626 | 1605 | ||
| 1627 | element = thisseq; | 1606 | element = thisseq; |
| 1628 | tem = Fvconcat (1, &element); | 1607 | tem = Fvconcat (1, &element); |
| 1629 | XSETFASTINT (XVECTOR (tem)->contents[XINT (last)], | 1608 | XSETFASTINT (AREF (tem, XINT (last)), |
| 1630 | XINT (elt) | meta_modifier); | 1609 | XINT (elt) | meta_modifier); |
| 1631 | 1610 | ||
| 1632 | /* This new sequence is the same length as | 1611 | /* This new sequence is the same length as |
| @@ -1732,7 +1711,7 @@ spaces are put between sequence elements, etc.") | |||
| 1732 | FETCH_STRING_CHAR_ADVANCE (c, keys, i, i_byte); | 1711 | FETCH_STRING_CHAR_ADVANCE (c, keys, i, i_byte); |
| 1733 | if (SINGLE_BYTE_CHAR_P (c) && (c & 0200)) | 1712 | if (SINGLE_BYTE_CHAR_P (c) && (c & 0200)) |
| 1734 | c ^= 0200 | meta_modifier; | 1713 | c ^= 0200 | meta_modifier; |
| 1735 | XSETFASTINT (XVECTOR (vector)->contents[i_before], c); | 1714 | XSETFASTINT (AREF (vector, i_before), c); |
| 1736 | } | 1715 | } |
| 1737 | keys = vector; | 1716 | keys = vector; |
| 1738 | } | 1717 | } |
| @@ -1750,8 +1729,7 @@ spaces are put between sequence elements, etc.") | |||
| 1750 | 1729 | ||
| 1751 | for (i = 0; i < len; i++) | 1730 | for (i = 0; i < len; i++) |
| 1752 | { | 1731 | { |
| 1753 | args[i * 2] = Fsingle_key_description (XVECTOR (keys)->contents[i], | 1732 | args[i * 2] = Fsingle_key_description (AREF (keys, i), Qnil); |
| 1754 | Qnil); | ||
| 1755 | args[i * 2 + 1] = sep; | 1733 | args[i * 2 + 1] = sep; |
| 1756 | } | 1734 | } |
| 1757 | } | 1735 | } |
| @@ -2047,8 +2025,6 @@ ascii_sequence_p (seq) | |||
| 2047 | static Lisp_Object where_is_internal_1 (); | 2025 | static Lisp_Object where_is_internal_1 (); |
| 2048 | static void where_is_internal_2 (); | 2026 | static void where_is_internal_2 (); |
| 2049 | 2027 | ||
| 2050 | /* This function can GC if Flookup_key autoloads any keymaps. */ | ||
| 2051 | |||
| 2052 | static INLINE int | 2028 | static INLINE int |
| 2053 | menu_item_p (item) | 2029 | menu_item_p (item) |
| 2054 | Lisp_Object item; | 2030 | Lisp_Object item; |
| @@ -2058,10 +2034,31 @@ menu_item_p (item) | |||
| 2058 | || STRINGP (XCAR (item)))); | 2034 | || STRINGP (XCAR (item)))); |
| 2059 | } | 2035 | } |
| 2060 | 2036 | ||
| 2037 | /* Like Flookup_key, but uses a list of keymaps SHADOW instead of a single map. | ||
| 2038 | Returns the first non-nil binding found in any of those maps. */ | ||
| 2039 | |||
| 2040 | static Lisp_Object | ||
| 2041 | shadow_lookup (shadow, key, flag) | ||
| 2042 | Lisp_Object shadow, key, flag; | ||
| 2043 | { | ||
| 2044 | Lisp_Object tail, value; | ||
| 2045 | |||
| 2046 | for (tail = shadow; CONSP (tail); tail = XCDR (tail)) | ||
| 2047 | { | ||
| 2048 | value = Flookup_key (XCAR (tail), key, flag); | ||
| 2049 | if (!NILP (value) && !NATNUMP (value)) | ||
| 2050 | return value; | ||
| 2051 | } | ||
| 2052 | return Qnil; | ||
| 2053 | } | ||
| 2054 | |||
| 2055 | /* This function can GC if Flookup_key autoloads any keymaps. */ | ||
| 2056 | |||
| 2061 | DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 4, 0, | 2057 | DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 4, 0, |
| 2062 | "Return list of keys that invoke DEFINITION.\n\ | 2058 | "Return list of keys that invoke DEFINITION.\n\ |
| 2063 | If KEYMAP is non-nil, search only KEYMAP and the global keymap.\n\ | 2059 | If KEYMAP is non-nil, search only KEYMAP and the global keymap.\n\ |
| 2064 | If KEYMAP is nil, search all the currently active keymaps.\n\ | 2060 | If KEYMAP is nil, search all the currently active keymaps.\n\ |
| 2061 | If KEYMAP is a list of keymaps, search only those keymaps.\n\ | ||
| 2065 | \n\ | 2062 | \n\ |
| 2066 | If optional 3rd arg FIRSTONLY is non-nil, return the first key sequence found,\n\ | 2063 | If optional 3rd arg FIRSTONLY is non-nil, return the first key sequence found,\n\ |
| 2067 | rather than a list of all possible key sequences.\n\ | 2064 | rather than a list of all possible key sequences.\n\ |
| @@ -2077,55 +2074,35 @@ indirect definition itself.") | |||
| 2077 | Lisp_Object definition, xkeymap; | 2074 | Lisp_Object definition, xkeymap; |
| 2078 | Lisp_Object firstonly, noindirect; | 2075 | Lisp_Object firstonly, noindirect; |
| 2079 | { | 2076 | { |
| 2080 | Lisp_Object maps; | 2077 | Lisp_Object maps = Qnil; |
| 2081 | Lisp_Object found, sequences; | 2078 | Lisp_Object found, sequences; |
| 2082 | Lisp_Object keymap1; | 2079 | Lisp_Object keymaps; |
| 2083 | int keymap_specified = !NILP (xkeymap); | ||
| 2084 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; | 2080 | struct gcpro gcpro1, gcpro2, gcpro3, gcpro4, gcpro5; |
| 2085 | /* 1 means ignore all menu bindings entirely. */ | 2081 | /* 1 means ignore all menu bindings entirely. */ |
| 2086 | int nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii); | 2082 | int nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii); |
| 2087 | 2083 | ||
| 2088 | /* Find keymaps accessible from `keymap' or the current | 2084 | /* Find keymaps accessible from `xkeymap' or the current context. */ |
| 2089 | context. But don't muck with the value of `keymap', | 2085 | if (CONSP (xkeymap) && KEYMAPP (XCAR (xkeymap))) |
| 2090 | because `where_is_internal_1' uses it to check for | 2086 | keymaps = xkeymap; |
| 2091 | shadowed bindings. */ | 2087 | else if (! NILP (xkeymap)) |
| 2092 | keymap1 = xkeymap; | 2088 | keymaps = Fcons (xkeymap, Fcons (current_global_map, Qnil)); |
| 2093 | if (! keymap_specified) | ||
| 2094 | keymap1 = get_local_map (PT, current_buffer, keymap); | ||
| 2095 | |||
| 2096 | if (!NILP (keymap1)) | ||
| 2097 | maps = nconc2 (Faccessible_keymaps (get_keymap (keymap1), Qnil), | ||
| 2098 | Faccessible_keymaps (get_keymap (current_global_map), | ||
| 2099 | Qnil)); | ||
| 2100 | else | 2089 | else |
| 2090 | keymaps = | ||
| 2091 | Fdelq (Qnil, | ||
| 2092 | nconc2 (Fcurrent_minor_mode_maps (), | ||
| 2093 | Fcons (get_local_map (PT, current_buffer, keymap), | ||
| 2094 | Fcons (get_local_map (PT, current_buffer, local_map), | ||
| 2095 | Fcons (current_global_map, Qnil))))); | ||
| 2096 | |||
| 2097 | found = keymaps; | ||
| 2098 | while (CONSP (found)) | ||
| 2101 | { | 2099 | { |
| 2102 | keymap1 = xkeymap; | 2100 | maps = |
| 2103 | if (! keymap_specified) | 2101 | nconc2 (maps, Faccessible_keymaps (get_keymap (XCAR (found)), Qnil)); |
| 2104 | keymap1 = get_local_map (PT, current_buffer, local_map); | 2102 | found = XCDR (found); |
| 2105 | |||
| 2106 | if (!NILP (keymap1)) | ||
| 2107 | maps = nconc2 (Faccessible_keymaps (get_keymap (keymap1), Qnil), | ||
| 2108 | Faccessible_keymaps (get_keymap (current_global_map), | ||
| 2109 | Qnil)); | ||
| 2110 | else | ||
| 2111 | maps = Faccessible_keymaps (get_keymap (current_global_map), Qnil); | ||
| 2112 | } | 2103 | } |
| 2113 | 2104 | ||
| 2114 | /* Put the minor mode keymaps on the front. */ | 2105 | GCPRO5 (definition, keymaps, maps, found, sequences); |
| 2115 | if (! keymap_specified) | ||
| 2116 | { | ||
| 2117 | Lisp_Object minors; | ||
| 2118 | minors = Fnreverse (Fcurrent_minor_mode_maps ()); | ||
| 2119 | while (!NILP (minors)) | ||
| 2120 | { | ||
| 2121 | maps = nconc2 (Faccessible_keymaps (get_keymap (XCAR (minors)), | ||
| 2122 | Qnil), | ||
| 2123 | maps); | ||
| 2124 | minors = XCDR (minors); | ||
| 2125 | } | ||
| 2126 | } | ||
| 2127 | |||
| 2128 | GCPRO5 (definition, xkeymap, maps, found, sequences); | ||
| 2129 | found = Qnil; | 2106 | found = Qnil; |
| 2130 | sequences = Qnil; | 2107 | sequences = Qnil; |
| 2131 | 2108 | ||
| @@ -2183,10 +2160,10 @@ indirect definition itself.") | |||
| 2183 | /* In a vector, look at each element. */ | 2160 | /* In a vector, look at each element. */ |
| 2184 | for (i = 0; i < XVECTOR (elt)->size; i++) | 2161 | for (i = 0; i < XVECTOR (elt)->size; i++) |
| 2185 | { | 2162 | { |
| 2186 | binding = XVECTOR (elt)->contents[i]; | 2163 | binding = AREF (elt, i); |
| 2187 | XSETFASTINT (key, i); | 2164 | XSETFASTINT (key, i); |
| 2188 | sequence = where_is_internal_1 (binding, key, definition, | 2165 | sequence = where_is_internal_1 (binding, key, definition, |
| 2189 | noindirect, xkeymap, this, | 2166 | noindirect, this, |
| 2190 | last, nomenus, last_is_meta); | 2167 | last, nomenus, last_is_meta); |
| 2191 | if (!NILP (sequence)) | 2168 | if (!NILP (sequence)) |
| 2192 | sequences = Fcons (sequence, sequences); | 2169 | sequences = Fcons (sequence, sequences); |
| @@ -2198,13 +2175,13 @@ indirect definition itself.") | |||
| 2198 | Lisp_Object args; | 2175 | Lisp_Object args; |
| 2199 | 2176 | ||
| 2200 | args = Fcons (Fcons (Fcons (definition, noindirect), | 2177 | args = Fcons (Fcons (Fcons (definition, noindirect), |
| 2201 | Fcons (xkeymap, Qnil)), | 2178 | Qnil), /* Result accumulator. */ |
| 2202 | Fcons (Fcons (this, last), | 2179 | Fcons (Fcons (this, last), |
| 2203 | Fcons (make_number (nomenus), | 2180 | Fcons (make_number (nomenus), |
| 2204 | make_number (last_is_meta)))); | 2181 | make_number (last_is_meta)))); |
| 2205 | map_char_table (where_is_internal_2, Qnil, elt, args, | 2182 | map_char_table (where_is_internal_2, Qnil, elt, args, |
| 2206 | 0, indices); | 2183 | 0, indices); |
| 2207 | sequences = XCDR (XCDR (XCAR (args))); | 2184 | sequences = XCDR (XCAR (args)); |
| 2208 | } | 2185 | } |
| 2209 | else if (CONSP (elt)) | 2186 | else if (CONSP (elt)) |
| 2210 | { | 2187 | { |
| @@ -2214,7 +2191,7 @@ indirect definition itself.") | |||
| 2214 | binding = XCDR (elt); | 2191 | binding = XCDR (elt); |
| 2215 | 2192 | ||
| 2216 | sequence = where_is_internal_1 (binding, key, definition, | 2193 | sequence = where_is_internal_1 (binding, key, definition, |
| 2217 | noindirect, xkeymap, this, | 2194 | noindirect, this, |
| 2218 | last, nomenus, last_is_meta); | 2195 | last, nomenus, last_is_meta); |
| 2219 | if (!NILP (sequence)) | 2196 | if (!NILP (sequence)) |
| 2220 | sequences = Fcons (sequence, sequences); | 2197 | sequences = Fcons (sequence, sequences); |
| @@ -2227,6 +2204,19 @@ indirect definition itself.") | |||
| 2227 | 2204 | ||
| 2228 | sequence = XCAR (sequences); | 2205 | sequence = XCAR (sequences); |
| 2229 | 2206 | ||
| 2207 | /* Verify that this key binding is not shadowed by another | ||
| 2208 | binding for the same key, before we say it exists. | ||
| 2209 | |||
| 2210 | Mechanism: look for local definition of this key and if | ||
| 2211 | it is defined and does not match what we found then | ||
| 2212 | ignore this key. | ||
| 2213 | |||
| 2214 | Either nil or number as value from Flookup_key | ||
| 2215 | means undefined. */ | ||
| 2216 | binding = shadow_lookup (keymaps, sequence, Qnil); | ||
| 2217 | if (!EQ (binding, definition)) | ||
| 2218 | continue; | ||
| 2219 | |||
| 2230 | /* It is a true unshadowed match. Record it, unless it's already | 2220 | /* It is a true unshadowed match. Record it, unless it's already |
| 2231 | been seen (as could happen when inheriting keymaps). */ | 2221 | been seen (as could happen when inheriting keymaps). */ |
| 2232 | if (NILP (Fmember (sequence, found))) | 2222 | if (NILP (Fmember (sequence, found))) |
| @@ -2272,43 +2262,39 @@ static void | |||
| 2272 | where_is_internal_2 (args, key, binding) | 2262 | where_is_internal_2 (args, key, binding) |
| 2273 | Lisp_Object args, key, binding; | 2263 | Lisp_Object args, key, binding; |
| 2274 | { | 2264 | { |
| 2275 | Lisp_Object definition, noindirect, keymap, this, last; | 2265 | Lisp_Object definition, noindirect, this, last; |
| 2276 | Lisp_Object result, sequence; | 2266 | Lisp_Object result, sequence; |
| 2277 | int nomenus, last_is_meta; | 2267 | int nomenus, last_is_meta; |
| 2278 | struct gcpro gcpro1, gcpro2, gcpro3; | 2268 | struct gcpro gcpro1, gcpro2, gcpro3; |
| 2279 | 2269 | ||
| 2280 | GCPRO3 (args, key, binding); | 2270 | GCPRO3 (args, key, binding); |
| 2281 | result = XCDR (XCDR (XCAR (args))); | 2271 | result = XCDR (XCAR (args)); |
| 2282 | definition = XCAR (XCAR (XCAR (args))); | 2272 | definition = XCAR (XCAR (XCAR (args))); |
| 2283 | noindirect = XCDR (XCAR (XCAR (args))); | 2273 | noindirect = XCDR (XCAR (XCAR (args))); |
| 2284 | keymap = XCAR (XCDR (XCAR (args))); | ||
| 2285 | this = XCAR (XCAR (XCDR (args))); | 2274 | this = XCAR (XCAR (XCDR (args))); |
| 2286 | last = XCDR (XCAR (XCDR (args))); | 2275 | last = XCDR (XCAR (XCDR (args))); |
| 2287 | nomenus = XFASTINT (XCAR (XCDR (XCDR (args)))); | 2276 | nomenus = XFASTINT (XCAR (XCDR (XCDR (args)))); |
| 2288 | last_is_meta = XFASTINT (XCDR (XCDR (XCDR (args)))); | 2277 | last_is_meta = XFASTINT (XCDR (XCDR (XCDR (args)))); |
| 2289 | 2278 | ||
| 2290 | sequence = where_is_internal_1 (binding, key, definition, noindirect, keymap, | 2279 | sequence = where_is_internal_1 (binding, key, definition, noindirect, |
| 2291 | this, last, nomenus, last_is_meta); | 2280 | this, last, nomenus, last_is_meta); |
| 2292 | 2281 | ||
| 2293 | if (!NILP (sequence)) | 2282 | if (!NILP (sequence)) |
| 2294 | XCDR (XCDR (XCAR (args))) = Fcons (sequence, result); | 2283 | XCDR (XCAR (args)) = Fcons (sequence, result); |
| 2295 | 2284 | ||
| 2296 | UNGCPRO; | 2285 | UNGCPRO; |
| 2297 | } | 2286 | } |
| 2298 | 2287 | ||
| 2299 | 2288 | ||
| 2300 | /* This function can GC.because Flookup_key calls get_keymap_1 with | 2289 | /* This function cannot GC. */ |
| 2301 | non-zero argument AUTOLOAD. */ | ||
| 2302 | 2290 | ||
| 2303 | static Lisp_Object | 2291 | static Lisp_Object |
| 2304 | where_is_internal_1 (binding, key, definition, noindirect, keymap, this, last, | 2292 | where_is_internal_1 (binding, key, definition, noindirect, this, last, |
| 2305 | nomenus, last_is_meta) | 2293 | nomenus, last_is_meta) |
| 2306 | Lisp_Object binding, key, definition, noindirect, keymap, this, last; | 2294 | Lisp_Object binding, key, definition, noindirect, this, last; |
| 2307 | int nomenus, last_is_meta; | 2295 | int nomenus, last_is_meta; |
| 2308 | { | 2296 | { |
| 2309 | Lisp_Object sequence; | 2297 | Lisp_Object sequence; |
| 2310 | int keymap_specified = !NILP (keymap); | ||
| 2311 | struct gcpro gcpro1, gcpro2; | ||
| 2312 | 2298 | ||
| 2313 | /* Skip left-over menu-items. | 2299 | /* Skip left-over menu-items. |
| 2314 | These can appear in a keymap bound to a mouse click, for example. */ | 2300 | These can appear in a keymap bound to a mouse click, for example. */ |
| @@ -2342,41 +2328,7 @@ where_is_internal_1 (binding, key, definition, noindirect, keymap, this, last, | |||
| 2342 | else | 2328 | else |
| 2343 | sequence = append_key (this, key); | 2329 | sequence = append_key (this, key); |
| 2344 | 2330 | ||
| 2345 | /* Verify that this key binding is not shadowed by another | 2331 | return sequence; |
| 2346 | binding for the same key, before we say it exists. | ||
| 2347 | |||
| 2348 | Mechanism: look for local definition of this key and if | ||
| 2349 | it is defined and does not match what we found then | ||
| 2350 | ignore this key. | ||
| 2351 | |||
| 2352 | Either nil or number as value from Flookup_key | ||
| 2353 | means undefined. */ | ||
| 2354 | GCPRO2 (sequence, binding); | ||
| 2355 | if (keymap_specified) | ||
| 2356 | { | ||
| 2357 | binding = Flookup_key (keymap, sequence, Qnil); | ||
| 2358 | if (!NILP (binding) && !INTEGERP (binding)) | ||
| 2359 | { | ||
| 2360 | if (CONSP (definition)) | ||
| 2361 | { | ||
| 2362 | Lisp_Object tem; | ||
| 2363 | tem = Fequal (binding, definition); | ||
| 2364 | if (NILP (tem)) | ||
| 2365 | RETURN_UNGCPRO (Qnil); | ||
| 2366 | } | ||
| 2367 | else | ||
| 2368 | if (!EQ (binding, definition)) | ||
| 2369 | RETURN_UNGCPRO (Qnil); | ||
| 2370 | } | ||
| 2371 | } | ||
| 2372 | else | ||
| 2373 | { | ||
| 2374 | binding = Fkey_binding (sequence, Qnil); | ||
| 2375 | if (!EQ (binding, definition)) | ||
| 2376 | RETURN_UNGCPRO (Qnil); | ||
| 2377 | } | ||
| 2378 | |||
| 2379 | RETURN_UNGCPRO (sequence); | ||
| 2380 | } | 2332 | } |
| 2381 | 2333 | ||
| 2382 | /* describe-bindings - summarizing all the bindings in a set of keymaps. */ | 2334 | /* describe-bindings - summarizing all the bindings in a set of keymaps. */ |
| @@ -2746,24 +2698,6 @@ describe_translation (definition) | |||
| 2746 | } | 2698 | } |
| 2747 | } | 2699 | } |
| 2748 | 2700 | ||
| 2749 | /* Like Flookup_key, but uses a list of keymaps SHADOW instead of a single map. | ||
| 2750 | Returns the first non-nil binding found in any of those maps. */ | ||
| 2751 | |||
| 2752 | static Lisp_Object | ||
| 2753 | shadow_lookup (shadow, key, flag) | ||
| 2754 | Lisp_Object shadow, key, flag; | ||
| 2755 | { | ||
| 2756 | Lisp_Object tail, value; | ||
| 2757 | |||
| 2758 | for (tail = shadow; CONSP (tail); tail = XCDR (tail)) | ||
| 2759 | { | ||
| 2760 | value = Flookup_key (XCAR (tail), key, flag); | ||
| 2761 | if (!NILP (value)) | ||
| 2762 | return value; | ||
| 2763 | } | ||
| 2764 | return Qnil; | ||
| 2765 | } | ||
| 2766 | |||
| 2767 | /* Describe the contents of map MAP, assuming that this map itself is | 2701 | /* Describe the contents of map MAP, assuming that this map itself is |
| 2768 | reached by the sequence of prefix keys KEYS (a string or vector). | 2702 | reached by the sequence of prefix keys KEYS (a string or vector). |
| 2769 | PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */ | 2703 | PARTIAL, SHADOW, NOMENU are as in `describe_map_tree' above. */ |
| @@ -2843,7 +2777,7 @@ describe_map (map, keys, elt_describer, partial, shadow, seen, nomenu) | |||
| 2843 | /* Don't show a command that isn't really visible | 2777 | /* Don't show a command that isn't really visible |
| 2844 | because a local definition of the same key shadows it. */ | 2778 | because a local definition of the same key shadows it. */ |
| 2845 | 2779 | ||
| 2846 | XVECTOR (kludge)->contents[0] = event; | 2780 | ASET (kludge, 0, event); |
| 2847 | if (!NILP (shadow)) | 2781 | if (!NILP (shadow)) |
| 2848 | { | 2782 | { |
| 2849 | tem = shadow_lookup (shadow, kludge, Qt); | 2783 | tem = shadow_lookup (shadow, kludge, Qt); |
| @@ -3038,7 +2972,7 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 3038 | = get_keyelt (XCHAR_TABLE (vector)->contents[i], 0); | 2972 | = get_keyelt (XCHAR_TABLE (vector)->contents[i], 0); |
| 3039 | } | 2973 | } |
| 3040 | else | 2974 | else |
| 3041 | definition = get_keyelt (XVECTOR (vector)->contents[i], 0); | 2975 | definition = get_keyelt (AREF (vector, i), 0); |
| 3042 | 2976 | ||
| 3043 | if (NILP (definition)) continue; | 2977 | if (NILP (definition)) continue; |
| 3044 | 2978 | ||
| @@ -3078,7 +3012,7 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 3078 | { | 3012 | { |
| 3079 | Lisp_Object tem; | 3013 | Lisp_Object tem; |
| 3080 | 3014 | ||
| 3081 | XVECTOR (kludge)->contents[0] = make_number (character); | 3015 | ASET (kludge, 0, make_number (character)); |
| 3082 | tem = shadow_lookup (shadow, kludge, Qt); | 3016 | tem = shadow_lookup (shadow, kludge, Qt); |
| 3083 | 3017 | ||
| 3084 | if (!NILP (tem)) continue; | 3018 | if (!NILP (tem)) continue; |
| @@ -3090,7 +3024,7 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 3090 | { | 3024 | { |
| 3091 | Lisp_Object tem; | 3025 | Lisp_Object tem; |
| 3092 | 3026 | ||
| 3093 | XVECTOR (kludge)->contents[0] = make_number (character); | 3027 | ASET (kludge, 0, make_number (character)); |
| 3094 | tem = Flookup_key (entire_map, kludge, Qt); | 3028 | tem = Flookup_key (entire_map, kludge, Qt); |
| 3095 | 3029 | ||
| 3096 | if (! EQ (tem, definition)) | 3030 | if (! EQ (tem, definition)) |
| @@ -3183,7 +3117,7 @@ describe_vector (vector, elt_prefix, elt_describer, | |||
| 3183 | } | 3117 | } |
| 3184 | else | 3118 | else |
| 3185 | while (i + 1 < to | 3119 | while (i + 1 < to |
| 3186 | && (tem2 = get_keyelt (XVECTOR (vector)->contents[i + 1], 0), | 3120 | && (tem2 = get_keyelt (AREF (vector, i + 1), 0), |
| 3187 | !NILP (tem2)) | 3121 | !NILP (tem2)) |
| 3188 | && !NILP (Fequal (tem2, definition))) | 3122 | && !NILP (Fequal (tem2, definition))) |
| 3189 | i++; | 3123 | i++; |