Mercurial > hg > xemacs-beta
comparison src/keymap.c @ 5679:a81a739181dc
Add command remapping, a more robust alternative to #'substitute-key-definition
src/ChangeLog addition:
2012-09-02 Aidan Kehoe <kehoea@parhasard.net>
* keymap.c:
Add command remapping, a more robust equivalent to
#'substitute-key-definition.
* keymap.c (CHECK_REMAPPING_POSITION): New.
* keymap.c (keymap_equal): Correct a comment here.
* keymap.c (Fdefine_key): Document the command remapping syntax.
* keymap.c (Fremap_command): New.
* keymap.c (command_remapping): New.
* keymap.c (Fcommand_remapping): New.
* keymap.c (commands_remapped_to_mapper): New.
* keymap.c (commands_remapped_to_traverser): New.
* keymap.c (Fcommands_remapped_to): New.
* keymap.c (get_relevant_keymaps): Take a new POSITION argument.
* keymap.c (Fcurrent_keymaps, event_binding):
Supply the new POSITION argument to get_relevant_keymaps.
* keymap.c (Fkey_binding):
Add new arguments, NO-REMAP and POSITION.
* keymap.c (map_keymap_mapper):
* keymap.c (Fwhere_is_internal):
* keymap.c (where_is_to_char):
* keymap.c (where_is_recursive_mapper):
Don't expose the key remapping in these functions. This conflicts
with GNU, but is more sane for our callers. Access to command
remapping is with the functions #'command-remapping,
#'commands-remapped-to, and #'remap-command, not with the general
keymap functions, apart from the compatibility hack in #'define-key.
* keymap.c (syms_of_keymap):
* keymap.c (vars_of_keymap):
* keymap.c (complex_vars_of_keymap):
* lisp.h: New CHECK_COMMAND macro.
man/ChangeLog addition:
2012-09-02 Aidan Kehoe <kehoea@parhasard.net>
* lispref/keymaps.texi (Keymaps):
* lispref/keymaps.texi (Changing Key Bindings):
* lispref/keymaps.texi (Scanning Keymaps):
* lispref/keymaps.texi (Remapping commands):
* lispref/keymaps.texi (XEmacs): New.
* lispref/keymaps.texi (Other Keymap Functions):
Document the new command remapping functionality in this file.
lisp/ChangeLog addition:
2012-09-02 Aidan Kehoe <kehoea@parhasard.net>
* help.el (describe-function-1):
Document any command remapping that has been done in this function.
tests/ChangeLog addition:
2012-09-02 Aidan Kehoe <kehoea@parhasard.net>
* automated/keymap-tests.el:
Test the new command remapping functionality.
author | Aidan Kehoe <kehoea@parhasard.net> |
---|---|
date | Sun, 02 Sep 2012 14:31:40 +0100 |
parents | 56144c8593a8 |
children | 4af5a3435c94 |
comparison
equal
deleted
inserted
replaced
5678:b0d40183ac79 | 5679:a81a739181dc |
---|---|
186 Lisp_Object Vsingle_space_string; | 186 Lisp_Object Vsingle_space_string; |
187 Lisp_Object Qsuppress_keymap; | 187 Lisp_Object Qsuppress_keymap; |
188 Lisp_Object Qmodeline_map; | 188 Lisp_Object Qmodeline_map; |
189 Lisp_Object Qtoolbar_map; | 189 Lisp_Object Qtoolbar_map; |
190 | 190 |
191 Lisp_Object Qremap; | |
192 Lisp_Object Qxemacs_command_remapping; /* Uninterned, so there's no conflict | |
193 with any key named remap. */ | |
194 | |
191 EXFUN (Fkeymap_fullness, 1); | 195 EXFUN (Fkeymap_fullness, 1); |
192 EXFUN (Fset_keymap_name, 2); | 196 EXFUN (Fset_keymap_name, 2); |
193 EXFUN (Fsingle_key_description, 1); | 197 EXFUN (Fsingle_key_description, 1); |
198 EXFUN (Fremap_command, 3); | |
194 | 199 |
195 static void describe_command (Lisp_Object definition, Lisp_Object buffer); | 200 static void describe_command (Lisp_Object definition, Lisp_Object buffer); |
196 static void describe_map (Lisp_Object keymap, Lisp_Object elt_prefix, | 201 static void describe_map (Lisp_Object keymap, Lisp_Object elt_prefix, |
197 void (*elt_describer) (Lisp_Object, Lisp_Object), | 202 void (*elt_describer) (Lisp_Object, Lisp_Object), |
198 int partial, | 203 int partial, |
199 Lisp_Object shadow, | 204 Lisp_Object shadow, |
200 int mice_only_p, | 205 int mice_only_p, |
201 Lisp_Object buffer); | 206 Lisp_Object buffer); |
202 static Lisp_Object keymap_submaps (Lisp_Object keymap); | 207 static Lisp_Object keymap_submaps (Lisp_Object keymap); |
208 static int get_relevant_keymaps (Lisp_Object, Lisp_Object, int, | |
209 Lisp_Object maps[]); | |
210 static Lisp_Object lookup_keys (Lisp_Object, int, Lisp_Object *, int); | |
211 static void map_keymap (Lisp_Object keymap_table, int sort_first, | |
212 void (*function) (const Lisp_Key_Data *key, | |
213 Lisp_Object binding, | |
214 void *fn_arg), | |
215 void *fn_arg); | |
203 | 216 |
204 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift; | 217 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift; |
205 | 218 |
206 #define INCLUDE_BUTTON_ZERO | 219 #define INCLUDE_BUTTON_ZERO |
207 #define FROB(num) \ | 220 #define FROB(num) \ |
218 #include "keymap-buttons.h" | 231 #include "keymap-buttons.h" |
219 | 232 |
220 /* Kludge kludge kludge */ | 233 /* Kludge kludge kludge */ |
221 Lisp_Object QLFD, QTAB, QRET, QESC, QDEL, QSPC, QBS; | 234 Lisp_Object QLFD, QTAB, QRET, QESC, QDEL, QSPC, QBS; |
222 | 235 |
236 #define CHECK_REMAPPING_POSITION(object) do \ | |
237 { \ | |
238 if (!(NILP (object) || FIXNUMP (object) || MARKERP (object) \ | |
239 || EVENTP (object))) \ | |
240 { \ | |
241 wtaerror ("Not a valid POSITION", object); \ | |
242 } \ | |
243 } while (0) | |
244 | |
223 | 245 |
224 /************************************************************************/ | 246 /************************************************************************/ |
225 /* The keymap Lisp object */ | 247 /* The keymap Lisp object */ |
226 /************************************************************************/ | 248 /************************************************************************/ |
227 | 249 |
228 /* Keymaps are equal if Faces are equal if all of their display attributes are equal. We | 250 /* Keymaps are equal if all of their attributes are equal. */ |
229 don't compare names or doc-strings, because that would make equal | |
230 be eq. | |
231 | |
232 This isn't concerned with "unspecified" attributes, that's what | |
233 #'face-differs-from-default-p is for. */ | |
234 static int | 251 static int |
235 keymap_equal (Lisp_Object obj1, Lisp_Object obj2, int depth, | 252 keymap_equal (Lisp_Object obj1, Lisp_Object obj2, int depth, |
236 int UNUSED (foldcase)) | 253 int UNUSED (foldcase)) |
237 { | 254 { |
238 Lisp_Keymap *k1 = XKEYMAP (obj1); | 255 Lisp_Keymap *k1 = XKEYMAP (obj1); |
1824 | 1841 |
1825 Besides the canonical representation as a vector of lists of symbols, | 1842 Besides the canonical representation as a vector of lists of symbols, |
1826 `define-key' also accepts a number of abbreviations, aliases, and variants | 1843 `define-key' also accepts a number of abbreviations, aliases, and variants |
1827 for convenience, compatibility, and internal use. | 1844 for convenience, compatibility, and internal use. |
1828 | 1845 |
1846 A key sequence can also be the vector [remap COMMAND]; this shadows any | |
1847 bindings for COMMAND in KEYMAP, using DEF instead of COMMAND. See | |
1848 `command-remapping' and `remap-command'. Specify [(remap) KEYSTROKE] if | |
1849 your keyboard has a key with the name `remap' and you'd like to use it as a | |
1850 prefix. | |
1851 | |
1829 A keystroke may be represented by a key; this is treated as though it were a | 1852 A keystroke may be represented by a key; this is treated as though it were a |
1830 list containing that key as the only element. A keystroke may also be | 1853 list containing that key as the only element. A keystroke may also be |
1831 represented by an event object, as returned by the `next-command-event' and | 1854 represented by an event object, as returned by the `next-command-event' and |
1832 `read-key-sequence' functions. A key sequence may be represented by a | 1855 `read-key-sequence' functions. A key sequence may be represented by a |
1833 single keystroke; this is treated as a vector containing that keystroke as | 1856 single keystroke; this is treated as a vector containing that keystroke as |
1913 } | 1936 } |
1914 if (len == 0) | 1937 if (len == 0) |
1915 return Qnil; | 1938 return Qnil; |
1916 | 1939 |
1917 GCPRO3 (keymap, keys, def); | 1940 GCPRO3 (keymap, keys, def); |
1941 | |
1942 /* Allow access to any keys named remap, use our uninterned symbol. */ | |
1943 if (2 == len && VECTORP (keys) && EQ (Qremap, XVECTOR_DATA (keys) [0])) | |
1944 { | |
1945 return Fremap_command (keymap, XVECTOR_DATA (keys) [1], def); | |
1946 } | |
1918 | 1947 |
1919 /* ASCII grunge. | 1948 /* ASCII grunge. |
1920 When the user defines a key which, in a strictly ASCII world, would be | 1949 When the user defines a key which, in a strictly ASCII world, would be |
1921 produced by two different keys (^J and linefeed, or ^H and backspace, | 1950 produced by two different keys (^J and linefeed, or ^H and backspace, |
1922 for example) then the binding will be made for both keysyms. | 1951 for example) then the binding will be made for both keysyms. |
2034 keymap = get_keymap (cmd, 1, 1); | 2063 keymap = get_keymap (cmd, 1, 1); |
2035 NUNGCPRO; | 2064 NUNGCPRO; |
2036 } | 2065 } |
2037 } | 2066 } |
2038 } | 2067 } |
2039 | 2068 |
2069 DEFUN ("remap-command", Fremap_command, 3, 3, 0, /* | |
2070 Ensure that NEW is called when previously OLD would be, in KEYMAP. | |
2071 | |
2072 NEW and OLD are both command symbols. KEYMAP is a keymap object. | |
2073 | |
2074 This is equivalent to `(define-key KEYMAP [remap OLD] NEW])'. See also | |
2075 `substitute-key-definition', an older way of doing a similar thing. | |
2076 */ | |
2077 (keymap, old, new_)) | |
2078 { | |
2079 Lisp_Object cmd; | |
2080 Lisp_Key_Data parsed; | |
2081 | |
2082 keymap = get_keymap (keymap, 1, 1); | |
2083 CHECK_COMMAND (old); | |
2084 CHECK_COMMAND (new_); | |
2085 | |
2086 define_key_parser (Qxemacs_command_remapping, &parsed); | |
2087 cmd = keymap_lookup_1 (keymap, &parsed, 0); | |
2088 if (NILP (cmd)) | |
2089 { | |
2090 cmd = Fmake_sparse_keymap (Qnil); | |
2091 XKEYMAP (cmd)->name /* for debugging */ | |
2092 = list2 (make_key_description (&parsed, 1), keymap); | |
2093 keymap_store (keymap, &parsed, cmd); | |
2094 } | |
2095 | |
2096 assert (!NILP (Fkeymapp (cmd))); | |
2097 define_key_parser (old, &parsed); | |
2098 keymap_store (cmd, &parsed, new_); | |
2099 return new_; | |
2100 } | |
2101 | |
2102 static Lisp_Object | |
2103 command_remapping (Lisp_Object definition, int nmaps, Lisp_Object *maps) | |
2104 { | |
2105 Lisp_Object remapping = Qnil; | |
2106 Lisp_Object keys[2] = { Qxemacs_command_remapping, definition }; | |
2107 int jj; | |
2108 | |
2109 for (jj = 0; jj < nmaps; jj++) | |
2110 { | |
2111 remapping = lookup_keys (maps[jj], countof (keys), keys, 0); | |
2112 if (!NILP (remapping) && !FIXNUMP (remapping)) | |
2113 { | |
2114 return remapping; | |
2115 } | |
2116 } | |
2117 | |
2118 return Qnil; | |
2119 } | |
2120 | |
2121 DEFUN ("command-remapping", Fcommand_remapping, 1, 3, 0, /* | |
2122 Return the remapping for command COMMAND. | |
2123 | |
2124 Return nil if COMMAND is not remapped (or not a symbol). The remapping is | |
2125 the command that is executed when some key sequence in the relevant keymaps | |
2126 would normally execute COMMAND, but this has been intercepted by | |
2127 `remap-command' or the [remap COMMAND] syntax for KEYS in `define-key'. | |
2128 | |
2129 If the optional argument POSITION is non-nil, it specifies an event, and the | |
2130 remapping occurs in the keymaps associated with it. It can also be a number | |
2131 or marker, in which case the keymap properties at the specified buffer | |
2132 position instead of point are used. The KEYMAPS argument is ignored if | |
2133 POSITION is non-nil. | |
2134 | |
2135 If the optional argument KEYMAPS is non-nil, it should be a list of | |
2136 keymaps to search for command remapping. Otherwise, search for the | |
2137 remapping in all currently active keymaps. | |
2138 */ | |
2139 (command, position, keymaps)) | |
2140 { | |
2141 Lisp_Object maps[100]; | |
2142 Lisp_Object *gubbish = maps; | |
2143 int nmaps, maps_count = countof (maps); | |
2144 | |
2145 CHECK_COMMAND (command); | |
2146 CHECK_LIST (keymaps); | |
2147 CHECK_REMAPPING_POSITION (position); | |
2148 | |
2149 /* Get keymaps as an array */ | |
2150 if (NILP (keymaps) || !NILP (position)) | |
2151 { | |
2152 nmaps = get_relevant_keymaps (Qnil, position, maps_count, gubbish); | |
2153 } | |
2154 else | |
2155 { | |
2156 Elemcount jj = 0; | |
2157 nmaps = XFIXNUM (Flength (keymaps)); | |
2158 if (nmaps > maps_count) | |
2159 { | |
2160 gubbish = alloca_array (Lisp_Object, nmaps); | |
2161 } | |
2162 | |
2163 { | |
2164 LIST_LOOP_2 (elt, keymaps) | |
2165 { | |
2166 gubbish[jj++] = elt; | |
2167 } | |
2168 } | |
2169 } | |
2170 | |
2171 if (nmaps > maps_count) | |
2172 { | |
2173 gubbish = alloca_array (Lisp_Object, nmaps); | |
2174 nmaps = get_relevant_keymaps (Qnil, position, nmaps, gubbish); | |
2175 } | |
2176 | |
2177 return command_remapping (command, nmaps, gubbish); | |
2178 } | |
2179 | |
2180 struct commands_remapped_to_closure | |
2181 { | |
2182 Lisp_Object command; | |
2183 Lisp_Object result; | |
2184 }; | |
2185 | |
2186 static void | |
2187 commands_remapped_to_mapper (const Lisp_Key_Data *key, Lisp_Object binding, | |
2188 void *data) | |
2189 { | |
2190 struct commands_remapped_to_closure *crtc | |
2191 = (struct commands_remapped_to_closure *) data; | |
2192 | |
2193 if (EQ (binding, crtc->command)) | |
2194 { | |
2195 crtc->result = Fcons (key->keysym, crtc->result); | |
2196 } | |
2197 } | |
2198 | |
2199 static Lisp_Object | |
2200 commands_remapped_to_traverser (Lisp_Object k, void *arg) | |
2201 { | |
2202 Lisp_Object remapping | |
2203 = lookup_keys (k, 1, &Qxemacs_command_remapping, 0); | |
2204 if (KEYMAPP (remapping)) | |
2205 { | |
2206 map_keymap (XKEYMAP (remapping)->table, 0, commands_remapped_to_mapper, | |
2207 arg); | |
2208 } | |
2209 | |
2210 return Qnil; | |
2211 } | |
2212 | |
2213 DEFUN ("commands-remapped-to", Fcommands_remapped_to, 1, 3, 0, /* | |
2214 Return a list of symbols for which COMMAND is their remapping in KEYMAPS. | |
2215 | |
2216 This is the inverse operation of `command-remapping', which see. | |
2217 */ | |
2218 (command, keymaps, position)) | |
2219 { | |
2220 Lisp_Object maps[100]; | |
2221 Lisp_Object *gubbish = maps; | |
2222 int nmaps, maps_count = countof (maps), jj; | |
2223 struct commands_remapped_to_closure closure = { command, Qnil }; | |
2224 struct gcpro gcpro1; | |
2225 | |
2226 CHECK_COMMAND (command); | |
2227 CHECK_LIST (keymaps); | |
2228 CHECK_REMAPPING_POSITION (position); | |
2229 | |
2230 /* Get keymaps as an array */ | |
2231 if (NILP (keymaps) || !NILP (position)) | |
2232 { | |
2233 nmaps = get_relevant_keymaps (Qnil, position, maps_count, gubbish); | |
2234 } | |
2235 else | |
2236 { | |
2237 jj = 0; | |
2238 nmaps = XFIXNUM (Flength (keymaps)); | |
2239 if (nmaps > maps_count) | |
2240 { | |
2241 gubbish = alloca_array (Lisp_Object, nmaps); | |
2242 } | |
2243 | |
2244 { | |
2245 LIST_LOOP_2 (elt, keymaps) | |
2246 { | |
2247 gubbish[jj++] = elt; | |
2248 } | |
2249 } | |
2250 } | |
2251 | |
2252 if (nmaps > maps_count) | |
2253 { | |
2254 gubbish = alloca_array (Lisp_Object, nmaps); | |
2255 nmaps = get_relevant_keymaps (Qnil, position, nmaps, gubbish); | |
2256 } | |
2257 | |
2258 GCPRO1 (closure.result); | |
2259 | |
2260 for (jj = 0; jj < nmaps; jj++) | |
2261 { | |
2262 traverse_keymaps (maps[jj], Qnil, commands_remapped_to_traverser, | |
2263 (void *) (&closure)); | |
2264 } | |
2265 | |
2266 RETURN_UNGCPRO (closure.result); | |
2267 } | |
2040 | 2268 |
2041 /************************************************************************/ | 2269 /************************************************************************/ |
2042 /* Looking up keys in keymaps */ | 2270 /* Looking up keys in keymaps */ |
2043 /************************************************************************/ | 2271 /************************************************************************/ |
2044 | 2272 |
2316 closure->gcpro->nvars = nmaps; | 2544 closure->gcpro->nvars = nmaps; |
2317 } | 2545 } |
2318 } | 2546 } |
2319 | 2547 |
2320 static int | 2548 static int |
2321 get_relevant_keymaps (Lisp_Object keys, | 2549 get_relevant_keymaps (Lisp_Object keys, Lisp_Object position, int max_maps, |
2322 int max_maps, Lisp_Object maps[]) | 2550 Lisp_Object maps[]) |
2323 { | 2551 { |
2324 /* This function can GC */ | 2552 /* This function can GC */ |
2325 Lisp_Object terminal = Qnil; | 2553 Lisp_Object terminal = Qnil; |
2326 struct gcpro gcpro1; | 2554 struct gcpro gcpro1; |
2327 struct relevant_maps closure; | 2555 struct relevant_maps closure; |
2461 if (!UNBOUNDP (map) && !NILP (map)) | 2689 if (!UNBOUNDP (map) && !NILP (map)) |
2462 relevant_map_push (map, &closure); | 2690 relevant_map_push (map, &closure); |
2463 } | 2691 } |
2464 } | 2692 } |
2465 #endif /* HAVE_WINDOW_SYSTEM */ | 2693 #endif /* HAVE_WINDOW_SYSTEM */ |
2694 | |
2695 if (FIXNUMP (position)) | |
2696 { | |
2697 get_relevant_extent_keymaps (position, wrap_buffer (current_buffer), | |
2698 Qnil, &closure); | |
2699 } | |
2700 else if (MARKERP (position) && !NILP (Fmarker_buffer (position))) | |
2701 { | |
2702 get_relevant_extent_keymaps (Fmarker_position (position), | |
2703 Fmarker_buffer (position), | |
2704 Qnil, &closure); | |
2705 } | |
2706 else if (EVENTP (position)) | |
2707 { | |
2708 Lisp_Object ew = Fevent_window (position); | |
2709 | |
2710 get_relevant_extent_keymaps (Fevent_point (position), | |
2711 WINDOWP (ew) ? | |
2712 Fwindow_buffer (Fevent_window (position)) | |
2713 : Qnil, Qnil, &closure); | |
2714 } | |
2715 else | |
2716 { | |
2717 assert (NILP (position)); | |
2718 } | |
2466 | 2719 |
2467 if (CONSOLE_TTY_P (con)) | 2720 if (CONSOLE_TTY_P (con)) |
2468 relevant_map_push (Vglobal_tty_map, &closure); | 2721 relevant_map_push (Vglobal_tty_map, &closure); |
2469 else | 2722 else |
2470 relevant_map_push (Vglobal_window_system_map, &closure); | 2723 relevant_map_push (Vglobal_window_system_map, &closure); |
2578 Lisp_Object maps[100]; | 2831 Lisp_Object maps[100]; |
2579 Lisp_Object *gubbish = maps; | 2832 Lisp_Object *gubbish = maps; |
2580 int nmaps; | 2833 int nmaps; |
2581 | 2834 |
2582 GCPRO1 (event_or_keys); | 2835 GCPRO1 (event_or_keys); |
2583 nmaps = get_relevant_keymaps (event_or_keys, countof (maps), | 2836 nmaps = get_relevant_keymaps (event_or_keys, Qnil, countof (maps), |
2584 gubbish); | 2837 gubbish); |
2585 if (nmaps > countof (maps)) | 2838 if (nmaps > countof (maps)) |
2586 { | 2839 { |
2587 gubbish = alloca_array (Lisp_Object, nmaps); | 2840 gubbish = alloca_array (Lisp_Object, nmaps); |
2588 nmaps = get_relevant_keymaps (event_or_keys, nmaps, gubbish); | 2841 nmaps = get_relevant_keymaps (event_or_keys, Qnil, nmaps, gubbish); |
2589 } | 2842 } |
2590 UNGCPRO; | 2843 UNGCPRO; |
2591 return Flist (nmaps, gubbish); | 2844 return Flist (nmaps, gubbish); |
2592 } | 2845 } |
2593 | 2846 |
2594 DEFUN ("key-binding", Fkey_binding, 1, 2, 0, /* | 2847 DEFUN ("key-binding", Fkey_binding, 1, 4, 0, /* |
2595 Return the binding for command KEYS in current keymaps. | 2848 Return the binding for command KEYS in current keymaps. |
2849 | |
2596 KEYS is a string, a vector of events, or a vector of key-description lists | 2850 KEYS is a string, a vector of events, or a vector of key-description lists |
2597 as described in the documentation for the `define-key' function. | 2851 as described in the documentation for the `define-key' function. |
2598 The binding is probably a symbol with a function definition; see | 2852 |
2599 the documentation for `lookup-key' for more information. | 2853 NO-REMAP, if non-nil, specifies that any substitutions that have been |
2854 specified by `remap-command' (or, equivalently, by `(define-key KEYMAP | |
2855 \[remap OLD] NEW)') should be ignored. | |
2856 | |
2857 POSITION, if non-nil, specifies a marker (and its associated buffer) or an | |
2858 integer position (in the current buffer) to examine for relevant keymaps. | |
2859 It can also be an event, in which case the associated buffer and position of | |
2860 that event will be used. | |
2861 | |
2862 The binding is probably a symbol with a function definition; see the | |
2863 documentation for `lookup-key' for more information. | |
2600 | 2864 |
2601 For key-presses, the order of keymaps searched is: | 2865 For key-presses, the order of keymaps searched is: |
2602 - the `keymap' property of any extent(s) at point; | 2866 - the `keymap' property of any extent(s) at point; |
2603 - any applicable minor-mode maps; | 2867 - any applicable minor-mode maps; |
2604 - the current local map of the current-buffer; | 2868 - the current local map of the current-buffer; |
2648 on the keycaps. (Not yet implemented) | 2912 on the keycaps. (Not yet implemented) |
2649 -- Finally, if the last keystroke matches `help-char', we automatically | 2913 -- Finally, if the last keystroke matches `help-char', we automatically |
2650 generate and display a list of possible key sequences and bindings | 2914 generate and display a list of possible key sequences and bindings |
2651 given the prefix so far generated. | 2915 given the prefix so far generated. |
2652 */ | 2916 */ |
2653 (keys, accept_default)) | 2917 (keys, accept_default, no_remap, position)) |
2654 { | 2918 { |
2655 /* This function can GC */ | 2919 /* This function can GC */ |
2656 int i; | 2920 int i; |
2657 Lisp_Object maps[100]; | 2921 Lisp_Object maps[100]; |
2658 int nmaps; | 2922 int nmaps; |
2659 struct gcpro gcpro1, gcpro2; | 2923 struct gcpro gcpro1, gcpro2; |
2660 GCPRO2 (keys, accept_default); /* get_relevant_keymaps may autoload */ | 2924 GCPRO2 (keys, accept_default); /* get_relevant_keymaps may autoload */ |
2661 | 2925 |
2662 nmaps = get_relevant_keymaps (keys, countof (maps), maps); | 2926 nmaps = get_relevant_keymaps (keys, position, countof (maps), maps); |
2663 | 2927 |
2664 UNGCPRO; | 2928 UNGCPRO; |
2665 | 2929 |
2666 if (EVENTP (keys)) /* unadvertised "feature" for the future */ | 2930 if (EVENTP (keys)) /* unadvertised "feature" for the future */ |
2667 return lookup_events (keys, nmaps, maps, !NILP (accept_default)); | 2931 return lookup_events (keys, nmaps, maps, !NILP (accept_default)); |
2668 | 2932 |
2669 for (i = 0; i < nmaps; i++) | 2933 for (i = 0; i < nmaps; i++) |
2670 { | 2934 { |
2671 Lisp_Object tem = Flookup_key (maps[i], keys, | 2935 Lisp_Object tem = Flookup_key (maps[i], keys, accept_default); |
2672 accept_default); | 2936 |
2673 if (FIXNUMP (tem)) | 2937 if (FIXNUMP (tem)) |
2674 { | 2938 { |
2675 /* Too long in some local map means don't look at global map */ | 2939 /* Too long in some local map means don't look at global map */ |
2676 return Qnil; | 2940 return Qnil; |
2677 } | 2941 } |
2678 else if (!NILP (tem)) | 2942 |
2679 return tem; | 2943 if (!NILP (tem) && NILP (no_remap) && SYMBOLP (tem)) |
2944 { | |
2945 Lisp_Object remap = command_remapping (tem, nmaps, maps); | |
2946 return NILP (remap) ? tem : remap; | |
2947 } | |
2680 } | 2948 } |
2681 return Qnil; | 2949 return Qnil; |
2682 } | 2950 } |
2683 | 2951 |
2684 static Lisp_Object | 2952 static Lisp_Object |
2722 Lisp_Object maps[100]; | 2990 Lisp_Object maps[100]; |
2723 int nmaps; | 2991 int nmaps; |
2724 | 2992 |
2725 assert (EVENTP (event0)); | 2993 assert (EVENTP (event0)); |
2726 | 2994 |
2727 nmaps = get_relevant_keymaps (event0, countof (maps), maps); | 2995 nmaps = get_relevant_keymaps (event0, Qnil, countof (maps), maps); |
2728 if (nmaps > countof (maps)) | 2996 if (nmaps > countof (maps)) |
2729 nmaps = countof (maps); | 2997 nmaps = countof (maps); |
2730 return process_event_binding_result (lookup_events (event0, nmaps, maps, | 2998 return process_event_binding_result (lookup_events (event0, nmaps, maps, |
2731 accept_default)); | 2999 accept_default)); |
2732 } | 3000 } |
3022 void *function) | 3290 void *function) |
3023 { | 3291 { |
3024 /* This function can GC */ | 3292 /* This function can GC */ |
3025 Lisp_Object fn; | 3293 Lisp_Object fn; |
3026 fn = GET_LISP_FROM_VOID (function); | 3294 fn = GET_LISP_FROM_VOID (function); |
3295 | |
3296 /* Don't expose our remapping here. */ | |
3297 if (EQ (KEY_DATA_KEYSYM (key), Qxemacs_command_remapping)) | |
3298 { | |
3299 return; | |
3300 } | |
3301 | |
3027 call2 (fn, make_key_description (key, 1), binding); | 3302 call2 (fn, make_key_description (key, 1), binding); |
3028 } | 3303 } |
3029 | 3304 |
3030 | 3305 |
3031 static void | 3306 static void |
3481 int nmaps; | 3756 int nmaps; |
3482 | 3757 |
3483 /* Get keymaps as an array */ | 3758 /* Get keymaps as an array */ |
3484 if (NILP (keymaps)) | 3759 if (NILP (keymaps)) |
3485 { | 3760 { |
3486 nmaps = get_relevant_keymaps (event_or_keys, countof (maps), | 3761 nmaps = get_relevant_keymaps (event_or_keys, Qnil, countof (maps), |
3487 gubbish); | 3762 gubbish); |
3488 if (nmaps > countof (maps)) | 3763 if (nmaps > countof (maps)) |
3489 { | 3764 { |
3490 gubbish = alloca_array (Lisp_Object, nmaps); | 3765 gubbish = alloca_array (Lisp_Object, nmaps); |
3491 nmaps = get_relevant_keymaps (event_or_keys, nmaps, gubbish); | 3766 nmaps = get_relevant_keymaps (event_or_keys, Qnil, nmaps, gubbish); |
3492 } | 3767 } |
3493 } | 3768 } |
3494 else if (CONSP (keymaps)) | 3769 else if (CONSP (keymaps)) |
3495 { | 3770 { |
3496 Lisp_Object rest; | 3771 Lisp_Object rest; |
3514 if (!EQ (gubbish[0], Vcurrent_global_map)) | 3789 if (!EQ (gubbish[0], Vcurrent_global_map)) |
3515 { | 3790 { |
3516 gubbish[1] = Vcurrent_global_map; | 3791 gubbish[1] = Vcurrent_global_map; |
3517 nmaps++; | 3792 nmaps++; |
3518 } | 3793 } |
3794 } | |
3795 | |
3796 if (!NILP (command_remapping (definition, nmaps, gubbish))) | |
3797 { | |
3798 return Qnil; | |
3519 } | 3799 } |
3520 | 3800 |
3521 return where_is_internal (definition, gubbish, nmaps, firstonly, 0); | 3801 return where_is_internal (definition, gubbish, nmaps, firstonly, 0); |
3522 } | 3802 } |
3523 | 3803 |
3534 Lisp_Object maps[100]; | 3814 Lisp_Object maps[100]; |
3535 Lisp_Object *gubbish = maps; | 3815 Lisp_Object *gubbish = maps; |
3536 int nmaps; | 3816 int nmaps; |
3537 | 3817 |
3538 /* Get keymaps as an array */ | 3818 /* Get keymaps as an array */ |
3539 nmaps = get_relevant_keymaps (Qnil, countof (maps), gubbish); | 3819 nmaps = get_relevant_keymaps (Qnil, Qnil, countof (maps), gubbish); |
3540 if (nmaps > countof (maps)) | 3820 if (nmaps > countof (maps)) |
3541 { | 3821 { |
3542 gubbish = alloca_array (Lisp_Object, nmaps); | 3822 gubbish = alloca_array (Lisp_Object, nmaps); |
3543 nmaps = get_relevant_keymaps (Qnil, nmaps, gubbish); | 3823 nmaps = get_relevant_keymaps (Qnil, Qnil, nmaps, gubbish); |
3544 } | 3824 } |
3545 | 3825 |
3546 where_is_internal (definition, maps, nmaps, Qt, buffer); | 3826 where_is_internal (definition, maps, nmaps, Qt, buffer); |
3547 } | 3827 } |
3548 | 3828 |
3711 if (NILP (submap)) | 3991 if (NILP (submap)) |
3712 { | 3992 { |
3713 XKEYMAP (map)->sub_maps_cache = Qt; | 3993 XKEYMAP (map)->sub_maps_cache = Qt; |
3714 continue; | 3994 continue; |
3715 } | 3995 } |
3996 | |
3997 /* Don't expose the command remapping to #'where-is-internal */ | |
3998 if (EQ (key, Qxemacs_command_remapping)) | |
3999 { | |
4000 continue; | |
4001 } | |
3716 | 4002 |
3717 /* If the map is a "bucky" map, then add a bit to the | 4003 /* If the map is a "bucky" map, then add a bit to the |
3718 modifiers_so_far list. | 4004 modifiers_so_far list. |
3719 Otherwise, add a new raw_key onto the end of keys_so_far. | 4005 Otherwise, add a new raw_key onto the end of keys_so_far. |
3720 */ | 4006 */ |
4305 | 4591 |
4306 DEFSYMBOL (Qsuppress_keymap); | 4592 DEFSYMBOL (Qsuppress_keymap); |
4307 | 4593 |
4308 DEFSYMBOL (Qmodeline_map); | 4594 DEFSYMBOL (Qmodeline_map); |
4309 DEFSYMBOL (Qtoolbar_map); | 4595 DEFSYMBOL (Qtoolbar_map); |
4596 DEFSYMBOL (Qremap); | |
4310 | 4597 |
4311 DEFSUBR (Fkeymap_parents); | 4598 DEFSUBR (Fkeymap_parents); |
4312 DEFSUBR (Fset_keymap_parents); | 4599 DEFSUBR (Fset_keymap_parents); |
4313 DEFSUBR (Fkeymap_name); | 4600 DEFSUBR (Fkeymap_name); |
4314 DEFSUBR (Fset_keymap_name); | 4601 DEFSUBR (Fset_keymap_name); |
4324 DEFSUBR (Fcopy_keymap); | 4611 DEFSUBR (Fcopy_keymap); |
4325 DEFSUBR (Fkeymap_fullness); | 4612 DEFSUBR (Fkeymap_fullness); |
4326 DEFSUBR (Fmap_keymap); | 4613 DEFSUBR (Fmap_keymap); |
4327 DEFSUBR (Fevent_matches_key_specifier_p); | 4614 DEFSUBR (Fevent_matches_key_specifier_p); |
4328 DEFSUBR (Fdefine_key); | 4615 DEFSUBR (Fdefine_key); |
4616 DEFSUBR (Fremap_command); | |
4617 DEFSUBR (Fcommands_remapped_to); | |
4618 DEFSUBR (Fcommand_remapping); | |
4329 DEFSUBR (Flookup_key); | 4619 DEFSUBR (Flookup_key); |
4330 DEFSUBR (Fkey_binding); | 4620 DEFSUBR (Fkey_binding); |
4331 DEFSUBR (Fuse_global_map); | 4621 DEFSUBR (Fuse_global_map); |
4332 DEFSUBR (Fuse_local_map); | 4622 DEFSUBR (Fuse_local_map); |
4333 DEFSUBR (Fcurrent_local_map); | 4623 DEFSUBR (Fcurrent_local_map); |
4453 | 4743 |
4454 staticpro (&Vcurrent_global_map); | 4744 staticpro (&Vcurrent_global_map); |
4455 | 4745 |
4456 Vsingle_space_string = make_string ((const Ibyte *) " ", 1); | 4746 Vsingle_space_string = make_string ((const Ibyte *) " ", 1); |
4457 staticpro (&Vsingle_space_string); | 4747 staticpro (&Vsingle_space_string); |
4748 | |
4749 Qxemacs_command_remapping | |
4750 = Fmake_symbol (build_ascstring ("xemacs-command-remapping")); | |
4751 staticpro (&Qxemacs_command_remapping); | |
4458 } | 4752 } |
4459 | 4753 |
4460 void | 4754 void |
4461 complex_vars_of_keymap (void) | 4755 complex_vars_of_keymap (void) |
4462 { | 4756 { |