Mercurial > hg > xemacs-beta
comparison src/keymap.c @ 0:376386a54a3c r19-14
Import from CVS: tag r19-14
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:45:50 +0200 |
parents | |
children | ac2d302a0011 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:376386a54a3c |
---|---|
1 /* Manipulation of keymaps | |
2 Copyright (C) 1985, 1991-1995 Free Software Foundation, Inc. | |
3 Copyright (C) 1995 Board of Trustees, University of Illinois. | |
4 Copyright (C) 1995 Sun Microsystems, Inc. | |
5 Totally redesigned by jwz in 1991. | |
6 | |
7 This file is part of XEmacs. | |
8 | |
9 XEmacs is free software; you can redistribute it and/or modify it | |
10 under the terms of the GNU General Public License as published by the | |
11 Free Software Foundation; either version 2, or (at your option) any | |
12 later version. | |
13 | |
14 XEmacs is distributed in the hope that it will be useful, but WITHOUT | |
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
16 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 for more details. | |
18 | |
19 You should have received a copy of the GNU General Public License | |
20 along with XEmacs; see the file COPYING. If not, write to | |
21 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
22 Boston, MA 02111-1307, USA. */ | |
23 | |
24 /* Synched up with: Not synched with FSF. Substantially different | |
25 from FSF. */ | |
26 | |
27 #include <config.h> | |
28 #include "lisp.h" | |
29 | |
30 #include "buffer.h" | |
31 #include "bytecode.h" | |
32 #include "commands.h" | |
33 #include "console.h" | |
34 #include "elhash.h" | |
35 #include "events.h" | |
36 #include "frame.h" | |
37 #include "insdel.h" | |
38 #include "keymap.h" | |
39 #include "window.h" | |
40 | |
41 | |
42 /* A keymap contains four slots: | |
43 | |
44 parents Ordered list of keymaps to search after | |
45 this one if no match is found. | |
46 Keymaps can thus be arranged in a hierarchy. | |
47 | |
48 table A hash table, hashing keysyms to their bindings. | |
49 As in the rest of emacs, a keysym is either a symbol or | |
50 an integer, which is an ASCII code (of one of the printing | |
51 ASCII characters: not 003 meaning C-c, for instance). | |
52 It can also be an integer representing a modifier | |
53 combination; this will be greater than or equal to | |
54 (1 << 16). | |
55 | |
56 inverse_table A hash table, hashing bindings to the list of keysyms | |
57 in this keymap which are bound to them. This is to make | |
58 the Fwhere_is_internal() function be fast. It needs to be | |
59 fast because we want to be able to call it in realtime to | |
60 update the keyboard-equivalents on the pulldown menus. | |
61 Values of the table are either atoms (keysyms) | |
62 or a dotted list of keysyms. | |
63 | |
64 sub_maps_cache An alist; for each entry in this keymap whose binding is | |
65 a keymap (that is, Fkeymapp()) this alist associates that | |
66 keysym with that binding. This is used to optimize both | |
67 Fwhere_is_internal() and Faccessible_keymaps(). This slot | |
68 gets set to the symbol `t' every time a change is made to | |
69 this keymap, causing it to be recomputed when next needed. | |
70 | |
71 prompt See `set-keymap-prompt'. | |
72 | |
73 default_binding See `set-keymap-default-binding'. | |
74 | |
75 Sequences of keys are stored in the obvious way: if the sequence of keys | |
76 "abc" was bound to some command `foo', the hierarchy would look like | |
77 | |
78 keymap-1: associates "a" with keymap-2 | |
79 keymap-2: associates "b" with keymap-3 | |
80 keymap-3: associates "c" with foo | |
81 | |
82 However, bucky bits ("modifiers" to the X-minded) are represented in the | |
83 keymap hierarchy as well. (This lets us use EQable objects as hash keys.) | |
84 Each combination of modifiers (e.g. control-hyper) gets its own submap | |
85 off of the main map. The hash key for a modifier combination is | |
86 a large integer, computed by MAKE_MODIFIER_HASH_KEY(). | |
87 | |
88 If the key `C-a' was bound to some command, the hierarchy would look like | |
89 | |
90 keymap-1: associates the integer (MOD_CONTROL << 16) with keymap-2 | |
91 keymap-2: associates "a" with the command | |
92 | |
93 Similarly, if the key `C-H-a' was bound to some command, the hierarchy | |
94 would look like | |
95 | |
96 keymap-1: associates the integer ((MOD_CONTROL | MOD_HYPER) << 16) | |
97 with keymap-2 | |
98 keymap-2: associates "a" with the command | |
99 | |
100 Note that a special exception is made for the meta modifier, in order | |
101 to deal with ESC/meta lossage. Any key combination containing the | |
102 meta modifier is first indexed off of the main map into the meta | |
103 submap (with hash key (MOD_META << 16)) and then indexed off of the | |
104 meta submap with the meta modifier removed from the key combination. | |
105 For example, when associating a command with C-M-H-a, we'd have | |
106 | |
107 keymap-1: associates the integer (MOD_META << 16) with keymap-2 | |
108 keymap-2: associates the integer ((MOD_CONTROL | MOD_HYPER) << 16) | |
109 with keymap-3 | |
110 keymap-3: associates "a" with the command | |
111 | |
112 Note that keymap-2 might have normal bindings in it; these would be | |
113 for key combinations containing only the meta modifier, such as | |
114 M-y or meta-backspace. | |
115 | |
116 If the command that "a" was bound to in keymap-3 was itself a keymap, | |
117 then that would make the key "C-M-H-a" be a prefix character. | |
118 | |
119 Note that this new model of keymaps takes much of the magic away from | |
120 the Escape key: the value of the variable `esc-map' is no longer indexed | |
121 in the `global-map' under the ESC key. It's indexed under the integer | |
122 (MOD_META << 16). This is not user-visible, however; none of the "bucky" | |
123 maps are. | |
124 | |
125 There is a hack in Flookup_key() that makes (lookup-key global-map "\^[") | |
126 and (define-key some-random-map "\^[" my-esc-map) work as before, for | |
127 compatibility. | |
128 | |
129 Since keymaps are opaque, the only way to extract information from them | |
130 is with the functions lookup-key, key-binding, local-key-binding, and | |
131 global-key-binding, which work just as before, and the new function | |
132 map-keymap, which is roughly analagous to maphash. | |
133 | |
134 Note that map-keymap perpetuates the illusion that the "bucky" submaps | |
135 don't exist: if you map over a keymap with bucky submaps, it will also | |
136 map over those submaps. It does not, however, map over other random | |
137 submaps of the keymap, just the bucky ones. | |
138 | |
139 One implication of this is that when you map over `global-map', you will | |
140 also map over `esc-map'. It is merely for compatibility that the esc-map | |
141 is accessible at all; I think that's a bad thing, since it blurs the | |
142 distinction between ESC and "meta" even more. "M-x" is no more a two- | |
143 key sequence than "C-x" is. | |
144 | |
145 */ | |
146 | |
147 struct keymap | |
148 { | |
149 struct lcrecord_header header; | |
150 Lisp_Object parents; /* Keymaps to be searched after this one | |
151 * An ordered list */ | |
152 Lisp_Object prompt; /* Qnil or a string to print in the minibuffer | |
153 * when reading from this keymap */ | |
154 | |
155 Lisp_Object table; /* The contents of this keymap */ | |
156 Lisp_Object inverse_table; /* The inverse mapping of the above */ | |
157 | |
158 Lisp_Object default_binding; /* Use this if no other binding is found | |
159 * (this overrides parent maps and the | |
160 * normal global-map lookup). */ | |
161 | |
162 | |
163 Lisp_Object sub_maps_cache; /* Cache of directly inferior keymaps; | |
164 This holds an alist, of the key and the | |
165 maps, or the modifier bit and the map. | |
166 If this is the symbol t, then the cache | |
167 needs to be recomputed. | |
168 */ | |
169 int fullness; /* How many entries there are in this table. | |
170 This should be the same as the fullness | |
171 of the `table', but hash.c is broken. */ | |
172 Lisp_Object name; /* Just for debugging convenience */ | |
173 }; | |
174 | |
175 #define XKEYMAP(x) XRECORD (x, keymap, struct keymap) | |
176 #define XSETKEYMAP(x, p) XSETRECORD (x, p, keymap) | |
177 #define KEYMAPP(x) RECORDP (x, keymap) | |
178 #define CHECK_KEYMAP(x) CHECK_RECORD (x, keymap) | |
179 | |
180 /* Hash key is shifted so it can't conflict with eight-bit | |
181 string-char constituents */ | |
182 #define MAKE_MODIFIER_HASH_KEY(modifier) (make_int ((modifier) << 16)) | |
183 #define MODIFIER_HASH_KEY_BITS(x) ((INTP((x))) ? (XINT ((x)) >> 16) : 0) | |
184 | |
185 | |
186 | |
187 /* Actually allocate storage for these variables */ | |
188 | |
189 static Lisp_Object Vcurrent_global_map; /* Always a keymap */ | |
190 | |
191 static Lisp_Object Vmouse_grabbed_buffer; | |
192 | |
193 /* Alist of minor mode variables and keymaps. */ | |
194 static Lisp_Object Qminor_mode_map_alist; | |
195 | |
196 static Lisp_Object Voverriding_local_map; | |
197 | |
198 static Lisp_Object Vkey_translation_map; | |
199 | |
200 /* This is incremented whenever a change is made to a keymap. This is | |
201 so that things which care (such as the menubar code) can recompute | |
202 privately-cached data when the user has changed keybindings. | |
203 */ | |
204 int keymap_tick; | |
205 | |
206 /* Prefixing a key with this character is the same as sending a meta bit. */ | |
207 Lisp_Object Vmeta_prefix_char; | |
208 | |
209 Lisp_Object Qkeymapp; | |
210 | |
211 Lisp_Object Vsingle_space_string; | |
212 | |
213 Lisp_Object Qsuppress_keymap; | |
214 | |
215 Lisp_Object Qmodeline_map; | |
216 Lisp_Object Qtoolbar_map; | |
217 | |
218 static void describe_command (Lisp_Object definition); | |
219 static void describe_map (Lisp_Object keymap, Lisp_Object elt_prefix, | |
220 void (*elt_describer) (Lisp_Object), | |
221 int partial, | |
222 Lisp_Object shadow, | |
223 int mice_only_p); | |
224 Lisp_Object Qcontrol, Qctrl, Qmeta, Qsuper, Qhyper, Qalt, Qshift; | |
225 /* Lisp_Object Qsymbol; defined in general.c */ | |
226 Lisp_Object Qbutton0, Qbutton1, Qbutton2, Qbutton3, Qbutton4, Qbutton5, | |
227 Qbutton6, Qbutton7; | |
228 Lisp_Object Qbutton0up, Qbutton1up, Qbutton2up, Qbutton3up, Qbutton4up, | |
229 Qbutton5up, Qbutton6up, Qbutton7up; | |
230 Lisp_Object Qmenu_selection; | |
231 | |
232 /* Kludge kludge kludge */ | |
233 Lisp_Object QLFD, QTAB, QRET, QESC, QDEL, QSPC, QBS; | |
234 | |
235 | |
236 /************************************************************************/ | |
237 /* The keymap Lisp object */ | |
238 /************************************************************************/ | |
239 | |
240 static Lisp_Object mark_keymap (Lisp_Object, void (*) (Lisp_Object)); | |
241 static void print_keymap (Lisp_Object, Lisp_Object, int); | |
242 /* No need for keymap_equal #### Why not? */ | |
243 DEFINE_LRECORD_IMPLEMENTATION ("keymap", keymap, | |
244 mark_keymap, print_keymap, 0, 0, 0, | |
245 struct keymap); | |
246 static Lisp_Object | |
247 mark_keymap (Lisp_Object obj, void (*markobj) (Lisp_Object)) | |
248 { | |
249 struct keymap *keymap = XKEYMAP (obj); | |
250 ((markobj) (keymap->parents)); | |
251 ((markobj) (keymap->prompt)); | |
252 ((markobj) (keymap->inverse_table)); | |
253 ((markobj) (keymap->sub_maps_cache)); | |
254 ((markobj) (keymap->default_binding)); | |
255 ((markobj) (keymap->name)); | |
256 return (keymap->table); | |
257 } | |
258 | |
259 static void | |
260 print_keymap (Lisp_Object obj, Lisp_Object printcharfun, int escapeflag) | |
261 { | |
262 /* This function can GC */ | |
263 struct keymap *keymap = XKEYMAP (obj); | |
264 char buf[200]; | |
265 int size = XINT (Fkeymap_fullness (obj)); | |
266 if (print_readably) | |
267 error ("printing unreadable object #<keymap 0x%x>", keymap->header.uid); | |
268 write_c_string ("#<keymap ", printcharfun); | |
269 if (!NILP (keymap->name)) | |
270 print_internal (keymap->name, printcharfun, 1); | |
271 sprintf (buf, "%s%d entr%s 0x%x>", | |
272 ((NILP (keymap->name)) ? "" : " "), | |
273 size, | |
274 ((size == 1) ? "y" : "ies"), | |
275 keymap->header.uid); | |
276 write_c_string (buf, printcharfun); | |
277 } | |
278 | |
279 | |
280 /************************************************************************/ | |
281 /* Traversing keymaps and their parents */ | |
282 /************************************************************************/ | |
283 | |
284 static Lisp_Object | |
285 traverse_keymaps (Lisp_Object start_keymap, Lisp_Object start_parents, | |
286 Lisp_Object (*mapper) (Lisp_Object keymap, void *mapper_arg), | |
287 void *mapper_arg) | |
288 { | |
289 /* This function can GC */ | |
290 Lisp_Object keymap; | |
291 Lisp_Object tail = start_parents; | |
292 Lisp_Object malloc_sucks[10]; | |
293 Lisp_Object malloc_bites = Qnil; | |
294 int stack_depth = 0; | |
295 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | |
296 GCPRO4 (*malloc_sucks, malloc_bites, start_keymap, tail); | |
297 gcpro1.nvars = 0; | |
298 | |
299 start_keymap = get_keymap (start_keymap, 1, 1); | |
300 keymap = start_keymap; | |
301 /* Hack special-case parents at top-level */ | |
302 tail = ((!NILP (tail)) ? tail : XKEYMAP (keymap)->parents); | |
303 | |
304 for (;;) | |
305 { | |
306 Lisp_Object result; | |
307 | |
308 QUIT; | |
309 result = ((mapper) (keymap, mapper_arg)); | |
310 if (!NILP (result)) | |
311 { | |
312 while (CONSP (malloc_bites)) | |
313 { | |
314 struct Lisp_Cons *victim = XCONS (malloc_bites); | |
315 malloc_bites = victim->cdr; | |
316 free_cons (victim); | |
317 } | |
318 UNGCPRO; | |
319 return (result); | |
320 } | |
321 if (NILP (tail)) | |
322 { | |
323 if (stack_depth == 0) | |
324 { | |
325 UNGCPRO; | |
326 return (Qnil); /* Nothing found */ | |
327 } | |
328 stack_depth--; | |
329 if (CONSP (malloc_bites)) | |
330 { | |
331 struct Lisp_Cons *victim = XCONS (malloc_bites); | |
332 tail = victim->car; | |
333 malloc_bites = victim->cdr; | |
334 free_cons (victim); | |
335 } | |
336 else | |
337 { | |
338 tail = malloc_sucks[stack_depth]; | |
339 gcpro1.nvars = stack_depth; | |
340 } | |
341 keymap = XCAR (tail); | |
342 tail = XCDR (tail); | |
343 } | |
344 else | |
345 { | |
346 Lisp_Object parents; | |
347 | |
348 keymap = XCAR (tail); | |
349 tail = XCDR (tail); | |
350 parents = XKEYMAP (keymap)->parents; | |
351 if (!CONSP (parents)) | |
352 ; | |
353 else if (NILP (tail)) | |
354 /* Tail-recurse */ | |
355 tail = parents; | |
356 else | |
357 { | |
358 if (CONSP (malloc_bites)) | |
359 malloc_bites = noseeum_cons (tail, malloc_bites); | |
360 else if (stack_depth < countof (malloc_sucks)) | |
361 { | |
362 malloc_sucks[stack_depth++] = tail; | |
363 gcpro1.nvars = stack_depth; | |
364 } | |
365 else | |
366 { | |
367 /* *&@##[*&^$ C. @#[$*&@# Unix. Losers all. */ | |
368 int i; | |
369 for (i = 0, malloc_bites = Qnil; | |
370 i < countof (malloc_sucks); | |
371 i++) | |
372 malloc_bites = noseeum_cons (malloc_sucks[i], | |
373 malloc_bites); | |
374 gcpro1.nvars = 0; | |
375 } | |
376 tail = parents; | |
377 } | |
378 } | |
379 keymap = get_keymap (keymap, 1, 1); | |
380 if (EQ (keymap, start_keymap)) | |
381 { | |
382 signal_simple_error ("Cyclic keymap indirection", | |
383 start_keymap); | |
384 } | |
385 } | |
386 } | |
387 | |
388 | |
389 /************************************************************************/ | |
390 /* Some low-level functions */ | |
391 /************************************************************************/ | |
392 | |
393 static unsigned int | |
394 bucky_sym_to_bucky_bit (Lisp_Object sym) | |
395 { | |
396 if (EQ (sym, Qcontrol)) | |
397 return MOD_CONTROL; | |
398 else if (EQ (sym, Qmeta)) | |
399 return MOD_META; | |
400 else if (EQ (sym, Qsuper)) | |
401 return MOD_SUPER; | |
402 else if (EQ (sym, Qhyper)) | |
403 return MOD_HYPER; | |
404 else if (EQ (sym, Qalt) || EQ (sym, Qsymbol)) /* #### - reverse compat */ | |
405 return MOD_ALT; | |
406 else if (EQ (sym, Qshift)) | |
407 return MOD_SHIFT; | |
408 else | |
409 return 0; | |
410 } | |
411 | |
412 static Lisp_Object | |
413 control_meta_superify (Lisp_Object frob, unsigned int modifiers) | |
414 { | |
415 if (modifiers == 0) | |
416 return frob; | |
417 frob = Fcons (frob, Qnil); | |
418 if (modifiers & MOD_SHIFT) | |
419 frob = Fcons (Qshift, frob); | |
420 if (modifiers & MOD_ALT) | |
421 frob = Fcons (Qalt, frob); | |
422 if (modifiers & MOD_HYPER) | |
423 frob = Fcons (Qhyper, frob); | |
424 if (modifiers & MOD_SUPER) | |
425 frob = Fcons (Qsuper, frob); | |
426 if (modifiers & MOD_CONTROL) | |
427 frob = Fcons (Qcontrol, frob); | |
428 if (modifiers & MOD_META) | |
429 frob = Fcons (Qmeta, frob); | |
430 return (frob); | |
431 } | |
432 | |
433 static Lisp_Object | |
434 make_key_description (CONST struct key_data *key, int prettify) | |
435 { | |
436 Lisp_Object keysym = key->keysym; | |
437 unsigned int modifiers = key->modifiers; | |
438 | |
439 if (prettify && INTP (keysym)) | |
440 { | |
441 /* This is a little slow, but (control a) is prettier than (control 65). | |
442 It's now ok to do this for digit-chars too, since we've fixed the | |
443 bug where \9 read as the integer 9 instead of as the symbol with | |
444 "9" as its name. | |
445 */ | |
446 /* !!#### I'm not sure how correct this is. */ | |
447 Bufbyte str [1 + MAX_EMCHAR_LEN]; | |
448 Bytecount count = set_charptr_emchar (str, XCHAR (keysym)); | |
449 str[count] = 0; | |
450 keysym = intern ((char *) str); | |
451 } | |
452 return (control_meta_superify (keysym, modifiers)); | |
453 } | |
454 | |
455 | |
456 /************************************************************************/ | |
457 /* Low-level keymap-store functions */ | |
458 /************************************************************************/ | |
459 | |
460 static Lisp_Object | |
461 raw_lookup_key (Lisp_Object keymap, | |
462 CONST struct key_data *raw_keys, int raw_keys_count, | |
463 int keys_so_far, int accept_default); | |
464 | |
465 /* Relies on caller to gc-protect args */ | |
466 static Lisp_Object | |
467 keymap_lookup_directly (Lisp_Object keymap, | |
468 Lisp_Object keysym, unsigned int modifiers) | |
469 { | |
470 struct keymap *k; | |
471 | |
472 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER | |
473 | MOD_ALT | MOD_SHIFT)) != 0) | |
474 abort (); | |
475 | |
476 k = XKEYMAP (keymap); | |
477 | |
478 /* If the keysym is a one-character symbol, use the char code instead. */ | |
479 if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1) | |
480 { | |
481 Lisp_Object i_fart_on_gcc = | |
482 make_char (string_char (XSYMBOL (keysym)->name, 0)); | |
483 keysym = i_fart_on_gcc; | |
484 } | |
485 | |
486 if (modifiers & MOD_META) /* Utterly hateful ESC lossage */ | |
487 { | |
488 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META), | |
489 k->table, Qnil); | |
490 if (NILP (submap)) | |
491 return (Qnil); | |
492 k = XKEYMAP (submap); | |
493 modifiers &= ~MOD_META; | |
494 } | |
495 | |
496 if (modifiers != 0) | |
497 { | |
498 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (modifiers), | |
499 k->table, Qnil); | |
500 if (NILP (submap)) | |
501 return (Qnil); | |
502 k = XKEYMAP (submap); | |
503 } | |
504 return (Fgethash (keysym, k->table, Qnil)); | |
505 } | |
506 | |
507 static void | |
508 keymap_store_inverse_internal (Lisp_Object inverse_table, | |
509 Lisp_Object keysym, | |
510 Lisp_Object value) | |
511 { | |
512 Lisp_Object keys = Fgethash (value, inverse_table, Qunbound); | |
513 | |
514 if (UNBOUNDP (keys)) | |
515 { | |
516 keys = keysym; | |
517 /* Don't cons this unless necessary */ | |
518 /* keys = Fcons (keysym, Qnil); */ | |
519 Fputhash (value, keys, inverse_table); | |
520 } | |
521 | |
522 else if (!CONSP (keys)) | |
523 { | |
524 /* Now it's necessary to cons */ | |
525 keys = Fcons (keys, keysym); | |
526 Fputhash (value, keys, inverse_table); | |
527 } | |
528 else | |
529 { | |
530 while (CONSP (Fcdr (keys))) | |
531 keys = XCDR (keys); | |
532 XCDR (keys) = Fcons (XCDR (keys), keysym); | |
533 /* No need to call puthash because we've destructively | |
534 modified the list tail in place */ | |
535 } | |
536 } | |
537 | |
538 | |
539 static void | |
540 keymap_delete_inverse_internal (Lisp_Object inverse_table, | |
541 Lisp_Object keysym, | |
542 Lisp_Object value) | |
543 { | |
544 Lisp_Object keys = Fgethash (value, inverse_table, Qunbound); | |
545 Lisp_Object new_keys = keys; | |
546 Lisp_Object tail; | |
547 Lisp_Object *prev; | |
548 | |
549 if (UNBOUNDP (keys)) | |
550 abort (); | |
551 | |
552 for (prev = &new_keys, tail = new_keys; | |
553 ; | |
554 prev = &(XCDR (tail)), tail = XCDR (tail)) | |
555 { | |
556 if (EQ (tail, keysym)) | |
557 { | |
558 *prev = Qnil; | |
559 break; | |
560 } | |
561 else if (EQ (keysym, XCAR (tail))) | |
562 { | |
563 *prev = XCDR (tail); | |
564 break; | |
565 } | |
566 } | |
567 | |
568 if (NILP (new_keys)) | |
569 Fremhash (value, inverse_table); | |
570 else if (!EQ (keys, new_keys)) | |
571 /* Removed the first elt */ | |
572 Fputhash (value, new_keys, inverse_table); | |
573 /* else the list's tail has been modified, so we don't need to | |
574 touch the hash table again (the pointer in there is ok). | |
575 */ | |
576 } | |
577 | |
578 | |
579 static void | |
580 keymap_store_internal (Lisp_Object keysym, struct keymap *keymap, | |
581 Lisp_Object value) | |
582 { | |
583 Lisp_Object prev_value = Fgethash (keysym, keymap->table, Qnil); | |
584 | |
585 if (EQ (prev_value, value)) | |
586 return; | |
587 if (!NILP (prev_value)) | |
588 keymap_delete_inverse_internal (keymap->inverse_table, | |
589 keysym, prev_value); | |
590 if (NILP (value)) | |
591 { | |
592 keymap->fullness--; | |
593 if (keymap->fullness < 0) abort (); | |
594 Fremhash (keysym, keymap->table); | |
595 } | |
596 else | |
597 { | |
598 if (NILP (prev_value)) | |
599 keymap->fullness++; | |
600 Fputhash (keysym, value, keymap->table); | |
601 keymap_store_inverse_internal (keymap->inverse_table, | |
602 keysym, value); | |
603 } | |
604 keymap_tick++; | |
605 } | |
606 | |
607 | |
608 static Lisp_Object | |
609 create_bucky_submap (struct keymap *k, unsigned int modifiers, | |
610 Lisp_Object parent_for_debugging_info) | |
611 { | |
612 Lisp_Object submap = Fmake_sparse_keymap (Qnil); | |
613 /* User won't see this, but it is nice for debugging Emacs */ | |
614 XKEYMAP (submap)->name | |
615 = control_meta_superify (parent_for_debugging_info, modifiers); | |
616 /* Invalidate cache */ | |
617 k->sub_maps_cache = Qt; | |
618 keymap_store_internal (MAKE_MODIFIER_HASH_KEY (modifiers), k, submap); | |
619 return (submap); | |
620 } | |
621 | |
622 | |
623 /* Relies on caller to gc-protect keymap, keysym, value */ | |
624 static void | |
625 keymap_store (Lisp_Object keymap, CONST struct key_data *key, | |
626 Lisp_Object value) | |
627 { | |
628 Lisp_Object keysym = key->keysym; | |
629 unsigned int modifiers = key->modifiers; | |
630 struct keymap *k; | |
631 | |
632 if ((modifiers & ~(MOD_CONTROL | MOD_META | MOD_SUPER | MOD_HYPER | |
633 | MOD_ALT | MOD_SHIFT)) != 0) | |
634 abort (); | |
635 | |
636 k = XKEYMAP (keymap); | |
637 | |
638 /* If the keysym is a one-character symbol, use the char code instead. */ | |
639 if (SYMBOLP (keysym) && string_char_length (XSYMBOL (keysym)->name) == 1) | |
640 { | |
641 Lisp_Object run_the_gcc_developers_over_with_a_steamroller = | |
642 make_char (string_char (XSYMBOL (keysym)->name, 0)); | |
643 keysym = run_the_gcc_developers_over_with_a_steamroller; | |
644 } | |
645 | |
646 if (modifiers & MOD_META) /* Utterly hateful ESC lossage */ | |
647 { | |
648 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META), | |
649 k->table, Qnil); | |
650 if (NILP (submap)) | |
651 submap = create_bucky_submap (k, MOD_META, keymap); | |
652 k = XKEYMAP (submap); | |
653 modifiers &= ~MOD_META; | |
654 } | |
655 | |
656 if (modifiers != 0) | |
657 { | |
658 Lisp_Object submap = Fgethash (MAKE_MODIFIER_HASH_KEY (modifiers), | |
659 k->table, Qnil); | |
660 if (NILP (submap)) | |
661 submap = create_bucky_submap (k, modifiers, keymap); | |
662 k = XKEYMAP (submap); | |
663 } | |
664 k->sub_maps_cache = Qt; /* Invalidate cache */ | |
665 keymap_store_internal (keysym, k, value); | |
666 } | |
667 | |
668 | |
669 /************************************************************************/ | |
670 /* Listing the submaps of a keymap */ | |
671 /************************************************************************/ | |
672 | |
673 struct keymap_submaps_closure | |
674 { | |
675 Lisp_Object *result_locative; | |
676 }; | |
677 | |
678 static void | |
679 keymap_submaps_mapper_0 (CONST void *hash_key, void *hash_contents, | |
680 void *keymap_submaps_closure) | |
681 { | |
682 /* This function can GC */ | |
683 Lisp_Object contents; | |
684 VOID_TO_LISP (contents, hash_contents); | |
685 /* Perform any autoloads, etc */ | |
686 (void) Fkeymapp (contents); | |
687 } | |
688 | |
689 static void | |
690 keymap_submaps_mapper (CONST void *hash_key, void *hash_contents, | |
691 void *keymap_submaps_closure) | |
692 { | |
693 /* This function can GC */ | |
694 Lisp_Object key, contents; | |
695 Lisp_Object *result_locative; | |
696 struct keymap_submaps_closure *cl = keymap_submaps_closure; | |
697 CVOID_TO_LISP (key, hash_key); | |
698 VOID_TO_LISP (contents, hash_contents); | |
699 result_locative = cl->result_locative; | |
700 | |
701 if (!NILP (Fkeymapp (contents))) | |
702 *result_locative = Fcons (Fcons (key, contents), *result_locative); | |
703 } | |
704 | |
705 static int map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2, | |
706 Lisp_Object pred); | |
707 | |
708 static Lisp_Object | |
709 keymap_submaps (Lisp_Object keymap) | |
710 { | |
711 /* This function can GC */ | |
712 struct keymap *k = XKEYMAP (keymap); | |
713 | |
714 if (EQ (k->sub_maps_cache, Qt)) /* Unknown */ | |
715 { | |
716 Lisp_Object result = Qnil; | |
717 struct gcpro gcpro1, gcpro2; | |
718 struct keymap_submaps_closure keymap_submaps_closure; | |
719 | |
720 GCPRO2 (keymap, result); | |
721 keymap_submaps_closure.result_locative = &result; | |
722 /* Do this first pass to touch (and load) any autoloaded maps */ | |
723 elisp_maphash (keymap_submaps_mapper_0, k->table, | |
724 &keymap_submaps_closure); | |
725 result = Qnil; | |
726 elisp_maphash (keymap_submaps_mapper, k->table, | |
727 &keymap_submaps_closure); | |
728 /* keep it sorted so that the result of accessible-keymaps is ordered */ | |
729 k->sub_maps_cache = list_sort (result, | |
730 Qnil, | |
731 map_keymap_sort_predicate); | |
732 UNGCPRO; | |
733 } | |
734 return (k->sub_maps_cache); | |
735 } | |
736 | |
737 | |
738 /************************************************************************/ | |
739 /* Basic operations on keymaps */ | |
740 /************************************************************************/ | |
741 | |
742 static Lisp_Object | |
743 make_keymap (int size) | |
744 { | |
745 Lisp_Object result = Qnil; | |
746 struct keymap *keymap = alloc_lcrecord (sizeof (struct keymap), | |
747 lrecord_keymap); | |
748 | |
749 XSETKEYMAP (result, keymap); | |
750 | |
751 keymap->parents = Qnil; | |
752 keymap->table = Qnil; | |
753 keymap->prompt = Qnil; | |
754 keymap->default_binding = Qnil; | |
755 keymap->inverse_table = Qnil; | |
756 keymap->sub_maps_cache = Qnil; /* No possible submaps */ | |
757 keymap->fullness = 0; | |
758 if (size != 0) /* hack for copy-keymap */ | |
759 { | |
760 keymap->table = Fmake_hashtable (make_int (size), Qnil); | |
761 /* Inverse table is often less dense because of duplicate key-bindings. | |
762 If not, it will grow anyway. */ | |
763 keymap->inverse_table = Fmake_hashtable (make_int (size * 3 / 4), Qnil); | |
764 } | |
765 keymap->name = Qnil; | |
766 return (result); | |
767 } | |
768 | |
769 DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 1, 0 /* | |
770 Construct and return a new keymap object. | |
771 All entries in it are nil, meaning \"command undefined\". | |
772 | |
773 Optional argument NAME specifies a name to assign to the keymap, | |
774 as in `set-keymap-name'. This name is only a debugging convenience; | |
775 it is not used except when printing the keymap. | |
776 */ ) | |
777 (name) | |
778 Lisp_Object name; | |
779 { | |
780 Lisp_Object keymap = make_keymap (60); | |
781 if (!NILP (name)) | |
782 Fset_keymap_name (keymap, name); | |
783 return keymap; | |
784 } | |
785 | |
786 DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, | |
787 0, 1, 0 /* | |
788 Construct and return a new keymap object. | |
789 All entries in it are nil, meaning \"command undefined\". The only | |
790 difference between this function and make-keymap is that this function | |
791 returns a \"smaller\" keymap (one that is expected to contain fewer | |
792 entries). As keymaps dynamically resize, the distinction is not great. | |
793 | |
794 Optional argument NAME specifies a name to assign to the keymap, | |
795 as in `set-keymap-name'. This name is only a debugging convenience; | |
796 it is not used except when printing the keymap. | |
797 */ ) | |
798 (name) | |
799 Lisp_Object name; | |
800 { | |
801 Lisp_Object keymap = make_keymap (8); | |
802 if (!NILP (name)) | |
803 Fset_keymap_name (keymap, name); | |
804 return keymap; | |
805 } | |
806 | |
807 DEFUN ("keymap-parents", Fkeymap_parents, Skeymap_parents, 1, 1, 0 /* | |
808 Return the `parent' keymaps of the given keymap, or nil. | |
809 The parents of a keymap are searched for keybindings when a key sequence | |
810 isn't bound in this one. `(current-global-map)' is the default parent | |
811 of all keymaps. | |
812 */ ) | |
813 (keymap) | |
814 Lisp_Object keymap; | |
815 { | |
816 keymap = get_keymap (keymap, 1, 1); | |
817 return (Fcopy_sequence (XKEYMAP (keymap)->parents)); | |
818 } | |
819 | |
820 | |
821 | |
822 static Lisp_Object | |
823 traverse_keymaps_noop (Lisp_Object keymap, void *arg) | |
824 { | |
825 return (Qnil); | |
826 } | |
827 | |
828 DEFUN ("set-keymap-parents", Fset_keymap_parents, Sset_keymap_parents, 2, 2, 0 /* | |
829 Sets the `parent' keymaps of the given keymap. | |
830 The parents of a keymap are searched for keybindings when a key sequence | |
831 isn't bound in this one. `(current-global-map)' is the default parent | |
832 of all keymaps. | |
833 */ ) | |
834 (keymap, parents) | |
835 Lisp_Object keymap, parents; | |
836 { | |
837 /* This function can GC */ | |
838 Lisp_Object k; | |
839 struct gcpro gcpro1, gcpro2; | |
840 | |
841 GCPRO2 (keymap, parents); | |
842 keymap = get_keymap (keymap, 1, 1); | |
843 | |
844 if (KEYMAPP (parents)) /* backwards-compatibility */ | |
845 parents = list1 (parents); | |
846 if (!NILP (parents)) | |
847 { | |
848 Lisp_Object tail = parents; | |
849 while (!NILP (tail)) | |
850 { | |
851 QUIT; | |
852 CHECK_CONS (tail); | |
853 k = XCAR (tail); | |
854 /* Require that it be an actual keymap object, rather than a symbol | |
855 with a (crockish) symbol-function which is a keymap */ | |
856 CHECK_KEYMAP (k); /* get_keymap (k, 1, 1); */ | |
857 tail = XCDR (tail); | |
858 } | |
859 } | |
860 | |
861 /* Check for circularities */ | |
862 traverse_keymaps (keymap, parents, traverse_keymaps_noop, 0); | |
863 keymap_tick++; | |
864 XKEYMAP (keymap)->parents = Fcopy_sequence (parents); | |
865 UNGCPRO; | |
866 return (parents); | |
867 } | |
868 | |
869 DEFUN ("set-keymap-name", Fset_keymap_name, Sset_keymap_name, 2, 2, 0 /* | |
870 Set the `name' of the KEYMAP to NEW-NAME. | |
871 The name is only a debugging convenience; it is not used except | |
872 when printing the keymap. | |
873 */ ) | |
874 (keymap, new_name) | |
875 Lisp_Object keymap, new_name; | |
876 { | |
877 keymap = get_keymap (keymap, 1, 1); | |
878 | |
879 XKEYMAP (keymap)->name = new_name; | |
880 return (new_name); | |
881 } | |
882 | |
883 DEFUN ("keymap-name", Fkeymap_name, Skeymap_name, 1, 1, 0 /* | |
884 Return the `name' of KEYMAP. | |
885 The name is only a debugging convenience; it is not used except | |
886 when printing the keymap. | |
887 */ ) | |
888 (keymap) | |
889 Lisp_Object keymap; | |
890 { | |
891 keymap = get_keymap (keymap, 1, 1); | |
892 | |
893 return (XKEYMAP (keymap)->name); | |
894 } | |
895 | |
896 DEFUN ("set-keymap-prompt", Fset_keymap_prompt, Sset_keymap_prompt, 2, 2, 0 /* | |
897 Sets the `prompt' of KEYMAP to string NEW-PROMPT, or `nil' | |
898 if no prompt is desired. The prompt is shown in the echo-area | |
899 when reading a key-sequence to be looked-up in this keymap. | |
900 */ ) | |
901 (keymap, new_prompt) | |
902 Lisp_Object keymap, new_prompt; | |
903 { | |
904 keymap = get_keymap (keymap, 1, 1); | |
905 | |
906 if (!NILP (new_prompt)) | |
907 CHECK_STRING (new_prompt); | |
908 | |
909 XKEYMAP (keymap)->prompt = new_prompt; | |
910 return (new_prompt); | |
911 } | |
912 | |
913 static Lisp_Object | |
914 keymap_prompt_mapper (Lisp_Object keymap, void *arg) | |
915 { | |
916 return (XKEYMAP (keymap)->prompt); | |
917 } | |
918 | |
919 | |
920 DEFUN ("keymap-prompt", Fkeymap_prompt, Skeymap_prompt, 1, 2, 0 /* | |
921 Return the `prompt' of the given keymap. | |
922 If non-nil, the prompt is shown in the echo-area | |
923 when reading a key-sequence to be looked-up in this keymap. | |
924 */ ) | |
925 (keymap, use_inherited) | |
926 Lisp_Object keymap, use_inherited; | |
927 { | |
928 /* This function can GC */ | |
929 Lisp_Object prompt; | |
930 | |
931 keymap = get_keymap (keymap, 1, 1); | |
932 prompt = XKEYMAP (keymap)->prompt; | |
933 if (!NILP (prompt) || NILP (use_inherited)) | |
934 return (prompt); | |
935 else | |
936 return (traverse_keymaps (keymap, Qnil, | |
937 keymap_prompt_mapper, 0)); | |
938 } | |
939 | |
940 DEFUN ("set-keymap-default-binding", | |
941 Fset_keymap_default_binding, Sset_keymap_default_binding, 2, 2, 0 /* | |
942 Sets the default binding of KEYMAP to COMMAND, or `nil' | |
943 if no default is desired. The default-binding is returned when | |
944 no other binding for a key-sequence is found in the keymap. | |
945 If a keymap has a non-nil default-binding, neither the keymap's | |
946 parents nor the current global map are searched for key bindings. | |
947 */ ) | |
948 (keymap, command) | |
949 Lisp_Object keymap, command; | |
950 { | |
951 /* This function can GC */ | |
952 keymap = get_keymap (keymap, 1, 1); | |
953 | |
954 XKEYMAP (keymap)->default_binding = command; | |
955 return (command); | |
956 } | |
957 | |
958 DEFUN ("keymap-default-binding", | |
959 Fkeymap_default_binding, Skeymap_default_binding, 1, 1, 0 /* | |
960 Return the default binding of KEYMAP, or `nil' if it has none. | |
961 The default-binding is returned when no other binding for a key-sequence | |
962 is found in the keymap. | |
963 If a keymap has a non-nil default-binding, neither the keymap's | |
964 parents nor the current global map are searched for key bindings. | |
965 */ ) | |
966 (keymap) | |
967 Lisp_Object keymap; | |
968 { | |
969 /* This function can GC */ | |
970 keymap = get_keymap (keymap, 1, 1); | |
971 return (XKEYMAP (keymap)->default_binding); | |
972 } | |
973 | |
974 DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0 /* | |
975 Return t if ARG is a keymap object. | |
976 The keymap may be autoloaded first if necessary. | |
977 */ ) | |
978 (object) | |
979 Lisp_Object object; | |
980 { | |
981 /* This function can GC */ | |
982 Lisp_Object tem = get_keymap (object, 0, 1); | |
983 return ((KEYMAPP (tem)) ? Qt : Qnil); | |
984 } | |
985 | |
986 /* Check that OBJECT is a keymap (after dereferencing through any | |
987 symbols). If it is, return it. | |
988 | |
989 If AUTOLOAD is non-zero and OBJECT is a symbol whose function value | |
990 is an autoload form, do the autoload and try again. | |
991 | |
992 ERRORP controls how we respond if OBJECT isn't a keymap. | |
993 If ERRORP is non-zero, signal an error; otherwise, just return Qnil. | |
994 */ | |
995 Lisp_Object | |
996 get_keymap (Lisp_Object object, int errorp, int autoload) | |
997 { | |
998 /* This function can GC */ | |
999 while (1) | |
1000 { | |
1001 Lisp_Object tem = indirect_function (object, 0); | |
1002 | |
1003 if (KEYMAPP (tem)) | |
1004 return tem; | |
1005 /* Should we do an autoload? */ | |
1006 else if (autoload | |
1007 /* (autoload "filename" doc nil keymap) */ | |
1008 && SYMBOLP (object) | |
1009 && CONSP (tem) | |
1010 && EQ (XCAR (tem), Qautoload) | |
1011 && EQ (Fcar (Fcdr (Fcdr (Fcdr (Fcdr (tem))))), Qkeymap)) | |
1012 { | |
1013 struct gcpro gcpro1, gcpro2; | |
1014 GCPRO2 (tem, object); | |
1015 do_autoload (tem, object); | |
1016 UNGCPRO; | |
1017 } | |
1018 else if (errorp) | |
1019 object = wrong_type_argument (Qkeymapp, object); | |
1020 else | |
1021 return Qnil; | |
1022 } | |
1023 } | |
1024 | |
1025 /* Given OBJECT which was found in a slot in a keymap, | |
1026 trace indirect definitions to get the actual definition of that slot. | |
1027 An indirect definition is a list of the form | |
1028 (KEYMAP . INDEX), where KEYMAP is a keymap or a symbol defined as one | |
1029 and INDEX is an ASCII code, or a cons of (KEYSYM . MODIFIERS). | |
1030 */ | |
1031 static Lisp_Object | |
1032 get_keyelt (Lisp_Object object, int accept_default) | |
1033 { | |
1034 /* This function can GC */ | |
1035 Lisp_Object map; | |
1036 | |
1037 tail_recurse: | |
1038 if (!CONSP (object)) | |
1039 return (object); | |
1040 | |
1041 { | |
1042 struct gcpro gcpro1; | |
1043 GCPRO1 (object); | |
1044 map = XCAR (object); | |
1045 map = get_keymap (map, 0, 1); | |
1046 UNGCPRO; | |
1047 } | |
1048 /* If the contents are (KEYMAP . ELEMENT), go indirect. */ | |
1049 if (!NILP (map)) | |
1050 { | |
1051 Lisp_Object idx = Fcdr (object); | |
1052 struct key_data indirection; | |
1053 if (CHARP (idx)) | |
1054 { | |
1055 struct Lisp_Event event; | |
1056 event.event_type = empty_event; | |
1057 character_to_event (XCHAR (idx), &event, | |
1058 XCONSOLE (Vselected_console), 0); | |
1059 indirection = event.event.key; | |
1060 } | |
1061 else if (CONSP (idx)) | |
1062 { | |
1063 if (!INTP (XCDR (idx))) | |
1064 return (Qnil); | |
1065 indirection.keysym = XCAR (idx); | |
1066 indirection.modifiers = XINT (XCDR (idx)); | |
1067 } | |
1068 else if (SYMBOLP (idx)) | |
1069 { | |
1070 indirection.keysym = idx; | |
1071 indirection.modifiers = 0; | |
1072 } | |
1073 else | |
1074 { | |
1075 /* Random junk */ | |
1076 return (Qnil); | |
1077 } | |
1078 return (raw_lookup_key (map, &indirection, 1, 0, | |
1079 accept_default)); | |
1080 } | |
1081 else if (STRINGP (XCAR (object))) | |
1082 { | |
1083 /* If the keymap contents looks like (STRING . DEFN), | |
1084 use DEFN. | |
1085 Keymap alist elements like (CHAR MENUSTRING . DEFN) | |
1086 will be used by HierarKey menus. */ | |
1087 object = XCDR (object); | |
1088 goto tail_recurse; | |
1089 } | |
1090 else | |
1091 { | |
1092 /* Anything else is really the value. */ | |
1093 return (object); | |
1094 } | |
1095 } | |
1096 | |
1097 static Lisp_Object | |
1098 keymap_lookup_1 (Lisp_Object keymap, CONST struct key_data *key, | |
1099 int accept_default) | |
1100 { | |
1101 /* This function can GC */ | |
1102 return (get_keyelt (keymap_lookup_directly (keymap, | |
1103 key->keysym, key->modifiers), | |
1104 accept_default)); | |
1105 } | |
1106 | |
1107 | |
1108 /************************************************************************/ | |
1109 /* Copying keymaps */ | |
1110 /************************************************************************/ | |
1111 | |
1112 struct copy_keymap_inverse_closure | |
1113 { | |
1114 Lisp_Object inverse_table; | |
1115 }; | |
1116 | |
1117 static void | |
1118 copy_keymap_inverse_mapper (CONST void *hash_key, void *hash_contents, | |
1119 void *copy_keymap_inverse_closure) | |
1120 { | |
1121 Lisp_Object key, inverse_table, inverse_contents; | |
1122 struct copy_keymap_inverse_closure *closure = copy_keymap_inverse_closure; | |
1123 | |
1124 VOID_TO_LISP (inverse_table, closure); | |
1125 VOID_TO_LISP (inverse_contents, hash_contents); | |
1126 CVOID_TO_LISP (key, hash_key); | |
1127 /* copy-sequence deals with dotted lists. */ | |
1128 if (CONSP (inverse_contents)) | |
1129 inverse_contents = Fcopy_sequence (inverse_contents); | |
1130 Fputhash (key, inverse_contents, closure->inverse_table); | |
1131 } | |
1132 | |
1133 | |
1134 static Lisp_Object | |
1135 copy_keymap_internal (struct keymap *keymap) | |
1136 { | |
1137 Lisp_Object nkm = make_keymap (0); | |
1138 struct keymap *new_keymap = XKEYMAP (nkm); | |
1139 struct copy_keymap_inverse_closure copy_keymap_inverse_closure; | |
1140 copy_keymap_inverse_closure.inverse_table = keymap->inverse_table; | |
1141 | |
1142 new_keymap->parents = Fcopy_sequence (keymap->parents); | |
1143 new_keymap->fullness = keymap->fullness; | |
1144 new_keymap->sub_maps_cache = Qnil; /* No submaps */ | |
1145 new_keymap->table = Fcopy_hashtable (keymap->table); | |
1146 new_keymap->inverse_table = Fcopy_hashtable (keymap->inverse_table); | |
1147 /* After copying the inverse map, we need to copy the conses which | |
1148 are its values, lest they be shared by the copy, and mangled. | |
1149 */ | |
1150 elisp_maphash (copy_keymap_inverse_mapper, keymap->inverse_table, | |
1151 ©_keymap_inverse_closure); | |
1152 return nkm; | |
1153 } | |
1154 | |
1155 | |
1156 static Lisp_Object copy_keymap (Lisp_Object keymap); | |
1157 | |
1158 struct copy_keymap_closure | |
1159 { | |
1160 struct keymap *self; | |
1161 }; | |
1162 | |
1163 static void | |
1164 copy_keymap_mapper (CONST void *hash_key, void *hash_contents, | |
1165 void *copy_keymap_closure) | |
1166 { | |
1167 /* This function can GC */ | |
1168 Lisp_Object key, contents; | |
1169 struct copy_keymap_closure *closure = copy_keymap_closure; | |
1170 | |
1171 CVOID_TO_LISP (key, hash_key); | |
1172 VOID_TO_LISP (contents, hash_contents); | |
1173 /* When we encounter a keymap which is indirected through a | |
1174 symbol, we need to copy the sub-map. In v18, the form | |
1175 (lookup-key (copy-keymap global-map) "\C-x") | |
1176 returned a new keymap, not the symbol 'Control-X-prefix. | |
1177 */ | |
1178 contents = get_keymap (contents, | |
1179 0, 1); /* #### autoload GC-safe here? */ | |
1180 if (KEYMAPP (contents)) | |
1181 keymap_store_internal (key, closure->self, | |
1182 copy_keymap (contents)); | |
1183 } | |
1184 | |
1185 static Lisp_Object | |
1186 copy_keymap (Lisp_Object keymap) | |
1187 { | |
1188 /* This function can GC */ | |
1189 struct copy_keymap_closure copy_keymap_closure; | |
1190 | |
1191 keymap = copy_keymap_internal (XKEYMAP (keymap)); | |
1192 copy_keymap_closure.self = XKEYMAP (keymap); | |
1193 elisp_maphash (copy_keymap_mapper, | |
1194 XKEYMAP (keymap)->table, | |
1195 ©_keymap_closure); | |
1196 return keymap; | |
1197 } | |
1198 | |
1199 DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0 /* | |
1200 Return a copy of the keymap KEYMAP. | |
1201 The copy starts out with the same definitions of KEYMAP, | |
1202 but changing either the copy or KEYMAP does not affect the other. | |
1203 Any key definitions that are subkeymaps are recursively copied. | |
1204 */ ) | |
1205 (keymap) | |
1206 Lisp_Object keymap; | |
1207 { | |
1208 /* This function can GC */ | |
1209 keymap = get_keymap (keymap, 1, 1); | |
1210 return copy_keymap (keymap); | |
1211 } | |
1212 | |
1213 | |
1214 static int | |
1215 keymap_fullness (Lisp_Object keymap) | |
1216 { | |
1217 /* This function can GC */ | |
1218 int fullness; | |
1219 Lisp_Object sub_maps; | |
1220 struct gcpro gcpro1, gcpro2; | |
1221 | |
1222 keymap = get_keymap (keymap, 1, 1); | |
1223 fullness = XKEYMAP (keymap)->fullness; | |
1224 sub_maps = keymap_submaps (keymap); | |
1225 GCPRO2 (keymap, sub_maps); | |
1226 for (; !NILP (sub_maps); sub_maps = XCDR (sub_maps)) | |
1227 { | |
1228 if (MODIFIER_HASH_KEY_BITS (XCAR (XCAR (sub_maps))) != 0) | |
1229 { | |
1230 Lisp_Object sub_map = XCDR (XCAR (sub_maps)); | |
1231 fullness--; /* don't count bucky maps */ | |
1232 fullness += keymap_fullness (sub_map); | |
1233 } | |
1234 } | |
1235 UNGCPRO; | |
1236 return (fullness); | |
1237 } | |
1238 | |
1239 DEFUN ("keymap-fullness", Fkeymap_fullness, Skeymap_fullness, 1, 1, 0 /* | |
1240 Return the number of bindings in the keymap. | |
1241 */ ) | |
1242 (keymap) | |
1243 Lisp_Object keymap; | |
1244 { | |
1245 /* This function can GC */ | |
1246 return (make_int (keymap_fullness | |
1247 (get_keymap (keymap, 1, 1)))); | |
1248 } | |
1249 | |
1250 | |
1251 /************************************************************************/ | |
1252 /* Defining keys in keymaps */ | |
1253 /************************************************************************/ | |
1254 | |
1255 static void | |
1256 define_key_check_keysym (Lisp_Object spec, | |
1257 Lisp_Object keysym, unsigned int modifiers) | |
1258 { | |
1259 /* Now, check and massage the trailing keysym specifier. */ | |
1260 if (SYMBOLP (keysym)) | |
1261 { | |
1262 if (string_length (XSYMBOL (keysym)->name) == 1) | |
1263 { | |
1264 keysym = make_int (string_char (XSYMBOL (keysym)->name, 0)); | |
1265 goto fixnum_keysym; | |
1266 } | |
1267 } | |
1268 else if (INTP (keysym)) | |
1269 { | |
1270 fixnum_keysym: | |
1271 if (XINT (keysym) < ' ' || XINT (keysym) > 255) | |
1272 signal_simple_error ("keysym must be in the range 32 - 255", | |
1273 keysym); | |
1274 /* #### This bites! I want to be able to write (control shift a) */ | |
1275 if (modifiers & MOD_SHIFT) | |
1276 signal_simple_error ("the `shift' modifier may not be applied to ASCII keysyms", | |
1277 spec); | |
1278 } | |
1279 else | |
1280 { | |
1281 signal_simple_error ("unknown keysym specifier", | |
1282 keysym); | |
1283 } | |
1284 } | |
1285 | |
1286 | |
1287 /* Given any kind of key-specifier, return a keysym and modifier mask. | |
1288 */ | |
1289 static void | |
1290 define_key_parser (Lisp_Object spec, struct key_data *returned_value) | |
1291 { | |
1292 if (INTP (spec)) | |
1293 { | |
1294 struct Lisp_Event event; | |
1295 event.event_type = empty_event; | |
1296 character_to_event (XINT (spec), &event, | |
1297 XCONSOLE (Vselected_console), 0); | |
1298 returned_value->keysym = event.event.key.keysym; | |
1299 returned_value->modifiers = event.event.key.modifiers; | |
1300 } | |
1301 else if (EVENTP (spec)) | |
1302 { | |
1303 switch (XEVENT (spec)->event_type) | |
1304 { | |
1305 case key_press_event: | |
1306 { | |
1307 returned_value->keysym = XEVENT (spec)->event.key.keysym; | |
1308 returned_value->modifiers = XEVENT (spec)->event.key.modifiers; | |
1309 break; | |
1310 } | |
1311 case button_press_event: | |
1312 case button_release_event: | |
1313 { | |
1314 int down = (XEVENT (spec)->event_type == button_press_event); | |
1315 switch (XEVENT (spec)->event.button.button) | |
1316 { | |
1317 case 1: | |
1318 returned_value->keysym = (down ? Qbutton1 : Qbutton1up); break; | |
1319 case 2: | |
1320 returned_value->keysym = (down ? Qbutton2 : Qbutton2up); break; | |
1321 case 3: | |
1322 returned_value->keysym = (down ? Qbutton3 : Qbutton3up); break; | |
1323 case 4: | |
1324 returned_value->keysym = (down ? Qbutton4 : Qbutton4up); break; | |
1325 case 5: | |
1326 returned_value->keysym = (down ? Qbutton5 : Qbutton5up); break; | |
1327 case 6: | |
1328 returned_value->keysym = (down ? Qbutton6 : Qbutton6up); break; | |
1329 case 7: | |
1330 returned_value->keysym = (down ? Qbutton7 : Qbutton7up); break; | |
1331 default: | |
1332 returned_value->keysym =(down ? Qbutton0 : Qbutton0up); break; | |
1333 } | |
1334 returned_value->modifiers = XEVENT (spec)->event.button.modifiers; | |
1335 break; | |
1336 } | |
1337 default: | |
1338 signal_error (Qwrong_type_argument, | |
1339 list2 (build_translated_string | |
1340 ("unable to bind this type of event"), | |
1341 spec)); | |
1342 } | |
1343 } | |
1344 else if (SYMBOLP (spec)) | |
1345 { | |
1346 /* Be nice, allow = to mean (=) */ | |
1347 if (bucky_sym_to_bucky_bit (spec) != 0) | |
1348 signal_simple_error ("Key is a modifier name", spec); | |
1349 define_key_check_keysym (spec, spec, 0); | |
1350 returned_value->keysym = spec; | |
1351 returned_value->modifiers = 0; | |
1352 } | |
1353 else if (CONSP (spec)) | |
1354 { | |
1355 unsigned int modifiers = 0; | |
1356 Lisp_Object keysym = Qnil; | |
1357 Lisp_Object rest = spec; | |
1358 | |
1359 /* First, parse out the leading modifier symbols. */ | |
1360 while (CONSP (rest)) | |
1361 { | |
1362 unsigned int modifier; | |
1363 | |
1364 keysym = XCAR (rest); | |
1365 modifier = bucky_sym_to_bucky_bit (keysym); | |
1366 modifiers |= modifier; | |
1367 if (!NILP (XCDR (rest))) | |
1368 { | |
1369 if (! modifier) | |
1370 signal_simple_error ("unknown modifier", keysym); | |
1371 } | |
1372 else | |
1373 { | |
1374 if (modifier) | |
1375 signal_simple_error ("nothing but modifiers here", | |
1376 spec); | |
1377 } | |
1378 rest = XCDR (rest); | |
1379 QUIT; | |
1380 } | |
1381 if (!NILP (rest)) | |
1382 signal_simple_error ("dotted list", spec); | |
1383 | |
1384 define_key_check_keysym (spec, keysym, modifiers); | |
1385 returned_value->keysym = keysym; | |
1386 returned_value->modifiers = modifiers; | |
1387 } | |
1388 else | |
1389 { | |
1390 signal_simple_error ("unknown key-sequence specifier", | |
1391 spec); | |
1392 } | |
1393 | |
1394 /* Convert single-character symbols into ints, since that's the | |
1395 way the events arrive from the keyboard... */ | |
1396 if (SYMBOLP (returned_value->keysym) && | |
1397 string_length (XSYMBOL (returned_value->keysym)->name) == 1) | |
1398 { | |
1399 returned_value->keysym = | |
1400 make_int (string_char (XSYMBOL (returned_value->keysym)->name, 0)); | |
1401 | |
1402 /* Detect bogus (user-provided) keysyms like '\?C-a; | |
1403 We can't do that for '\?M-a because that interferes with | |
1404 legitimate 8-bit input. */ | |
1405 if (XINT (returned_value->keysym) < ' ' || | |
1406 XINT (returned_value->keysym) > 255) | |
1407 signal_simple_error ("keysym must be in the range 32 - 255", | |
1408 returned_value->keysym); | |
1409 } | |
1410 | |
1411 if (SYMBOLP (returned_value->keysym)) | |
1412 { | |
1413 char *name = (char *) string_data (XSYMBOL (returned_value->keysym)->name); | |
1414 | |
1415 /* FSFmacs uses symbols with the printed representation of keysyms in | |
1416 their names, like 'M-x, and we use the syntax '(meta x). So, to avoid | |
1417 confusion, notice the M-x syntax and signal an error - because | |
1418 otherwise it would be interpreted as a regular keysym, and would even | |
1419 show up in the list-buffers output, causing confusion to the naive. | |
1420 | |
1421 We can get away with this because none of the X keysym names contain | |
1422 a hyphen (some contain underscore, however). | |
1423 | |
1424 It might be useful to reject keysyms which are not x-valid-keysym- | |
1425 name-p, but that would interfere with various tricks we do to | |
1426 sanitize the Sun keyboards, and would make it trickier to | |
1427 conditionalize a .emacs file for multiple X servers. | |
1428 */ | |
1429 if (((unsigned int) strlen (name) >= 2 && name[1] == '-') | |
1430 #if 1 | |
1431 || | |
1432 /* Ok, this is a bit more dubious - prevent people from doing things | |
1433 like (global-set-key 'RET 'something) because that will have the | |
1434 same problem as above. (Gag!) Maybe we should just silently | |
1435 accept these as aliases for the "real" names? | |
1436 */ | |
1437 (string_length (XSYMBOL (returned_value->keysym)->name) < 4 && | |
1438 (!strcmp (name, "LFD") || | |
1439 !strcmp (name, "TAB") || | |
1440 !strcmp (name, "RET") || | |
1441 !strcmp (name, "ESC") || | |
1442 !strcmp (name, "DEL") || | |
1443 !strcmp (name, "SPC") || | |
1444 !strcmp (name, "BS"))) | |
1445 #endif /* unused */ | |
1446 ) | |
1447 signal_simple_error ("invalid keysym (see doc of define-key)", | |
1448 returned_value->keysym); | |
1449 | |
1450 /* #### Ok, this is a bit more dubious - make people not lose if they | |
1451 do things like (global-set-key 'RET 'something) because that would | |
1452 otherwise have the same problem as above. (Gag!) We silently | |
1453 accept these as aliases for the "real" names. | |
1454 */ | |
1455 else if (EQ (returned_value->keysym, QLFD)) | |
1456 returned_value->keysym = QKlinefeed; | |
1457 else if (EQ (returned_value->keysym, QTAB)) | |
1458 returned_value->keysym = QKtab; | |
1459 else if (EQ (returned_value->keysym, QRET)) | |
1460 returned_value->keysym = QKreturn; | |
1461 else if (EQ (returned_value->keysym, QESC)) | |
1462 returned_value->keysym = QKescape; | |
1463 else if (EQ (returned_value->keysym, QDEL)) | |
1464 returned_value->keysym = QKdelete; | |
1465 else if (EQ (returned_value->keysym, QBS)) | |
1466 returned_value->keysym = QKbackspace; | |
1467 } | |
1468 } | |
1469 | |
1470 /* Used by character-to-event */ | |
1471 void | |
1472 key_desc_list_to_event (Lisp_Object list, Lisp_Object event, | |
1473 int allow_menu_events) | |
1474 { | |
1475 struct key_data raw_key; | |
1476 | |
1477 if (allow_menu_events && | |
1478 CONSP (list) && | |
1479 /* #### where the hell does this come from? */ | |
1480 EQ (XCAR (list), Qmenu_selection)) | |
1481 { | |
1482 Lisp_Object fn, arg; | |
1483 if (! NILP (Fcdr (Fcdr (list)))) | |
1484 signal_simple_error ("invalid menu event desc", list); | |
1485 arg = Fcar (Fcdr (list)); | |
1486 if (SYMBOLP (arg)) | |
1487 fn = Qcall_interactively; | |
1488 else | |
1489 fn = Qeval; | |
1490 XSETFRAME (XEVENT (event)->channel, selected_frame ()); | |
1491 XEVENT (event)->event_type = misc_user_event; | |
1492 XEVENT (event)->event.eval.function = fn; | |
1493 XEVENT (event)->event.eval.object = arg; | |
1494 return; | |
1495 } | |
1496 | |
1497 define_key_parser (list, &raw_key); | |
1498 | |
1499 if (EQ (raw_key.keysym, Qbutton0) || EQ (raw_key.keysym, Qbutton0up) || | |
1500 EQ (raw_key.keysym, Qbutton1) || EQ (raw_key.keysym, Qbutton1up) || | |
1501 EQ (raw_key.keysym, Qbutton2) || EQ (raw_key.keysym, Qbutton2up) || | |
1502 EQ (raw_key.keysym, Qbutton3) || EQ (raw_key.keysym, Qbutton3up) || | |
1503 EQ (raw_key.keysym, Qbutton4) || EQ (raw_key.keysym, Qbutton4up) || | |
1504 EQ (raw_key.keysym, Qbutton5) || EQ (raw_key.keysym, Qbutton5up) || | |
1505 EQ (raw_key.keysym, Qbutton6) || EQ (raw_key.keysym, Qbutton6up) || | |
1506 EQ (raw_key.keysym, Qbutton7) || EQ (raw_key.keysym, Qbutton7up)) | |
1507 error ("Mouse-clicks can't appear in saved keyboard macros."); | |
1508 | |
1509 XEVENT (event)->channel = Vselected_console; | |
1510 XEVENT (event)->event_type = key_press_event; | |
1511 XEVENT (event)->event.key.keysym = raw_key.keysym; | |
1512 XEVENT (event)->event.key.modifiers = raw_key.modifiers; | |
1513 } | |
1514 | |
1515 | |
1516 int | |
1517 event_matches_key_specifier_p (struct Lisp_Event *event, | |
1518 Lisp_Object key_specifier) | |
1519 { | |
1520 Lisp_Object event2; | |
1521 int retval; | |
1522 struct gcpro gcpro1; | |
1523 | |
1524 if (event->event_type != key_press_event || NILP (key_specifier) || | |
1525 (INTP (key_specifier) && XINT (key_specifier) < 0)) | |
1526 return 0; | |
1527 | |
1528 /* if the specifier is an integer such as 27, then it should match | |
1529 both of the events 'escape' and 'control ['. Calling | |
1530 Fcharacter_to_event() will only match 'escape'. */ | |
1531 if (INTP (key_specifier)) | |
1532 return XINT (key_specifier) == event_to_character (event, 0, 0, 0); | |
1533 | |
1534 /* Otherwise, we cannot call event_to_character() because we may | |
1535 be dealing with non-ASCII keystrokes. In any case, if I ask | |
1536 for 'control [' then I should get exactly that, and not | |
1537 'escape'. | |
1538 | |
1539 However, we have to behave differently on TTY's, where 'control [' | |
1540 is silently converted into 'escape' by the keyboard driver. | |
1541 In this case, ASCII is the only thing we know about, so we have | |
1542 to compare the ASCII values. */ | |
1543 | |
1544 GCPRO1 (event2); | |
1545 event2 = Fmake_event (); | |
1546 Fcharacter_to_event (key_specifier, event2, Qnil, Qnil); | |
1547 if (XEVENT (event2)->event_type != key_press_event) | |
1548 retval = 0; | |
1549 else if (CONSOLE_TTY_P (XCONSOLE (EVENT_CHANNEL (event)))) | |
1550 { | |
1551 int ch1, ch2; | |
1552 | |
1553 ch1 = event_to_character (event, 0, 0, 0); | |
1554 ch2 = event_to_character (XEVENT (event2), 0, 0, 0); | |
1555 retval = (ch1 >= 0 && ch2 >= 0 && ch1 == ch2); | |
1556 } | |
1557 else if (EQ (event->event.key.keysym, XEVENT (event2)->event.key.keysym) && | |
1558 event->event.key.modifiers == XEVENT (event2)->event.key.modifiers) | |
1559 retval = 1; | |
1560 else | |
1561 retval = 0; | |
1562 Fdeallocate_event (event2); | |
1563 UNGCPRO; | |
1564 return retval; | |
1565 } | |
1566 | |
1567 static int | |
1568 meta_prefix_char_p (CONST struct key_data *key) | |
1569 { | |
1570 struct Lisp_Event event; | |
1571 | |
1572 event.event_type = key_press_event; | |
1573 event.channel = Vselected_console; | |
1574 event.event.key.keysym = key->keysym; | |
1575 event.event.key.modifiers = key->modifiers; | |
1576 return event_matches_key_specifier_p (&event, Vmeta_prefix_char); | |
1577 } | |
1578 | |
1579 DEFUN ("event-matches-key-specifier-p", | |
1580 Fevent_matches_key_specifier_p, | |
1581 Sevent_matches_key_specifier_p, | |
1582 2, 2, 0 /* | |
1583 Return non-nil if EVENT matches KEY-SPECIFIER. | |
1584 This can be useful, e.g., to determine if the user pressed `help-char' or | |
1585 `quit-char'. | |
1586 */ ) | |
1587 (event, key_specifier) | |
1588 Lisp_Object event, key_specifier; | |
1589 { | |
1590 CHECK_LIVE_EVENT (event); | |
1591 return (event_matches_key_specifier_p (XEVENT (event), key_specifier) | |
1592 ? Qt : Qnil); | |
1593 } | |
1594 | |
1595 /* ASCII grunge. | |
1596 Given a keysym, return another keysym/modifier pair which could be | |
1597 considered the same key in an ASCII world. Backspace returns ^H, for | |
1598 example. | |
1599 */ | |
1600 static void | |
1601 define_key_alternate_name (struct key_data *key, | |
1602 struct key_data *returned_value) | |
1603 { | |
1604 Lisp_Object keysym = key->keysym; | |
1605 unsigned int modifiers = key->modifiers; | |
1606 unsigned int modifiers_sans_control = (modifiers & (~MOD_CONTROL)); | |
1607 unsigned int modifiers_sans_meta = (modifiers & (~MOD_META)); | |
1608 returned_value->keysym = Qnil; /* By default, no "alternate" key */ | |
1609 returned_value->modifiers = 0; | |
1610 #define MACROLET(k,m) do { returned_value->keysym = (k); \ | |
1611 returned_value->modifiers = (m); \ | |
1612 RETURN__; } while (0) | |
1613 if (modifiers_sans_meta == MOD_CONTROL) | |
1614 { | |
1615 if EQ (keysym, QKspace) | |
1616 MACROLET (make_char ('@'), modifiers); | |
1617 else if (!CHARP (keysym)) | |
1618 return; | |
1619 else switch (XCHAR (keysym)) | |
1620 { | |
1621 case '@': /* c-@ => c-space */ | |
1622 MACROLET (QKspace, modifiers); | |
1623 case 'h': /* c-h => backspace */ | |
1624 MACROLET (QKbackspace, modifiers_sans_control); | |
1625 case 'i': /* c-i => tab */ | |
1626 MACROLET (QKtab, modifiers_sans_control); | |
1627 case 'j': /* c-j => linefeed */ | |
1628 MACROLET (QKlinefeed, modifiers_sans_control); | |
1629 case 'm': /* c-m => return */ | |
1630 MACROLET (QKreturn, modifiers_sans_control); | |
1631 case '[': /* c-[ => escape */ | |
1632 MACROLET (QKescape, modifiers_sans_control); | |
1633 default: | |
1634 return; | |
1635 } | |
1636 } | |
1637 else if (modifiers_sans_meta != 0) | |
1638 return; | |
1639 else if (EQ (keysym, QKbackspace)) /* backspace => c-h */ | |
1640 MACROLET (make_char ('h'), (modifiers | MOD_CONTROL)); | |
1641 else if (EQ (keysym, QKtab)) /* tab => c-i */ | |
1642 MACROLET (make_char ('i'), (modifiers | MOD_CONTROL)); | |
1643 else if (EQ (keysym, QKlinefeed)) /* linefeed => c-j */ | |
1644 MACROLET (make_char ('j'), (modifiers | MOD_CONTROL)); | |
1645 else if (EQ (keysym, QKreturn)) /* return => c-m */ | |
1646 MACROLET (make_char ('m'), (modifiers | MOD_CONTROL)); | |
1647 else if (EQ (keysym, QKescape)) /* escape => c-[ */ | |
1648 MACROLET (make_char ('['), (modifiers | MOD_CONTROL)); | |
1649 else | |
1650 return; | |
1651 #undef MACROLET | |
1652 } | |
1653 | |
1654 | |
1655 static void | |
1656 ensure_meta_prefix_char_keymapp (Lisp_Object keys, int indx, | |
1657 Lisp_Object keymap) | |
1658 { | |
1659 /* This function can GC */ | |
1660 char buf [255]; | |
1661 Lisp_Object new_keys; | |
1662 int i; | |
1663 Lisp_Object mpc_binding; | |
1664 struct key_data meta_key; | |
1665 | |
1666 if (NILP (Vmeta_prefix_char) || | |
1667 (INTP (Vmeta_prefix_char) && XINT (Vmeta_prefix_char) < 0)) | |
1668 return; | |
1669 | |
1670 define_key_parser (Vmeta_prefix_char, &meta_key); | |
1671 mpc_binding = keymap_lookup_1 (keymap, &meta_key, 0); | |
1672 if (NILP (mpc_binding) || !NILP (Fkeymapp (mpc_binding))) | |
1673 return; | |
1674 | |
1675 if (indx == 0) | |
1676 new_keys = keys; | |
1677 else if (STRINGP (keys)) | |
1678 new_keys = Fsubstring (keys, Qzero, make_int (indx)); | |
1679 else if (VECTORP (keys)) | |
1680 { | |
1681 new_keys = make_vector (indx, Qnil); | |
1682 for (i = 0; i < indx; i++) | |
1683 vector_data (XVECTOR (new_keys)) [i] = | |
1684 vector_data (XVECTOR (keys)) [i]; | |
1685 } | |
1686 else | |
1687 abort (); | |
1688 if (EQ (keys, new_keys)) | |
1689 sprintf (buf, GETTEXT ("can't bind %s: %s has a non-keymap binding"), | |
1690 (char *) string_data (XSTRING (Fkey_description (keys))), | |
1691 (char *) string_data (XSTRING | |
1692 (Fsingle_key_description | |
1693 (Vmeta_prefix_char)))); | |
1694 else | |
1695 sprintf (buf, GETTEXT ("can't bind %s: %s %s has a non-keymap binding"), | |
1696 (char *) string_data (XSTRING (Fkey_description (keys))), | |
1697 (char *) string_data (XSTRING (Fkey_description (new_keys))), | |
1698 (char *) string_data (XSTRING | |
1699 (Fsingle_key_description | |
1700 (Vmeta_prefix_char)))); | |
1701 signal_simple_error (buf, mpc_binding); | |
1702 } | |
1703 | |
1704 DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 3, 0 /* | |
1705 Define key sequence KEYS, in KEYMAP, as DEF. | |
1706 KEYMAP is a keymap object. | |
1707 KEYS is the sequence of keystrokes to bind, described below. | |
1708 DEF is anything that can be a key's definition: | |
1709 nil (means key is undefined in this keymap); | |
1710 a command (a Lisp function suitable for interactive calling); | |
1711 a string or key sequence vector (treated as a keyboard macro); | |
1712 a keymap (to define a prefix key); | |
1713 a symbol; when the key is looked up, the symbol will stand for its | |
1714 function definition, that should at that time be one of the above, | |
1715 or another symbol whose function definition is used, and so on. | |
1716 a cons (STRING . DEFN), meaning that DEFN is the definition | |
1717 (DEFN should be a valid definition in its own right); | |
1718 or a cons (KEYMAP . CHAR), meaning use definition of CHAR in map KEYMAP. | |
1719 | |
1720 Contrary to popular belief, the world is not ASCII. When running under a | |
1721 window manager, XEmacs can tell the difference between, for example, the | |
1722 keystrokes control-h, control-shift-h, and backspace. You can, in fact, | |
1723 bind different commands to each of these. | |
1724 | |
1725 A `key sequence' is a set of keystrokes. A `keystroke' is a keysym and some | |
1726 set of modifiers (such as control and meta). A `keysym' is what is printed | |
1727 on the keys on your keyboard. | |
1728 | |
1729 A keysym may be represented by a symbol, or (if and only if it is equivalent | |
1730 to an ASCII character in the range 32 - 255) by a character or its equivalent | |
1731 ASCII code. The `A' key may be represented by the symbol `A', the character | |
1732 `?A', or by the number 65. The `break' key may be represented only by the | |
1733 symbol `break'. | |
1734 | |
1735 A keystroke may be represented by a list: the last element of the list | |
1736 is the key (a symbol, character, or number, as above) and the | |
1737 preceding elements are the symbolic names of modifier keys (control, | |
1738 meta, super, hyper, alt, and shift). Thus, the sequence control-b is | |
1739 represented by the forms `(control b)', `(control ?b)', and `(control | |
1740 98)'. A keystroke may also be represented by an event object, as | |
1741 returned by the `next-command-event' and `read-key-sequence' | |
1742 functions. | |
1743 | |
1744 Note that in this context, the keystroke `control-b' is *not* represented | |
1745 by the number 2 (the ASCII code for ^B) or the character `?\^B'. See below. | |
1746 | |
1747 The `shift' modifier is somewhat of a special case. You should not (and | |
1748 cannot) use `(meta shift a)' to mean `(meta A)', since for characters that | |
1749 have ASCII equivalents, the state of the shift key is implicit in the | |
1750 keysym (a vs. A). You also cannot say `(shift =)' to mean `+', as that | |
1751 sort of thing varies from keyboard to keyboard. The shift modifier is for | |
1752 use only with characters that do not have a second keysym on the same key, | |
1753 such as `backspace' and `tab'. | |
1754 | |
1755 A key sequence is a vector of keystrokes. As a degenerate case, elements | |
1756 of this vector may also be keysyms if they have no modifiers. That is, | |
1757 the `A' keystroke is represented by all of these forms: | |
1758 A ?A 65 (A) (?A) (65) | |
1759 [A] [?A] [65] [(A)] [(?A)] [(65)] | |
1760 | |
1761 the `control-a' keystroke is represented by these forms: | |
1762 (control A) (control ?A) (control 65) | |
1763 [(control A)] [(control ?A)] [(control 65)] | |
1764 the key sequence `control-c control-a' is represented by these forms: | |
1765 [(control c) (control a)] [(control ?c) (control ?a)] | |
1766 [(control 99) (control 65)] etc. | |
1767 | |
1768 Mouse button clicks work just like keypresses: (control button1) means | |
1769 pressing the left mouse button while holding down the control key. | |
1770 \[(control c) (shift button3)] means control-c, hold shift, click right. | |
1771 | |
1772 Commands may be bound to the mouse-button up-stroke rather than the down- | |
1773 stroke as well. `button1' means the down-stroke, and `button1up' means the | |
1774 up-stroke. Different commands may be bound to the up and down strokes, | |
1775 though that is probably not what you want, so be careful. | |
1776 | |
1777 For backward compatibility, a key sequence may also be represented by a | |
1778 string. In this case, it represents the key sequence(s) that would | |
1779 produce that sequence of ASCII characters in a purely ASCII world. For | |
1780 example, a string containing the ASCII backspace character, \"\\^H\", would | |
1781 represent two key sequences: `(control h)' and `backspace'. Binding a | |
1782 command to this will actually bind both of those key sequences. Likewise | |
1783 for the following pairs: | |
1784 | |
1785 control h backspace | |
1786 control i tab | |
1787 control m return | |
1788 control j linefeed | |
1789 control [ escape | |
1790 control @ control space | |
1791 | |
1792 After binding a command to two key sequences with a form like | |
1793 | |
1794 (define-key global-map \"\\^X\\^I\" \'command-1) | |
1795 | |
1796 it is possible to redefine only one of those sequences like so: | |
1797 | |
1798 (define-key global-map [(control x) (control i)] \'command-2) | |
1799 (define-key global-map [(control x) tab] \'command-3) | |
1800 | |
1801 Of course, all of this applies only when running under a window system. If | |
1802 you're talking to XEmacs through a TTY connection, you don't get any of | |
1803 these features. | |
1804 */ ) | |
1805 (keymap, keys, def) | |
1806 Lisp_Object keymap; | |
1807 Lisp_Object keys; | |
1808 Lisp_Object def; | |
1809 { | |
1810 /* This function can GC */ | |
1811 int idx; | |
1812 int metized = 0; | |
1813 int size; | |
1814 int ascii_hack; | |
1815 struct gcpro gcpro1, gcpro2, gcpro3; | |
1816 | |
1817 if (VECTORP (keys)) | |
1818 size = vector_length (XVECTOR (keys)); | |
1819 else if (STRINGP (keys)) | |
1820 size = string_length (XSTRING (keys)); | |
1821 else if (INTP (keys) || SYMBOLP (keys) || CONSP (keys)) | |
1822 { | |
1823 if (!CONSP (keys)) keys = list1 (keys); | |
1824 size = 1; | |
1825 keys = make_vector (1, keys); /* this is kinda sleazy. */ | |
1826 } | |
1827 else | |
1828 { | |
1829 keys = wrong_type_argument (Qsequencep, keys); | |
1830 size = XINT (Flength (keys)); | |
1831 } | |
1832 if (size == 0) | |
1833 return (Qnil); | |
1834 | |
1835 GCPRO3 (keymap, keys, def); | |
1836 | |
1837 /* ASCII grunge. | |
1838 When the user defines a key which, in a strictly ASCII world, would be | |
1839 produced by two different keys (^J and linefeed, or ^H and backspace, | |
1840 for example) then the binding will be made for both keysyms. | |
1841 | |
1842 This is done if the user binds a command to a string, as in | |
1843 (define-key map "\^H" 'something), but not when using one of the new | |
1844 syntaxes, like (define-key map '(control h) 'something). | |
1845 */ | |
1846 ascii_hack = (STRINGP (keys)); | |
1847 | |
1848 keymap = get_keymap (keymap, 1, 1); | |
1849 | |
1850 idx = 0; | |
1851 while (1) | |
1852 { | |
1853 Lisp_Object c; | |
1854 struct key_data raw_key1; | |
1855 struct key_data raw_key2; | |
1856 | |
1857 if (STRINGP (keys)) | |
1858 c = make_char (string_char (XSTRING (keys), idx)); | |
1859 else | |
1860 { | |
1861 c = vector_data (XVECTOR (keys)) [idx]; | |
1862 if (INTP (c) && | |
1863 (XINT (c) < ' ' || XINT (c) > 127)) | |
1864 args_out_of_range_3 (c, make_int (32), make_int (127)); | |
1865 } | |
1866 | |
1867 define_key_parser (c, &raw_key1); | |
1868 | |
1869 if (!metized && ascii_hack && meta_prefix_char_p (&raw_key1)) | |
1870 { | |
1871 if (idx == (size - 1)) | |
1872 { | |
1873 /* This is a hack to prevent a binding for the meta-prefix-char | |
1874 from being made in a map which already has a non-empty "meta" | |
1875 submap. That is, we can't let both "escape" and "meta" have | |
1876 a binding in the same keymap. This implies that the idiom | |
1877 (define-key my-map "\e" my-escape-map) | |
1878 (define-key my-escape-map "a" 'my-command) | |
1879 no longer works. That's ok. Instead the luser should do | |
1880 (define-key my-map "\ea" 'my-command) | |
1881 or, more correctly | |
1882 (define-key my-map "\M-a" 'my-command) | |
1883 and then perhaps | |
1884 (defvar my-escape-map (lookup-key my-map "\e")) | |
1885 if the luser really wants the map in a variable. | |
1886 */ | |
1887 Lisp_Object mmap; | |
1888 struct gcpro ngcpro1; | |
1889 | |
1890 NGCPRO1 (c); | |
1891 mmap = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META), | |
1892 XKEYMAP (keymap)->table, Qnil); | |
1893 if (!NILP (mmap) | |
1894 && keymap_fullness (mmap) != 0) | |
1895 { | |
1896 Lisp_Object desc | |
1897 = Fsingle_key_description (Vmeta_prefix_char); | |
1898 signal_simple_error_2 | |
1899 ("Map contains meta-bindings, can't bind", desc, keymap); | |
1900 } | |
1901 NUNGCPRO; | |
1902 } | |
1903 else | |
1904 { | |
1905 metized = 1; | |
1906 idx++; | |
1907 continue; | |
1908 } | |
1909 } | |
1910 | |
1911 if (ascii_hack) | |
1912 define_key_alternate_name (&raw_key1, &raw_key2); | |
1913 else | |
1914 { | |
1915 raw_key2.keysym = Qnil; | |
1916 raw_key2.modifiers = 0; | |
1917 } | |
1918 | |
1919 if (metized) | |
1920 { | |
1921 raw_key1.modifiers |= MOD_META; | |
1922 raw_key2.modifiers |= MOD_META; | |
1923 metized = 0; | |
1924 } | |
1925 | |
1926 /* This crap is to make sure that someone doesn't bind something like | |
1927 "C-x M-a" while "C-x ESC" has a non-keymap binding. */ | |
1928 if (raw_key1.modifiers & MOD_META) | |
1929 ensure_meta_prefix_char_keymapp (keys, idx, keymap); | |
1930 | |
1931 if (++idx == size) | |
1932 { | |
1933 keymap_store (keymap, &raw_key1, def); | |
1934 if (ascii_hack && !NILP (raw_key2.keysym)) | |
1935 keymap_store (keymap, &raw_key2, def); | |
1936 UNGCPRO; | |
1937 return def; | |
1938 } | |
1939 | |
1940 { | |
1941 Lisp_Object cmd; | |
1942 struct gcpro ngcpro1; | |
1943 NGCPRO1 (c); | |
1944 | |
1945 cmd = keymap_lookup_1 (keymap, &raw_key1, 0); | |
1946 if (NILP (cmd)) | |
1947 { | |
1948 cmd = Fmake_sparse_keymap (Qnil); | |
1949 XKEYMAP (cmd)->name /* for debugging */ | |
1950 = list2 (make_key_description (&raw_key1, 1), keymap); | |
1951 keymap_store (keymap, &raw_key1, cmd); | |
1952 } | |
1953 if (NILP (Fkeymapp (cmd))) | |
1954 signal_simple_error_2 ("invalid prefix keys in sequence", | |
1955 c, keys); | |
1956 | |
1957 if (ascii_hack && !NILP (raw_key2.keysym) && | |
1958 NILP (keymap_lookup_1 (keymap, &raw_key2, 0))) | |
1959 keymap_store (keymap, &raw_key2, cmd); | |
1960 | |
1961 keymap = get_keymap (cmd, 1, 1); | |
1962 NUNGCPRO; | |
1963 } | |
1964 } | |
1965 } | |
1966 | |
1967 | |
1968 /************************************************************************/ | |
1969 /* Looking up keys in keymaps */ | |
1970 /************************************************************************/ | |
1971 | |
1972 /* We need a very fast (i.e., non-consing) version of lookup-key in order | |
1973 to make where-is-internal really fly. | |
1974 */ | |
1975 | |
1976 struct raw_lookup_key_mapper_closure | |
1977 { | |
1978 int remaining; | |
1979 CONST struct key_data *raw_keys; | |
1980 int raw_keys_count; | |
1981 int keys_so_far; | |
1982 int accept_default; | |
1983 }; | |
1984 | |
1985 static Lisp_Object raw_lookup_key_mapper (Lisp_Object k, void *); | |
1986 | |
1987 /* Caller should gc-protect args (keymaps may autoload) */ | |
1988 static Lisp_Object | |
1989 raw_lookup_key (Lisp_Object keymap, | |
1990 CONST struct key_data *raw_keys, int raw_keys_count, | |
1991 int keys_so_far, int accept_default) | |
1992 { | |
1993 /* This function can GC */ | |
1994 struct raw_lookup_key_mapper_closure c; | |
1995 c.remaining = raw_keys_count - 1; | |
1996 c.raw_keys = raw_keys; | |
1997 c.raw_keys_count = raw_keys_count; | |
1998 c.keys_so_far = keys_so_far; | |
1999 c.accept_default = accept_default; | |
2000 | |
2001 return (traverse_keymaps (keymap, Qnil, raw_lookup_key_mapper, | |
2002 &c)); | |
2003 } | |
2004 | |
2005 static Lisp_Object | |
2006 raw_lookup_key_mapper (Lisp_Object k, void *arg) | |
2007 { | |
2008 /* This function can GC */ | |
2009 struct raw_lookup_key_mapper_closure *c = arg; | |
2010 int accept_default = c->accept_default; | |
2011 int remaining = c->remaining; | |
2012 int keys_so_far = c->keys_so_far; | |
2013 CONST struct key_data *raw_keys = c->raw_keys; | |
2014 Lisp_Object cmd; | |
2015 | |
2016 if (! meta_prefix_char_p (&(raw_keys[0]))) | |
2017 { | |
2018 /* Normal case: every case except the meta-hack (see below). */ | |
2019 cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default); | |
2020 | |
2021 if (remaining == 0) | |
2022 /* Return whatever we found if we're out of keys */ | |
2023 ; | |
2024 else if (NILP (cmd)) | |
2025 /* Found nothing (though perhaps parent map may have binding) */ | |
2026 ; | |
2027 else if (NILP (Fkeymapp (cmd))) | |
2028 /* Didn't find a keymap, and we have more keys. | |
2029 * Return a fixnum to indicate that keys were too long. | |
2030 */ | |
2031 cmd = make_int (keys_so_far + 1); | |
2032 else | |
2033 cmd = raw_lookup_key (cmd, raw_keys + 1, remaining, | |
2034 keys_so_far + 1, accept_default); | |
2035 } | |
2036 else | |
2037 { | |
2038 /* This is a hack so that looking up a key-sequence whose last | |
2039 * element is the meta-prefix-char will return the keymap that | |
2040 * the "meta" keys are stored in, if there is no binding for | |
2041 * the meta-prefix-char (and if this map has a "meta" submap). | |
2042 * If this map doesnt have a "meta" submap, then the | |
2043 * meta-prefix-char is looked up just like any other key. | |
2044 */ | |
2045 if (remaining == 0) | |
2046 { | |
2047 /* First look for the prefix-char directly */ | |
2048 cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default); | |
2049 if (NILP (cmd)) | |
2050 { | |
2051 /* Do kludgy return of the meta-map */ | |
2052 cmd = Fgethash (MAKE_MODIFIER_HASH_KEY (MOD_META), | |
2053 XKEYMAP (k)->table, Qnil); | |
2054 } | |
2055 } | |
2056 else | |
2057 { | |
2058 /* Search for the prefix-char-prefixed sequence directly */ | |
2059 cmd = keymap_lookup_1 (k, &(raw_keys[0]), accept_default); | |
2060 cmd = get_keymap (cmd, 0, 1); | |
2061 if (!NILP (cmd)) | |
2062 cmd = raw_lookup_key (cmd, raw_keys + 1, remaining, | |
2063 keys_so_far + 1, accept_default); | |
2064 else if ((raw_keys[1].modifiers & MOD_META) == 0) | |
2065 { | |
2066 struct key_data metified; | |
2067 metified.keysym = raw_keys[1].keysym; | |
2068 metified.modifiers = raw_keys[1].modifiers | MOD_META; | |
2069 | |
2070 /* Search for meta-next-char sequence directly */ | |
2071 cmd = keymap_lookup_1 (k, &metified, accept_default); | |
2072 if (remaining == 1) | |
2073 ; | |
2074 else | |
2075 { | |
2076 cmd = get_keymap (cmd, 0, 1); | |
2077 if (!NILP (cmd)) | |
2078 cmd = raw_lookup_key (cmd, raw_keys + 2, remaining - 1, | |
2079 keys_so_far + 2, | |
2080 accept_default); | |
2081 } | |
2082 } | |
2083 } | |
2084 } | |
2085 if (accept_default && NILP (cmd)) | |
2086 cmd = XKEYMAP (k)->default_binding; | |
2087 return (cmd); | |
2088 } | |
2089 | |
2090 /* Value is number if `keys' is too long; NIL if valid but has no definition.*/ | |
2091 /* Caller should gc-protect arguments */ | |
2092 static Lisp_Object | |
2093 lookup_keys (Lisp_Object keymap, int nkeys, Lisp_Object *keys, | |
2094 int accept_default) | |
2095 { | |
2096 /* This function can GC */ | |
2097 struct key_data kkk[20]; | |
2098 struct key_data *raw_keys; | |
2099 int i; | |
2100 | |
2101 if (nkeys == 0) | |
2102 return Qnil; | |
2103 | |
2104 if (nkeys > (countof (kkk))) | |
2105 raw_keys = kkk; | |
2106 else | |
2107 raw_keys = (struct key_data *) alloca (sizeof (struct key_data) * nkeys); | |
2108 | |
2109 for (i = 0; i < nkeys; i++) | |
2110 { | |
2111 define_key_parser (keys[i], &(raw_keys[i])); | |
2112 } | |
2113 return (raw_lookup_key (keymap, raw_keys, nkeys, 0, | |
2114 accept_default)); | |
2115 } | |
2116 | |
2117 static Lisp_Object | |
2118 lookup_events (Lisp_Object event_head, int nmaps, Lisp_Object keymaps[], | |
2119 int accept_default) | |
2120 { | |
2121 /* This function can GC */ | |
2122 struct key_data kkk[20]; | |
2123 Lisp_Object event; | |
2124 | |
2125 int nkeys; | |
2126 struct key_data *raw_keys; | |
2127 Lisp_Object tem = Qnil; | |
2128 struct gcpro gcpro1, gcpro2; | |
2129 int iii; | |
2130 | |
2131 CHECK_LIVE_EVENT (event_head); | |
2132 | |
2133 nkeys = event_chain_count (event_head); | |
2134 | |
2135 if (nkeys < (countof (kkk))) | |
2136 raw_keys = kkk; | |
2137 else | |
2138 raw_keys = (struct key_data *) alloca (sizeof (struct key_data) * nkeys); | |
2139 | |
2140 nkeys = 0; | |
2141 EVENT_CHAIN_LOOP (event, event_head) | |
2142 define_key_parser (event, &(raw_keys[nkeys++])); | |
2143 GCPRO2 (keymaps[0], event_head); | |
2144 gcpro1.nvars = nmaps; | |
2145 /* ####raw_keys[].keysym slots aren't gc-protected. We rely (but shouldn't) | |
2146 * on somebody else somewhere (obarray) having a pointer to all keysyms. */ | |
2147 for (iii = 0; iii < nmaps; iii++) | |
2148 { | |
2149 tem = raw_lookup_key (keymaps[iii], raw_keys, nkeys, 0, | |
2150 accept_default); | |
2151 if (INTP (tem)) | |
2152 { | |
2153 /* Too long in some local map means don't look at global map */ | |
2154 tem = Qnil; | |
2155 break; | |
2156 } | |
2157 else if (!NILP (tem)) | |
2158 break; | |
2159 } | |
2160 UNGCPRO; | |
2161 return (tem); | |
2162 } | |
2163 | |
2164 DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0 /* | |
2165 In keymap KEYMAP, look up key-sequence KEYS. Return the definition. | |
2166 Nil is returned if KEYS is unbound. See documentation of `define-key' | |
2167 for valid key definitions and key-sequence specifications. | |
2168 A number is returned if KEYS is \"too long\"; that is, the leading | |
2169 characters fail to be a valid sequence of prefix characters in KEYMAP. | |
2170 The number is how many characters at the front of KEYS | |
2171 it takes to reach a non-prefix command. | |
2172 */ ) | |
2173 (keymap, keys, accept_default) | |
2174 Lisp_Object keymap, keys, accept_default; | |
2175 { | |
2176 /* This function can GC */ | |
2177 if (VECTORP (keys)) | |
2178 { | |
2179 return lookup_keys (keymap, | |
2180 vector_length (XVECTOR (keys)), | |
2181 vector_data (XVECTOR (keys)), | |
2182 !NILP (accept_default)); | |
2183 } | |
2184 else if (SYMBOLP (keys) || INTP (keys) || CONSP (keys)) | |
2185 { | |
2186 return lookup_keys (keymap, 1, &keys, | |
2187 !NILP (accept_default)); | |
2188 } | |
2189 else if (!STRINGP (keys)) | |
2190 { | |
2191 keys = wrong_type_argument (Qsequencep, keys); | |
2192 return Flookup_key (keymap, keys, accept_default); | |
2193 } | |
2194 else | |
2195 { | |
2196 int length = string_char_length (XSTRING (keys)); | |
2197 int i; | |
2198 struct key_data *raw_keys | |
2199 = (struct key_data *) alloca (sizeof (struct key_data) * length); | |
2200 if (length == 0) | |
2201 return Qnil; | |
2202 | |
2203 for (i = 0; i < length; i++) | |
2204 { | |
2205 Emchar n = string_char (XSTRING (keys), i); | |
2206 define_key_parser (make_char (n), &(raw_keys[i])); | |
2207 } | |
2208 return (raw_lookup_key (keymap, raw_keys, length, 0, | |
2209 !NILP (accept_default))); | |
2210 } | |
2211 } | |
2212 | |
2213 /* Given a key sequence, returns a list of keymaps to search for bindings. | |
2214 Does all manner of semi-hairy heuristics, like looking in the current | |
2215 buffer's map before looking in the global map and looking in the local | |
2216 map of the buffer in which the mouse was clicked in event0 is a click. | |
2217 | |
2218 It would be kind of nice if this were in Lisp so that this semi-hairy | |
2219 semi-heuristic command-lookup behaviour could be readily understood and | |
2220 customised. However, this needs to be pretty fast, or performance of | |
2221 keyboard macros goes to shit; putting this in lisp slows macros down | |
2222 2-3x. And they're already slower than v18 by 5-6x. | |
2223 */ | |
2224 | |
2225 struct relevant_maps | |
2226 { | |
2227 int nmaps; | |
2228 unsigned int max_maps; | |
2229 Lisp_Object *maps; | |
2230 struct gcpro *gcpro; | |
2231 }; | |
2232 | |
2233 static void get_relevant_extent_keymaps (Lisp_Object pos, | |
2234 Lisp_Object buffer_or_string, | |
2235 Lisp_Object glyph, | |
2236 struct relevant_maps *closure); | |
2237 static void get_relevant_minor_maps (Lisp_Object buffer, | |
2238 struct relevant_maps *closure); | |
2239 | |
2240 static void | |
2241 relevant_map_push (Lisp_Object map, struct relevant_maps *closure) | |
2242 { | |
2243 unsigned int nmaps = closure->nmaps; | |
2244 | |
2245 if (!KEYMAPP (map)) | |
2246 return; | |
2247 closure->nmaps = nmaps + 1; | |
2248 if (nmaps < closure->max_maps) | |
2249 { | |
2250 closure->maps[nmaps] = map; | |
2251 closure->gcpro->nvars = nmaps; | |
2252 } | |
2253 } | |
2254 | |
2255 static int | |
2256 get_relevant_keymaps (Lisp_Object keys, | |
2257 int max_maps, Lisp_Object maps[]) | |
2258 { | |
2259 /* This function can GC */ | |
2260 Lisp_Object terminal = Qnil; | |
2261 struct gcpro gcpro1; | |
2262 struct relevant_maps closure; | |
2263 struct console *con; | |
2264 | |
2265 GCPRO1 (*maps); | |
2266 gcpro1.nvars = 0; | |
2267 closure.nmaps = 0; | |
2268 closure.max_maps = max_maps; | |
2269 closure.maps = maps; | |
2270 closure.gcpro = &gcpro1; | |
2271 | |
2272 if (EVENTP (keys)) | |
2273 terminal = event_chain_tail (keys); | |
2274 else if (VECTORP (keys)) | |
2275 { | |
2276 int len = vector_length (XVECTOR (keys)); | |
2277 if (len > 0) | |
2278 terminal = vector_data (XVECTOR (keys))[len - 1]; | |
2279 } | |
2280 | |
2281 if (EVENTP (terminal)) | |
2282 { | |
2283 CHECK_LIVE_EVENT (terminal); | |
2284 con = event_console_or_selected (terminal); | |
2285 } | |
2286 else | |
2287 con = XCONSOLE (Vselected_console); | |
2288 | |
2289 if (KEYMAPP (con->overriding_terminal_local_map) | |
2290 || KEYMAPP (Voverriding_local_map)) | |
2291 { | |
2292 if (KEYMAPP (con->overriding_terminal_local_map)) | |
2293 relevant_map_push (con->overriding_terminal_local_map, &closure); | |
2294 if (KEYMAPP (Voverriding_local_map)) | |
2295 relevant_map_push (Voverriding_local_map, &closure); | |
2296 } | |
2297 else if (!EVENTP (terminal) | |
2298 || (XEVENT (terminal)->event_type != button_press_event | |
2299 && XEVENT (terminal)->event_type != button_release_event)) | |
2300 { | |
2301 Lisp_Object tem; | |
2302 XSETBUFFER (tem, current_buffer); | |
2303 /* It's not a mouse event; order of keymaps searched is: | |
2304 o keymap of any/all extents under the mouse | |
2305 o minor-mode maps | |
2306 o local-map of current-buffer | |
2307 o global-map | |
2308 */ | |
2309 /* The terminal element of the lookup may be nil or a keysym. | |
2310 In those cases we don't want to check for an extent | |
2311 keymap. */ | |
2312 if (EVENTP (terminal)) | |
2313 { | |
2314 get_relevant_extent_keymaps (make_int (BUF_PT (current_buffer)), | |
2315 tem, Qnil, &closure); | |
2316 } | |
2317 get_relevant_minor_maps (tem, &closure); | |
2318 | |
2319 tem = current_buffer->keymap; | |
2320 if (!NILP (tem)) | |
2321 relevant_map_push (tem, &closure); | |
2322 } | |
2323 #ifdef HAVE_WINDOW_SYSTEM | |
2324 else | |
2325 { | |
2326 /* It's a mouse event; order of keymaps searched is: | |
2327 o local-map of mouse-grabbed-buffer | |
2328 o keymap of any/all extents under the mouse | |
2329 if the mouse is over a modeline: | |
2330 o modeline-map of buffer corresponding to that modeline | |
2331 o else, local-map of buffer under the mouse | |
2332 o minor-mode maps | |
2333 o local-map of current-buffer | |
2334 o global-map | |
2335 */ | |
2336 Lisp_Object window = Fevent_window (terminal); | |
2337 | |
2338 if (BUFFERP (Vmouse_grabbed_buffer)) | |
2339 { | |
2340 Lisp_Object map = XBUFFER (Vmouse_grabbed_buffer)->keymap; | |
2341 | |
2342 get_relevant_minor_maps (Vmouse_grabbed_buffer, &closure); | |
2343 if (!NILP (map)) | |
2344 relevant_map_push (map, &closure); | |
2345 } | |
2346 | |
2347 if (!NILP (window)) | |
2348 { | |
2349 Lisp_Object buffer = Fwindow_buffer (window); | |
2350 | |
2351 if (!NILP (buffer)) | |
2352 { | |
2353 if (!NILP (Fevent_over_modeline_p (terminal))) | |
2354 { | |
2355 Lisp_Object map = symbol_value_in_buffer (Qmodeline_map, | |
2356 buffer); | |
2357 | |
2358 get_relevant_extent_keymaps | |
2359 (Fevent_modeline_position (terminal), | |
2360 XBUFFER (buffer)->generated_modeline_string, | |
2361 /* #### third arg should maybe be a glyph. */ | |
2362 Qnil, &closure); | |
2363 | |
2364 if (!UNBOUNDP (map) && !NILP (map)) | |
2365 relevant_map_push (get_keymap (map, 1, 1), &closure); | |
2366 } | |
2367 else | |
2368 { | |
2369 get_relevant_extent_keymaps (Fevent_point (terminal), buffer, | |
2370 Fevent_glyph_extent (terminal), | |
2371 &closure); | |
2372 } | |
2373 | |
2374 if (!EQ (buffer, Vmouse_grabbed_buffer)) /* already pushed */ | |
2375 { | |
2376 get_relevant_minor_maps (buffer, &closure); | |
2377 relevant_map_push (XBUFFER (buffer)->keymap, &closure); | |
2378 } | |
2379 } | |
2380 } | |
2381 else if (!NILP (Fevent_over_toolbar_p (terminal))) | |
2382 { | |
2383 Lisp_Object map = Fsymbol_value (Qtoolbar_map); | |
2384 | |
2385 if (!UNBOUNDP (map) && !NILP (map)) | |
2386 relevant_map_push (map, &closure); | |
2387 } | |
2388 } | |
2389 #endif /* HAVE_WINDOW_SYSTEM */ | |
2390 | |
2391 { | |
2392 int nmaps = closure.nmaps; | |
2393 /* Silently truncate at 100 keymaps to prevent infinite losssage */ | |
2394 if (nmaps >= max_maps && max_maps > 0) | |
2395 maps[max_maps - 1] = Vcurrent_global_map; | |
2396 else | |
2397 maps[nmaps] = Vcurrent_global_map; | |
2398 UNGCPRO; | |
2399 return (nmaps + 1); | |
2400 } | |
2401 } | |
2402 | |
2403 /* Returns a set of keymaps extracted from the extents at POS in | |
2404 BUFFER_OR_STRING. The GLYPH arg, if specified, is one more extent | |
2405 to look for a keymap in, and if it has one, its keymap will be the | |
2406 first element in the list returned. This is so we can correctly | |
2407 search the keymaps associated with glyphs which may be physically | |
2408 disjoint from their extents: for example, if a glyph is out in the | |
2409 margin, we should still consult the kemyap of that glyph's extent, | |
2410 which may not itself be under the mouse. | |
2411 */ | |
2412 static void | |
2413 get_relevant_extent_keymaps (Lisp_Object pos, Lisp_Object buffer_or_string, | |
2414 Lisp_Object glyph, | |
2415 struct relevant_maps *closure) | |
2416 { | |
2417 /* This function can GC */ | |
2418 /* the glyph keymap, if any, comes first. | |
2419 (Processing it twice is no big deal: noop.) */ | |
2420 if (!NILP (glyph)) | |
2421 { | |
2422 Lisp_Object keymap = Fextent_property (glyph, Qkeymap, Qnil); | |
2423 if (!NILP (keymap)) | |
2424 relevant_map_push (get_keymap (keymap, 1, 1), closure); | |
2425 } | |
2426 | |
2427 /* Next check the extents at the text position, if any */ | |
2428 if (!NILP (pos)) | |
2429 { | |
2430 Lisp_Object extent; | |
2431 for (extent = Fextent_at (pos, buffer_or_string, Qkeymap, Qnil, Qnil); | |
2432 !NILP (extent); | |
2433 extent = Fextent_at (pos, buffer_or_string, Qkeymap, extent, Qnil)) | |
2434 { | |
2435 Lisp_Object keymap = Fextent_property (extent, Qkeymap, Qnil); | |
2436 if (!NILP (keymap)) | |
2437 relevant_map_push (get_keymap (keymap, 1, 1), closure); | |
2438 QUIT; | |
2439 } | |
2440 } | |
2441 } | |
2442 | |
2443 static Lisp_Object | |
2444 minor_mode_keymap_predicate (Lisp_Object assoc, Lisp_Object buffer) | |
2445 { | |
2446 /* This function can GC */ | |
2447 if (CONSP (assoc)) | |
2448 { | |
2449 Lisp_Object sym = XCAR (assoc); | |
2450 if (SYMBOLP (sym)) | |
2451 { | |
2452 Lisp_Object val = symbol_value_in_buffer (sym, buffer); | |
2453 if (!NILP (val) && !UNBOUNDP (val)) | |
2454 { | |
2455 Lisp_Object map = get_keymap (XCDR (assoc), 0, 1); | |
2456 return (map); | |
2457 } | |
2458 } | |
2459 } | |
2460 return (Qnil); | |
2461 } | |
2462 | |
2463 static void | |
2464 get_relevant_minor_maps (Lisp_Object buffer, struct relevant_maps *closure) | |
2465 { | |
2466 /* This function can GC */ | |
2467 Lisp_Object alist; | |
2468 | |
2469 /* Will you ever lose badly if you make this circular! */ | |
2470 for (alist = symbol_value_in_buffer (Qminor_mode_map_alist, buffer); | |
2471 CONSP (alist); | |
2472 alist = XCDR (alist)) | |
2473 { | |
2474 Lisp_Object m = minor_mode_keymap_predicate (XCAR (alist), | |
2475 buffer); | |
2476 if (!NILP (m)) relevant_map_push (m, closure); | |
2477 QUIT; | |
2478 } | |
2479 } | |
2480 | |
2481 /* #### Would map-current-keymaps be a better thing?? */ | |
2482 DEFUN ("current-keymaps", Fcurrent_keymaps, Scurrent_keymaps, 0, 1, 0 /* | |
2483 Return a list of the current keymaps that will be searched for bindings. | |
2484 This lists keymaps such as the current local map and the minor-mode maps, | |
2485 but does not list the parents of those keymaps. | |
2486 EVENT-OR-KEYS controls which keymaps will be listed. | |
2487 If EVENT-OR-KEYS is a mouse event (or a vector whose last element is a | |
2488 mouse event), the keymaps for that mouse event will be listed (see | |
2489 `key-binding'). Otherwise, the keymaps for key presses will be listed. | |
2490 */ ) | |
2491 (event_or_keys) | |
2492 Lisp_Object event_or_keys; | |
2493 { | |
2494 /* This function can GC */ | |
2495 struct gcpro gcpro1; | |
2496 Lisp_Object maps[100]; | |
2497 Lisp_Object *gubbish = maps; | |
2498 int nmaps; | |
2499 | |
2500 GCPRO1 (event_or_keys); | |
2501 nmaps = get_relevant_keymaps (event_or_keys, countof (maps), | |
2502 gubbish); | |
2503 if (nmaps > countof (maps)) | |
2504 { | |
2505 gubbish = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); | |
2506 nmaps = get_relevant_keymaps (event_or_keys, nmaps, gubbish); | |
2507 } | |
2508 UNGCPRO; | |
2509 return (Flist (nmaps, gubbish)); | |
2510 } | |
2511 | |
2512 DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 2, 0 /* | |
2513 Return the binding for command KEYS in current keymaps. | |
2514 KEYS is a string, a vector of events, or a vector of key-description lists | |
2515 as described in the documentation for the `define-key' function. | |
2516 The binding is probably a symbol with a function definition; see | |
2517 the documentation for `lookup-key' for more information. | |
2518 | |
2519 For key-presses, the order of keymaps searched is: | |
2520 - the `keymap' property of any extent(s) at point; | |
2521 - any applicable minor-mode maps; | |
2522 - the current-local-map of the current-buffer; | |
2523 - the current global map. | |
2524 | |
2525 For mouse-clicks, the order of keymaps searched is: | |
2526 - the current-local-map of the `mouse-grabbed-buffer' if any; | |
2527 - the `keymap' property of any extent(s) at the position of the click | |
2528 (this includes modeline extents); | |
2529 - the modeline-map of the buffer corresponding to the modeline under | |
2530 the mouse (if the click happened over a modeline); | |
2531 - the value of toolbar-map in the current-buffer (if the click | |
2532 happened over a toolbar); | |
2533 - the current-local-map of the buffer under the mouse (does not | |
2534 apply to toolbar clicks); | |
2535 - any applicable minor-mode maps; | |
2536 - the current global map. | |
2537 | |
2538 Note that if `overriding-local-map' or `overriding-terminal-local-map' | |
2539 is non-nil, *only* those two maps and the current global map are searched. | |
2540 */ ) | |
2541 (keys, accept_default) | |
2542 Lisp_Object keys, accept_default; | |
2543 { | |
2544 /* This function can GC */ | |
2545 int i; | |
2546 Lisp_Object maps[100]; | |
2547 int nmaps; | |
2548 struct gcpro gcpro1, gcpro2; | |
2549 GCPRO2 (keys, accept_default); /* get_relevant_keymaps may autoload */ | |
2550 | |
2551 nmaps = get_relevant_keymaps (keys, countof (maps), maps); | |
2552 | |
2553 UNGCPRO; | |
2554 | |
2555 if (EVENTP (keys)) /* unadvertised "feature" for the future */ | |
2556 return (lookup_events (keys, nmaps, maps, | |
2557 !NILP (accept_default))); | |
2558 | |
2559 for (i = 0; i < nmaps; i++) | |
2560 { | |
2561 Lisp_Object tem = Flookup_key (maps[i], keys, | |
2562 accept_default); | |
2563 if (INTP (tem)) | |
2564 { | |
2565 /* Too long in some local map means don't look at global map */ | |
2566 return (Qnil); | |
2567 } | |
2568 else if (!NILP (tem)) | |
2569 return (tem); | |
2570 } | |
2571 return (Qnil); | |
2572 } | |
2573 | |
2574 static Lisp_Object | |
2575 process_event_binding_result (Lisp_Object result) | |
2576 { | |
2577 if (EQ (result, Qundefined)) | |
2578 /* The suppress-keymap function binds keys to 'undefined - special-case | |
2579 that here, so that being bound to that has the same error-behavior as | |
2580 not being defined at all. | |
2581 */ | |
2582 result = Qnil; | |
2583 if (!NILP (result)) | |
2584 { | |
2585 Lisp_Object map; | |
2586 /* Snap out possible keymap indirections */ | |
2587 map = get_keymap (result, 0, 1); | |
2588 if (!NILP (map)) | |
2589 result = map; | |
2590 } | |
2591 | |
2592 return result; | |
2593 } | |
2594 | |
2595 /* Attempts to find a command corresponding to the event-sequence | |
2596 whose head is event0 (sequence is threaded though event_next). | |
2597 | |
2598 The return value will be | |
2599 | |
2600 -- nil (there is no binding; this will also be returned | |
2601 whenever the event chain is "too long", i.e. there | |
2602 is a non-nil, non-keymap binding for a prefix of | |
2603 the event chain) | |
2604 -- a keymap (part of a command has been specified) | |
2605 -- a command (anything that satisfies `commandp'; this includes | |
2606 some symbols, lists, subrs, strings, vectors, and | |
2607 compiled-function objects) */ | |
2608 Lisp_Object | |
2609 event_binding (Lisp_Object event0, int accept_default) | |
2610 { | |
2611 /* This function can GC */ | |
2612 Lisp_Object maps[100]; | |
2613 int nmaps; | |
2614 | |
2615 assert (EVENTP (event0)); | |
2616 | |
2617 nmaps = get_relevant_keymaps (event0, countof (maps), maps); | |
2618 return (process_event_binding_result | |
2619 (lookup_events (event0, nmaps, maps, accept_default))); | |
2620 } | |
2621 | |
2622 /* Attempts to find a function key mapping corresponding to the | |
2623 event-sequence whose head is event0 (sequence is threaded through | |
2624 event_next). The return value will be the same as for event_binding(). */ | |
2625 Lisp_Object | |
2626 munging_key_map_event_binding (Lisp_Object event0, | |
2627 enum munge_me_out_the_door munge) | |
2628 { | |
2629 Lisp_Object the_map; | |
2630 Lisp_Object maps[1]; | |
2631 | |
2632 if (munge == MUNGE_ME_FUNCTION_KEY) | |
2633 { | |
2634 struct console *c = event_console_or_selected (event0); | |
2635 | |
2636 the_map = CONSOLE_FUNCTION_KEY_MAP (c); | |
2637 } | |
2638 else | |
2639 the_map = Vkey_translation_map; | |
2640 | |
2641 if (NILP (the_map)) | |
2642 return Qnil; | |
2643 | |
2644 maps[0] = the_map; | |
2645 return process_event_binding_result (lookup_events (event0, 1, maps, 1)); | |
2646 } | |
2647 | |
2648 | |
2649 /************************************************************************/ | |
2650 /* Setting/querying the global and local maps */ | |
2651 /************************************************************************/ | |
2652 | |
2653 DEFUN ("use-global-map", Fuse_global_map, Suse_global_map, 1, 1, 0 /* | |
2654 Select KEYMAP as the global keymap. | |
2655 */ ) | |
2656 (keymap) | |
2657 Lisp_Object keymap; | |
2658 { | |
2659 /* This function can GC */ | |
2660 keymap = get_keymap (keymap, 1, 1); | |
2661 Vcurrent_global_map = keymap; | |
2662 return Qnil; | |
2663 } | |
2664 | |
2665 DEFUN ("use-local-map", Fuse_local_map, Suse_local_map, 1, 2, 0 /* | |
2666 Select KEYMAP as the local keymap in BUFFER. | |
2667 If KEYMAP is nil, that means no local keymap. | |
2668 If BUFFER is nil, the current buffer is assumed. | |
2669 */ ) | |
2670 (keymap, buffer) | |
2671 Lisp_Object keymap, buffer; | |
2672 { | |
2673 /* This function can GC */ | |
2674 struct buffer *b = decode_buffer (buffer, 0); | |
2675 if (!NILP (keymap)) | |
2676 keymap = get_keymap (keymap, 1, 1); | |
2677 | |
2678 b->keymap = keymap; | |
2679 | |
2680 return Qnil; | |
2681 } | |
2682 | |
2683 DEFUN ("current-local-map", Fcurrent_local_map, Scurrent_local_map, 0, 1, 0 /* | |
2684 Return BUFFER's local keymap, or nil if it has none. | |
2685 If BUFFER is nil, the current buffer is assumed. | |
2686 */ ) | |
2687 (buffer) | |
2688 Lisp_Object buffer; | |
2689 { | |
2690 struct buffer *b = decode_buffer (buffer, 0); | |
2691 return b->keymap; | |
2692 } | |
2693 | |
2694 DEFUN ("current-global-map", Fcurrent_global_map, Scurrent_global_map, 0, 0, 0 /* | |
2695 Return the current global keymap. | |
2696 */ ) | |
2697 () | |
2698 { | |
2699 return (Vcurrent_global_map); | |
2700 } | |
2701 | |
2702 | |
2703 /************************************************************************/ | |
2704 /* Mapping over keymap elements */ | |
2705 /************************************************************************/ | |
2706 | |
2707 /* Since keymaps are arranged in a hierarchy, one keymap per bucky bit or | |
2708 prefix key, it's not entirely objvious what map-keymap should do, but | |
2709 what it does is: map over all keys in this map; then recursively map | |
2710 over all submaps of this map that are "bucky" submaps. This means that, | |
2711 when mapping over a keymap, it appears that "x" and "C-x" are in the | |
2712 same map, although "C-x" is really in the "control" submap of this one. | |
2713 However, since we don't recursively descend the submaps that are bound | |
2714 to prefix keys (like C-x, C-h, etc) the caller will have to recurse on | |
2715 those explicitly, if that's what they want. | |
2716 | |
2717 So the end result of this is that the bucky keymaps (the ones indexed | |
2718 under the large integers returned from MAKE_MODIFIER_HASH_KEY()) are | |
2719 invisible from elisp. They're just an implementation detail that code | |
2720 outside of this file doesn't need to know about. | |
2721 */ | |
2722 | |
2723 struct map_keymap_unsorted_closure | |
2724 { | |
2725 void (*fn) (CONST struct key_data *, Lisp_Object binding, void *arg); | |
2726 void *arg; | |
2727 unsigned int modifiers; | |
2728 }; | |
2729 | |
2730 /* used by map_keymap() */ | |
2731 static void | |
2732 map_keymap_unsorted_mapper (CONST void *hash_key, void *hash_contents, | |
2733 void *map_keymap_unsorted_closure) | |
2734 { | |
2735 /* This function can GC */ | |
2736 Lisp_Object keysym; | |
2737 Lisp_Object contents; | |
2738 struct map_keymap_unsorted_closure *closure = map_keymap_unsorted_closure; | |
2739 unsigned int modifiers = closure->modifiers; | |
2740 unsigned int mod_bit; | |
2741 CVOID_TO_LISP (keysym, hash_key); | |
2742 VOID_TO_LISP (contents, hash_contents); | |
2743 mod_bit = MODIFIER_HASH_KEY_BITS (keysym); | |
2744 if (mod_bit != 0) | |
2745 { | |
2746 int omod = modifiers; | |
2747 closure->modifiers = (modifiers | mod_bit); | |
2748 contents = get_keymap (contents, 1, 1); | |
2749 elisp_maphash (map_keymap_unsorted_mapper, | |
2750 XKEYMAP (contents)->table, | |
2751 map_keymap_unsorted_closure); | |
2752 closure->modifiers = omod; | |
2753 } | |
2754 else | |
2755 { | |
2756 struct key_data key; | |
2757 key.keysym = keysym; | |
2758 key.modifiers = modifiers; | |
2759 ((*closure->fn) (&key, contents, closure->arg)); | |
2760 } | |
2761 } | |
2762 | |
2763 | |
2764 struct map_keymap_sorted_closure | |
2765 { | |
2766 Lisp_Object *result_locative; | |
2767 }; | |
2768 | |
2769 /* used by map_keymap_sorted() */ | |
2770 static void | |
2771 map_keymap_sorted_mapper (CONST void *hash_key, void *hash_contents, | |
2772 void *map_keymap_sorted_closure) | |
2773 { | |
2774 struct map_keymap_sorted_closure *cl = map_keymap_sorted_closure; | |
2775 Lisp_Object key, contents; | |
2776 Lisp_Object *list = cl->result_locative; | |
2777 CVOID_TO_LISP (key, hash_key); | |
2778 VOID_TO_LISP (contents, hash_contents); | |
2779 *list = Fcons (Fcons (key, contents), *list); | |
2780 } | |
2781 | |
2782 | |
2783 /* used by map_keymap_sorted(), describe_map_sort_predicate(), | |
2784 and keymap_submaps(). | |
2785 */ | |
2786 static int | |
2787 map_keymap_sort_predicate (Lisp_Object obj1, Lisp_Object obj2, | |
2788 Lisp_Object pred) | |
2789 { | |
2790 /* obj1 and obj2 are conses with keysyms in their cars. Cdrs are ignored. | |
2791 */ | |
2792 unsigned int bit1, bit2; | |
2793 int sym1_p = 0; | |
2794 int sym2_p = 0; | |
2795 obj1 = XCAR (obj1); | |
2796 obj2 = XCAR (obj2); | |
2797 | |
2798 if (EQ (obj1, obj2)) | |
2799 return -1; | |
2800 bit1 = MODIFIER_HASH_KEY_BITS (obj1); | |
2801 bit2 = MODIFIER_HASH_KEY_BITS (obj2); | |
2802 | |
2803 /* If either is a symbol with a character-set-property, then sort it by | |
2804 that code instead of alphabetically. | |
2805 */ | |
2806 if (! bit1 && SYMBOLP (obj1)) | |
2807 { | |
2808 Lisp_Object code = Fget (obj1, Vcharacter_set_property, Qnil); | |
2809 if (INTP (code)) | |
2810 obj1 = code, sym1_p = 1; | |
2811 } | |
2812 if (! bit2 && SYMBOLP (obj2)) | |
2813 { | |
2814 Lisp_Object code = Fget (obj2, Vcharacter_set_property, Qnil); | |
2815 if (INTP (code)) | |
2816 obj2 = code, sym2_p = 1; | |
2817 } | |
2818 | |
2819 /* all symbols (non-ASCIIs) come after characters (ASCIIs) */ | |
2820 if (XTYPE (obj1) != XTYPE (obj2)) | |
2821 return (SYMBOLP (obj2) ? 1 : -1); | |
2822 | |
2823 if (! bit1 && CHARP (obj1)) /* they're both ASCII */ | |
2824 { | |
2825 int o1 = XCHAR (obj1); | |
2826 int o2 = XCHAR (obj2); | |
2827 if (o1 == o2 && /* If one started out as a symbol and the */ | |
2828 sym1_p != sym2_p) /* other didn't, the symbol comes last. */ | |
2829 return (sym2_p ? 1 : -1); | |
2830 | |
2831 return ((o1 < o2) ? 1 : -1); /* else just compare them */ | |
2832 } | |
2833 | |
2834 /* else they're both symbols. If they're both buckys, then order them. */ | |
2835 if (bit1 && bit2) | |
2836 return ((bit1 < bit2) ? 1 : -1); | |
2837 | |
2838 /* if only one is a bucky, then it comes later */ | |
2839 if (bit1 || bit2) | |
2840 return (bit2 ? 1 : -1); | |
2841 | |
2842 /* otherwise, string-sort them. */ | |
2843 { | |
2844 char *s1 = (char *) string_data (XSYMBOL (obj1)->name); | |
2845 char *s2 = (char *) string_data (XSYMBOL (obj2)->name); | |
2846 return ( | |
2847 #ifdef I18N2 | |
2848 (0 > strcoll (s1, s2)) | |
2849 #else | |
2850 (0 > strcmp (s1, s2)) | |
2851 #endif | |
2852 ? 1 : -1); | |
2853 } | |
2854 } | |
2855 | |
2856 | |
2857 /* used by map_keymap() */ | |
2858 static void | |
2859 map_keymap_sorted (Lisp_Object keymap_table, | |
2860 unsigned int modifiers, | |
2861 void (*function) (CONST struct key_data *key, | |
2862 Lisp_Object binding, | |
2863 void *map_keymap_sorted_closure), | |
2864 void *map_keymap_sorted_closure) | |
2865 { | |
2866 /* This function can GC */ | |
2867 struct gcpro gcpro1; | |
2868 Lisp_Object contents = Qnil; | |
2869 | |
2870 if (XINT (Fhashtable_fullness (keymap_table)) == 0) | |
2871 return; | |
2872 | |
2873 GCPRO1 (contents); | |
2874 | |
2875 { | |
2876 struct map_keymap_sorted_closure c1; | |
2877 c1.result_locative = &contents; | |
2878 elisp_maphash (map_keymap_sorted_mapper, keymap_table, &c1); | |
2879 } | |
2880 contents = list_sort (contents, Qnil, map_keymap_sort_predicate); | |
2881 for (; !NILP (contents); contents = XCDR (contents)) | |
2882 { | |
2883 Lisp_Object keysym = XCAR (XCAR (contents)); | |
2884 Lisp_Object binding = XCDR (XCAR (contents)); | |
2885 unsigned int sub_bits = MODIFIER_HASH_KEY_BITS (keysym); | |
2886 if (sub_bits != 0) | |
2887 map_keymap_sorted (XKEYMAP (get_keymap (binding, | |
2888 1, 1))->table, | |
2889 (modifiers | sub_bits), | |
2890 function, | |
2891 map_keymap_sorted_closure); | |
2892 else | |
2893 { | |
2894 struct key_data k; | |
2895 k.keysym = keysym; | |
2896 k.modifiers = modifiers; | |
2897 ((*function) (&k, binding, map_keymap_sorted_closure)); | |
2898 } | |
2899 } | |
2900 UNGCPRO; | |
2901 } | |
2902 | |
2903 | |
2904 /* used by Fmap_keymap() */ | |
2905 static void | |
2906 map_keymap_mapper (CONST struct key_data *key, | |
2907 Lisp_Object binding, | |
2908 void *function) | |
2909 { | |
2910 /* This function can GC */ | |
2911 Lisp_Object fn; | |
2912 VOID_TO_LISP (fn, function); | |
2913 call2 (fn, make_key_description (key, 1), binding); | |
2914 } | |
2915 | |
2916 | |
2917 static void | |
2918 map_keymap (Lisp_Object keymap_table, int sort_first, | |
2919 void (*function) (CONST struct key_data *key, | |
2920 Lisp_Object binding, | |
2921 void *fn_arg), | |
2922 void *fn_arg) | |
2923 { | |
2924 /* This function can GC */ | |
2925 if (sort_first) | |
2926 map_keymap_sorted (keymap_table, 0, function, fn_arg); | |
2927 else | |
2928 { | |
2929 struct map_keymap_unsorted_closure map_keymap_unsorted_closure; | |
2930 map_keymap_unsorted_closure.fn = function; | |
2931 map_keymap_unsorted_closure.arg = fn_arg; | |
2932 map_keymap_unsorted_closure.modifiers = 0; | |
2933 elisp_maphash (map_keymap_unsorted_mapper, keymap_table, | |
2934 &map_keymap_unsorted_closure); | |
2935 } | |
2936 } | |
2937 | |
2938 DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 3, 0 /* | |
2939 Apply FUNCTION to each element of KEYMAP. | |
2940 FUNCTION will be called with two arguments: a key-description list, and | |
2941 the binding. The order in which the elements of the keymap are passed to | |
2942 the function is unspecified. If the function inserts new elements into | |
2943 the keymap, it may or may not be called with them later. No element of | |
2944 the keymap will ever be passed to the function more than once. | |
2945 | |
2946 The function will not be called on elements of this keymap's parents | |
2947 (see the function `keymap-parents') or upon keymaps which are contained | |
2948 within this keymap (multi-character definitions). | |
2949 It will be called on \"meta\" characters since they are not really | |
2950 two-character sequences. | |
2951 | |
2952 If the optional third argument SORT-FIRST is non-nil, then the elements of | |
2953 the keymap will be passed to the mapper function in a canonical order. | |
2954 Otherwise, they will be passed in hash (that is, random) order, which is | |
2955 faster. | |
2956 */ ) | |
2957 (function, keymap, sort_first) | |
2958 Lisp_Object function, keymap, sort_first; | |
2959 { | |
2960 /* This function can GC */ | |
2961 struct gcpro gcpro1, gcpro2; | |
2962 | |
2963 /* tolerate obviously transposed args */ | |
2964 if (!NILP (Fkeymapp (function))) | |
2965 { | |
2966 Lisp_Object tmp = function; | |
2967 function = keymap; | |
2968 keymap = tmp; | |
2969 } | |
2970 GCPRO2 (function, keymap); | |
2971 keymap = get_keymap (keymap, 1, 1); | |
2972 map_keymap (XKEYMAP (keymap)->table, !NILP (sort_first), | |
2973 map_keymap_mapper, LISP_TO_VOID (function)); | |
2974 UNGCPRO; | |
2975 return Qnil; | |
2976 } | |
2977 | |
2978 | |
2979 | |
2980 /************************************************************************/ | |
2981 /* Accessible keymaps */ | |
2982 /************************************************************************/ | |
2983 | |
2984 struct accessible_keymaps_closure | |
2985 { | |
2986 Lisp_Object tail; | |
2987 }; | |
2988 | |
2989 | |
2990 static void | |
2991 accessible_keymaps_mapper_1 (Lisp_Object keysym, Lisp_Object contents, | |
2992 unsigned int modifiers, | |
2993 struct accessible_keymaps_closure *closure) | |
2994 { | |
2995 /* This function can GC */ | |
2996 unsigned int subbits = MODIFIER_HASH_KEY_BITS (keysym); | |
2997 | |
2998 if (subbits != 0) | |
2999 { | |
3000 Lisp_Object submaps; | |
3001 | |
3002 contents = get_keymap (contents, 1, 1); | |
3003 submaps = keymap_submaps (contents); | |
3004 for (; !NILP (submaps); submaps = XCDR (submaps)) | |
3005 { | |
3006 accessible_keymaps_mapper_1 (XCAR (XCAR (submaps)), | |
3007 XCDR (XCAR (submaps)), | |
3008 (subbits | modifiers), | |
3009 closure); | |
3010 } | |
3011 } | |
3012 else | |
3013 { | |
3014 Lisp_Object thisseq = Fcar (Fcar (closure->tail)); | |
3015 Lisp_Object cmd = get_keyelt (contents, 1); | |
3016 Lisp_Object vec; | |
3017 int j; | |
3018 struct key_data key; | |
3019 key.keysym = keysym; | |
3020 key.modifiers = modifiers; | |
3021 | |
3022 if (NILP (cmd)) | |
3023 abort (); | |
3024 cmd = get_keymap (cmd, 0, 1); | |
3025 if (!KEYMAPP (cmd)) | |
3026 abort (); | |
3027 | |
3028 vec = make_vector (vector_length (XVECTOR (thisseq)) + 1, Qnil); | |
3029 for (j = 0; j < vector_length (XVECTOR (thisseq)); j++) | |
3030 vector_data (XVECTOR (vec)) [j] = vector_data (XVECTOR (thisseq)) [j]; | |
3031 vector_data (XVECTOR (vec)) [j] = make_key_description (&key, 1); | |
3032 | |
3033 nconc2 (closure->tail, list1 (Fcons (vec, cmd))); | |
3034 } | |
3035 } | |
3036 | |
3037 | |
3038 static Lisp_Object | |
3039 accessible_keymaps_keymap_mapper (Lisp_Object thismap, void *arg) | |
3040 { | |
3041 /* This function can GC */ | |
3042 struct accessible_keymaps_closure *closure = arg; | |
3043 Lisp_Object submaps = keymap_submaps (thismap); | |
3044 | |
3045 for (; !NILP (submaps); submaps = XCDR (submaps)) | |
3046 { | |
3047 accessible_keymaps_mapper_1 (XCAR (XCAR (submaps)), | |
3048 XCDR (XCAR (submaps)), | |
3049 0, | |
3050 closure); | |
3051 } | |
3052 return (Qnil); | |
3053 } | |
3054 | |
3055 | |
3056 DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps, | |
3057 1, 2, 0 /* | |
3058 Find all keymaps accessible via prefix characters from STARTMAP. | |
3059 Returns a list of elements of the form (KEYS . MAP), where the sequence | |
3060 KEYS starting from STARTMAP gets you to MAP. These elements are ordered | |
3061 so that the KEYS increase in length. The first element is ([] . STARTMAP). | |
3062 An optional argument PREFIX, if non-nil, should be a key sequence; | |
3063 then the value includes only maps for prefixes that start with PREFIX. | |
3064 */ ) | |
3065 (startmap, prefix) | |
3066 Lisp_Object startmap, prefix; | |
3067 { | |
3068 /* This function can GC */ | |
3069 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | |
3070 Lisp_Object accessible_keymaps = Qnil; | |
3071 struct accessible_keymaps_closure c; | |
3072 c.tail = Qnil; | |
3073 GCPRO4 (accessible_keymaps, c.tail, prefix, startmap); | |
3074 | |
3075 retry: | |
3076 startmap = get_keymap (startmap, 1, 1); | |
3077 if (NILP (prefix)) | |
3078 prefix = make_vector (0, Qnil); | |
3079 else if (!VECTORP (prefix) || STRINGP (prefix)) | |
3080 { | |
3081 prefix = wrong_type_argument (Qarrayp, prefix); | |
3082 goto retry; | |
3083 } | |
3084 else | |
3085 { | |
3086 int len = XINT (Flength (prefix)); | |
3087 Lisp_Object def = Flookup_key (startmap, prefix, Qnil); | |
3088 Lisp_Object p; | |
3089 int iii; | |
3090 struct gcpro ngcpro1; | |
3091 | |
3092 def = get_keymap (def, 0, 1); | |
3093 if (!KEYMAPP (def)) | |
3094 goto RETURN; | |
3095 | |
3096 startmap = def; | |
3097 p = make_vector (len, Qnil); | |
3098 NGCPRO1 (p); | |
3099 for (iii = 0; iii < len; iii++) | |
3100 { | |
3101 struct key_data key; | |
3102 define_key_parser (Faref (prefix, make_int (iii)), &key); | |
3103 vector_data (XVECTOR (p))[iii] = make_key_description (&key, 1); | |
3104 } | |
3105 NUNGCPRO; | |
3106 prefix = p; | |
3107 } | |
3108 | |
3109 accessible_keymaps = list1 (Fcons (prefix, startmap)); | |
3110 | |
3111 /* For each map in the list maps, | |
3112 look at any other maps it points to | |
3113 and stick them at the end if they are not already in the list */ | |
3114 | |
3115 for (c.tail = accessible_keymaps; | |
3116 !NILP (c.tail); | |
3117 c.tail = XCDR (c.tail)) | |
3118 { | |
3119 Lisp_Object thismap = Fcdr (Fcar (c.tail)); | |
3120 CHECK_KEYMAP (thismap); | |
3121 traverse_keymaps (thismap, Qnil, | |
3122 accessible_keymaps_keymap_mapper, &c); | |
3123 } | |
3124 RETURN: | |
3125 UNGCPRO; | |
3126 return (accessible_keymaps); | |
3127 } | |
3128 | |
3129 | |
3130 | |
3131 /************************************************************************/ | |
3132 /* Pretty descriptions of key sequences */ | |
3133 /************************************************************************/ | |
3134 | |
3135 DEFUN ("key-description", Fkey_description, Skey_description, 1, 1, 0 /* | |
3136 Return a pretty description of key-sequence KEYS. | |
3137 Control characters turn into \"C-foo\" sequences, meta into \"M-foo\" | |
3138 spaces are put between sequence elements, etc. | |
3139 */ ) | |
3140 (keys) | |
3141 Lisp_Object keys; | |
3142 { | |
3143 if (INTP (keys) || CONSP (keys) || SYMBOLP (keys) || EVENTP (keys)) | |
3144 { | |
3145 return Fsingle_key_description (keys); | |
3146 } | |
3147 else if (VECTORP (keys) || | |
3148 STRINGP (keys)) | |
3149 { | |
3150 Lisp_Object string = Qnil; | |
3151 /* Lisp_Object sep = Qnil; */ | |
3152 int size = XINT (Flength (keys)); | |
3153 int i; | |
3154 | |
3155 for (i = 0; i < size; i++) | |
3156 { | |
3157 Lisp_Object s2 = Fsingle_key_description | |
3158 (((STRINGP (keys)) | |
3159 ? make_char (string_char (XSTRING (keys), i)) | |
3160 : vector_data (XVECTOR (keys))[i])); | |
3161 | |
3162 if (i == 0) | |
3163 string = s2; | |
3164 else | |
3165 { | |
3166 /* if (NILP (sep)) Lisp_Object sep = build_string (" ") */; | |
3167 string = concat2 (string, concat2 (Vsingle_space_string, s2)); | |
3168 } | |
3169 } | |
3170 return (string); | |
3171 } | |
3172 return Fkey_description (wrong_type_argument (Qsequencep, keys)); | |
3173 } | |
3174 | |
3175 DEFUN ("single-key-description", Fsingle_key_description, | |
3176 Ssingle_key_description, 1, 1, 0 /* | |
3177 Return a pretty description of command character KEY. | |
3178 Control characters turn into C-whatever, etc. | |
3179 This differs from `text-char-description' in that it returns a description | |
3180 of a key read from the user rather than a character from a buffer. | |
3181 */ ) | |
3182 (key) | |
3183 Lisp_Object key; | |
3184 { | |
3185 if (SYMBOLP (key)) | |
3186 key = Fcons (key, Qnil); /* sleaze sleaze */ | |
3187 | |
3188 if (EVENTP (key) || CHARP (key)) | |
3189 { | |
3190 char buf [255]; | |
3191 if (!EVENTP (key)) | |
3192 { | |
3193 struct Lisp_Event event; | |
3194 event.event_type = empty_event; | |
3195 CHECK_CHAR_COERCE_INT (key); | |
3196 character_to_event (XCHAR (key), &event, | |
3197 XCONSOLE (Vselected_console), 0); | |
3198 format_event_object (buf, &event, 1); | |
3199 } | |
3200 else | |
3201 format_event_object (buf, XEVENT (key), 1); | |
3202 return (build_string (buf)); | |
3203 } | |
3204 | |
3205 if (CONSP (key)) | |
3206 { | |
3207 char buf[255]; | |
3208 char *bufp = buf; | |
3209 Lisp_Object rest; | |
3210 buf[0] = 0; | |
3211 LIST_LOOP (rest, key) | |
3212 { | |
3213 Lisp_Object keysym = XCAR (rest); | |
3214 if (EQ (keysym, Qcontrol)) strcpy (bufp, "C-"), bufp += 2; | |
3215 else if (EQ (keysym, Qctrl)) strcpy (bufp, "C-"), bufp += 2; | |
3216 else if (EQ (keysym, Qmeta)) strcpy (bufp, "M-"), bufp += 2; | |
3217 else if (EQ (keysym, Qsuper)) strcpy (bufp, "S-"), bufp += 2; | |
3218 else if (EQ (keysym, Qhyper)) strcpy (bufp, "H-"), bufp += 2; | |
3219 else if (EQ (keysym, Qalt)) strcpy (bufp, "A-"), bufp += 2; | |
3220 else if (EQ (keysym, Qshift)) strcpy (bufp, "Sh-"), bufp += 3; | |
3221 else if (INTP (keysym)) | |
3222 *bufp = XINT (keysym), bufp++, *bufp = 0; | |
3223 else | |
3224 { | |
3225 CHECK_SYMBOL (keysym); | |
3226 #if 0 /* This is bogus */ | |
3227 if (EQ (keysym, QKlinefeed)) strcpy (bufp, "LFD"); | |
3228 else if (EQ (keysym, QKtab)) strcpy (bufp, "TAB"); | |
3229 else if (EQ (keysym, QKreturn)) strcpy (bufp, "RET"); | |
3230 else if (EQ (keysym, QKescape)) strcpy (bufp, "ESC"); | |
3231 else if (EQ (keysym, QKdelete)) strcpy (bufp, "DEL"); | |
3232 else if (EQ (keysym, QKspace)) strcpy (bufp, "SPC"); | |
3233 else if (EQ (keysym, QKbackspace)) strcpy (bufp, "BS"); | |
3234 else | |
3235 #endif | |
3236 strcpy (bufp, (char *) string_data (XSYMBOL (keysym)->name)); | |
3237 if (!NILP (XCDR (rest))) | |
3238 signal_simple_error ("invalid key description", | |
3239 key); | |
3240 } | |
3241 } | |
3242 return build_string (buf); | |
3243 } | |
3244 return Fsingle_key_description | |
3245 (wrong_type_argument (intern ("char-or-event-p"), key)); | |
3246 } | |
3247 | |
3248 DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, | |
3249 1, 1, 0 /* | |
3250 Return a pretty description of file-character CHR. | |
3251 Unprintable characters turn into \"^char\" or \\NNN, depending on the value | |
3252 of the `ctl-arrow' variable. | |
3253 This differs from `single-key-description' in that it returns a description | |
3254 of a character from a buffer rather than a key read from the user. | |
3255 */ ) | |
3256 (chr) | |
3257 Lisp_Object chr; | |
3258 { | |
3259 Bufbyte buf[200]; | |
3260 Bufbyte *p; | |
3261 unsigned int c; | |
3262 Lisp_Object ctl_arrow = current_buffer->ctl_arrow; | |
3263 int ctl_p = !NILP (ctl_arrow); | |
3264 int printable_min = (INTP (ctl_arrow) | |
3265 ? XINT (ctl_arrow) | |
3266 : ((EQ (ctl_arrow, Qt) || EQ (ctl_arrow, Qnil)) | |
3267 ? 256 : 160)); | |
3268 | |
3269 if (EVENTP (chr)) | |
3270 { | |
3271 Lisp_Object ch = Fevent_to_character (chr, Qnil, Qnil, Qt); | |
3272 if (NILP (ch)) | |
3273 return | |
3274 signal_simple_continuable_error | |
3275 ("character has no ASCII equivalent", Fcopy_event (chr, Qnil)); | |
3276 chr = ch; | |
3277 } | |
3278 | |
3279 CHECK_CHAR_COERCE_INT (chr); | |
3280 | |
3281 c = XCHAR (chr); | |
3282 p = buf; | |
3283 | |
3284 if (c >= printable_min) | |
3285 { | |
3286 p += set_charptr_emchar (p, c); | |
3287 } | |
3288 else if (c < 040 && ctl_p) | |
3289 { | |
3290 *p++ = '^'; | |
3291 *p++ = c + 64; /* 'A' - 1 */ | |
3292 } | |
3293 else if (c == 0177) | |
3294 { | |
3295 *p++ = '^'; | |
3296 *p++ = '?'; | |
3297 } | |
3298 else if (c >= 0200 || c < 040) | |
3299 { | |
3300 *p++ = '\\'; | |
3301 *p++ = '0' + ((c & 0700) >> 6); | |
3302 *p++ = '0' + ((c & 0070) >> 3); | |
3303 *p++ = '0' + ((c & 0007)); | |
3304 } | |
3305 else | |
3306 { | |
3307 p += set_charptr_emchar (p, c); | |
3308 } | |
3309 | |
3310 *p = 0; | |
3311 return build_string ((char *) buf); | |
3312 } | |
3313 | |
3314 | |
3315 /************************************************************************/ | |
3316 /* where-is (mapping bindings to keys) */ | |
3317 /************************************************************************/ | |
3318 | |
3319 static Lisp_Object | |
3320 where_is_internal (Lisp_Object definition, Lisp_Object *maps, int nmaps, | |
3321 Lisp_Object firstonly, char *target_buffer); | |
3322 | |
3323 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0 /* | |
3324 Return list of keys that invoke DEFINITION in KEYMAPS. | |
3325 KEYMAPS can be either a keymap (meaning search in that keymap and the | |
3326 current global keymap) or a list of keymaps (meaning search in exactly | |
3327 those keymaps and no others). If KEYMAPS is nil, search in the currently | |
3328 applicable maps for EVENT-OR-KEYS (this is equivalent to specifying | |
3329 `(current-keymaps EVENT-OR-KEYS)' as the argument to KEYMAPS). | |
3330 | |
3331 If optional 3rd arg FIRSTONLY is non-nil, return a vector representing | |
3332 the first key sequence found, rather than a list of all possible key | |
3333 sequences. | |
3334 | |
3335 If optional 4th arg NOINDIRECT is non-nil, don't follow indirections | |
3336 to other keymaps or slots. This makes it possible to search for an | |
3337 indirect definition itself. | |
3338 */ ) | |
3339 (definition, keymaps, firstonly, noindirect, event_or_keys) | |
3340 Lisp_Object definition, keymaps, firstonly, noindirect, event_or_keys; | |
3341 { | |
3342 /* This function can GC */ | |
3343 Lisp_Object maps[100]; | |
3344 Lisp_Object *gubbish = maps; | |
3345 int nmaps; | |
3346 | |
3347 /* Get keymaps as an array */ | |
3348 if (NILP (keymaps)) | |
3349 { | |
3350 nmaps = get_relevant_keymaps (event_or_keys, countof (maps), | |
3351 gubbish); | |
3352 if (nmaps > countof (maps)) | |
3353 { | |
3354 gubbish = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); | |
3355 nmaps = get_relevant_keymaps (event_or_keys, nmaps, gubbish); | |
3356 } | |
3357 } | |
3358 else if (CONSP (keymaps)) | |
3359 { | |
3360 Lisp_Object rest; | |
3361 int i; | |
3362 | |
3363 nmaps = XINT (Flength (keymaps)); | |
3364 if (nmaps > countof (maps)) | |
3365 { | |
3366 gubbish = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); | |
3367 } | |
3368 for (rest = keymaps, i = 0; !NILP (rest); | |
3369 rest = XCDR (keymaps), i++) | |
3370 { | |
3371 gubbish[i] = get_keymap (XCAR (keymaps), 1, 1); | |
3372 } | |
3373 } | |
3374 else | |
3375 { | |
3376 nmaps = 1; | |
3377 gubbish[0] = get_keymap (keymaps, 1, 1); | |
3378 if (!EQ (gubbish[0], Vcurrent_global_map)) | |
3379 { | |
3380 gubbish[1] = Vcurrent_global_map; | |
3381 nmaps++; | |
3382 } | |
3383 } | |
3384 | |
3385 return where_is_internal (definition, gubbish, nmaps, firstonly, 0); | |
3386 } | |
3387 | |
3388 /* This function is like | |
3389 (key-description (where-is-internal definition nil t)) | |
3390 except that it writes its output into a (char *) buffer that you | |
3391 provide; it doesn't cons (or allocate memory) at all, so it's | |
3392 very fast. This is used by menubar.c. | |
3393 */ | |
3394 void | |
3395 where_is_to_char (Lisp_Object definition, char *buffer) | |
3396 { | |
3397 /* This function can GC */ | |
3398 Lisp_Object maps[100]; | |
3399 Lisp_Object *gubbish = maps; | |
3400 int nmaps; | |
3401 | |
3402 /* Get keymaps as an array */ | |
3403 nmaps = get_relevant_keymaps (Qnil, countof (maps), gubbish); | |
3404 if (nmaps > countof (maps)) | |
3405 { | |
3406 gubbish = (Lisp_Object *) alloca (nmaps * sizeof (Lisp_Object)); | |
3407 nmaps = get_relevant_keymaps (Qnil, nmaps, gubbish); | |
3408 } | |
3409 | |
3410 buffer[0] = 0; | |
3411 where_is_internal (definition, maps, nmaps, Qt, buffer); | |
3412 } | |
3413 | |
3414 | |
3415 static Lisp_Object | |
3416 raw_keys_to_keys (struct key_data *keys, int count) | |
3417 { | |
3418 Lisp_Object result = make_vector (count, Qnil); | |
3419 while (count--) | |
3420 vector_data (XVECTOR (result)) [count] = | |
3421 make_key_description (&(keys[count]), 1); | |
3422 return (result); | |
3423 } | |
3424 | |
3425 | |
3426 static void | |
3427 format_raw_keys (struct key_data *keys, int count, char *buf) | |
3428 { | |
3429 int i; | |
3430 struct Lisp_Event event; | |
3431 event.event_type = key_press_event; | |
3432 event.channel = Vselected_console; | |
3433 for (i = 0; i < count; i++) | |
3434 { | |
3435 event.event.key.keysym = keys[i].keysym; | |
3436 event.event.key.modifiers = keys[i].modifiers; | |
3437 format_event_object (buf, &event, 1); | |
3438 buf += strlen (buf); | |
3439 if (i < count-1) | |
3440 buf[0] = ' ', buf++; | |
3441 } | |
3442 } | |
3443 | |
3444 | |
3445 /* definition is the thing to look for. | |
3446 map is a keymap. | |
3447 shadow is an array of shadow_count keymaps; if there is a different | |
3448 binding in any of the keymaps of a key that we are considering | |
3449 returning, then we reconsider. | |
3450 firstonly means give up after finding the first match; | |
3451 keys_so_far and modifiers_so_far describe which map we're looking in; | |
3452 If we're in the "meta" submap of the map that "C-x 4" is bound to, | |
3453 then keys_so_far will be {(control x), \4}, and modifiers_so_far | |
3454 will be MOD_META. That is, keys_so_far is the chain of keys that we | |
3455 have followed, and modifiers_so_far_so_far is the bits (partial keys) | |
3456 beyond that. | |
3457 | |
3458 (keys_so_far is a global buffer and the keys_count arg says how much | |
3459 of it we're currently interested in.) | |
3460 | |
3461 If target_buffer is provided, then we write a key-description into it, | |
3462 to avoid consing a string. This only works with firstonly on. | |
3463 */ | |
3464 | |
3465 struct where_is_closure | |
3466 { | |
3467 Lisp_Object definition; | |
3468 Lisp_Object *shadow; | |
3469 int shadow_count; | |
3470 int firstonly; | |
3471 int keys_count; | |
3472 unsigned int modifiers_so_far; | |
3473 char *target_buffer; | |
3474 struct key_data *keys_so_far; | |
3475 int keys_so_far_total_size; | |
3476 int keys_so_far_malloced; | |
3477 }; | |
3478 | |
3479 static Lisp_Object where_is_recursive_mapper (Lisp_Object map, void *arg); | |
3480 | |
3481 static Lisp_Object | |
3482 where_is_recursive_mapper (Lisp_Object map, void *arg) | |
3483 { | |
3484 /* This function can GC */ | |
3485 struct where_is_closure *c = arg; | |
3486 Lisp_Object definition = c->definition; | |
3487 CONST int firstonly = c->firstonly; | |
3488 CONST unsigned int keys_count = c->keys_count; | |
3489 CONST unsigned int modifiers_so_far = c->modifiers_so_far; | |
3490 char *target_buffer = c->target_buffer; | |
3491 Lisp_Object keys = Fgethash (definition, | |
3492 XKEYMAP (map)->inverse_table, | |
3493 Qnil); | |
3494 Lisp_Object submaps; | |
3495 Lisp_Object result = Qnil; | |
3496 | |
3497 if (!NILP (keys)) | |
3498 { | |
3499 /* One or more keys in this map match the definition we're looking | |
3500 for. Verify that these bindings aren't shadowed by other bindings | |
3501 in the shadow maps. Either nil or number as value from | |
3502 raw_lookup_key() means undefined. | |
3503 */ | |
3504 struct key_data *so_far = c->keys_so_far; | |
3505 | |
3506 for (;;) /* loop over all keys that match */ | |
3507 { | |
3508 Lisp_Object k = ((CONSP (keys)) ? XCAR (keys) : keys); | |
3509 int i; | |
3510 | |
3511 so_far [keys_count].keysym = k; | |
3512 so_far [keys_count].modifiers = modifiers_so_far; | |
3513 | |
3514 /* now loop over all shadow maps */ | |
3515 for (i = 0; i < c->shadow_count; i++) | |
3516 { | |
3517 Lisp_Object shadowed = raw_lookup_key (c->shadow[i], | |
3518 so_far, | |
3519 keys_count + 1, | |
3520 0, 1); | |
3521 | |
3522 if (NILP (shadowed) || CHARP (shadowed) || | |
3523 EQ (shadowed, definition)) | |
3524 continue; /* we passed this test; it's not shadowed here. */ | |
3525 else | |
3526 /* ignore this key binding, since it actually has a | |
3527 different binding in a shadowing map */ | |
3528 goto c_doesnt_have_proper_loop_exit_statements; | |
3529 } | |
3530 | |
3531 /* OK, the key is for real */ | |
3532 if (target_buffer) | |
3533 { | |
3534 if (!firstonly) abort (); | |
3535 format_raw_keys (so_far, keys_count + 1, target_buffer); | |
3536 return (make_int (1)); | |
3537 } | |
3538 else if (firstonly) | |
3539 return raw_keys_to_keys (so_far, keys_count + 1); | |
3540 else | |
3541 result = Fcons (raw_keys_to_keys (so_far, keys_count + 1), | |
3542 result); | |
3543 | |
3544 c_doesnt_have_proper_loop_exit_statements: | |
3545 /* now on to the next matching key ... */ | |
3546 if (!CONSP (keys)) break; | |
3547 keys = XCDR (keys); | |
3548 } | |
3549 } | |
3550 | |
3551 /* Now search the sub-keymaps of this map. | |
3552 If we're in "firstonly" mode and have already found one, this | |
3553 point is not reached. If we get one from lower down, either | |
3554 return it immediately (in firstonly mode) or tack it onto the | |
3555 end of the ones we've gotten so far. | |
3556 */ | |
3557 for (submaps = keymap_submaps (map); | |
3558 !NILP (submaps); | |
3559 submaps = XCDR (submaps)) | |
3560 { | |
3561 Lisp_Object key = XCAR (XCAR (submaps)); | |
3562 Lisp_Object submap = XCDR (XCAR (submaps)); | |
3563 unsigned int lower_modifiers; | |
3564 int lower_keys_count = keys_count; | |
3565 unsigned int bucky; | |
3566 | |
3567 submap = get_keymap (submap, 0, 1); | |
3568 | |
3569 if (EQ (submap, map)) | |
3570 /* Arrgh! Some loser has introduced a loop... */ | |
3571 continue; | |
3572 | |
3573 /* If this is not a keymap, then that's probably because someone | |
3574 did an `fset' of a symbol that used to point to a map such that | |
3575 it no longer does. Sigh. Ignore this, and invalidate the cache | |
3576 so that it doesn't happen to us next time too. | |
3577 */ | |
3578 if (NILP (submap)) | |
3579 { | |
3580 XKEYMAP (map)->sub_maps_cache = Qt; | |
3581 continue; | |
3582 } | |
3583 | |
3584 /* If the map is a "bucky" map, then add a bit to the | |
3585 modifiers_so_far list. | |
3586 Otherwise, add a new raw_key onto the end of keys_so_far. | |
3587 */ | |
3588 bucky = MODIFIER_HASH_KEY_BITS (key); | |
3589 if (bucky != 0) | |
3590 lower_modifiers = (modifiers_so_far | bucky); | |
3591 else | |
3592 { | |
3593 struct key_data *so_far = c->keys_so_far; | |
3594 lower_modifiers = 0; | |
3595 so_far [lower_keys_count].keysym = key; | |
3596 so_far [lower_keys_count].modifiers = modifiers_so_far; | |
3597 lower_keys_count++; | |
3598 } | |
3599 | |
3600 if (lower_keys_count >= c->keys_so_far_total_size) | |
3601 { | |
3602 int size = lower_keys_count + 50; | |
3603 if (! c->keys_so_far_malloced) | |
3604 { | |
3605 struct key_data *new = xmalloc (size * sizeof (struct key_data)); | |
3606 memcpy ((void *)new, (const void *)c->keys_so_far, | |
3607 c->keys_so_far_total_size * sizeof (struct key_data)); | |
3608 } | |
3609 else | |
3610 c->keys_so_far = xrealloc (c->keys_so_far, | |
3611 size * sizeof (struct key_data)); | |
3612 | |
3613 c->keys_so_far_total_size = size; | |
3614 c->keys_so_far_malloced = 1; | |
3615 } | |
3616 | |
3617 { | |
3618 Lisp_Object lower; | |
3619 | |
3620 c->keys_count = lower_keys_count; | |
3621 c->modifiers_so_far = lower_modifiers; | |
3622 | |
3623 lower = traverse_keymaps (submap, Qnil, where_is_recursive_mapper, | |
3624 c); | |
3625 c->keys_count = keys_count; | |
3626 c->modifiers_so_far = modifiers_so_far; | |
3627 | |
3628 if (!firstonly) | |
3629 result = nconc2 (lower, result); | |
3630 else if (!NILP (lower)) | |
3631 return (lower); | |
3632 } | |
3633 } | |
3634 return (result); | |
3635 } | |
3636 | |
3637 | |
3638 static Lisp_Object | |
3639 where_is_internal (Lisp_Object definition, Lisp_Object *maps, int nmaps, | |
3640 Lisp_Object firstonly, char *target_buffer) | |
3641 { | |
3642 /* This function can GC */ | |
3643 Lisp_Object result = Qnil; | |
3644 int i; | |
3645 struct key_data raw[20]; | |
3646 struct where_is_closure c; | |
3647 | |
3648 c.definition = definition; | |
3649 c.shadow = maps; | |
3650 c.firstonly = !NILP (firstonly); | |
3651 c.target_buffer = target_buffer; | |
3652 c.keys_so_far = raw; | |
3653 c.keys_so_far_total_size = countof (raw); | |
3654 c.keys_so_far_malloced = 0; | |
3655 | |
3656 /* Loop over each of the maps, accumulating the keys found. | |
3657 For each map searched, all previous maps shadow this one | |
3658 so that bogus keys aren't listed. */ | |
3659 for (i = 0; i < nmaps; i++) | |
3660 { | |
3661 Lisp_Object this_result; | |
3662 c.shadow_count = i; | |
3663 /* Reset the things set in each iteration */ | |
3664 c.keys_count = 0; | |
3665 c.modifiers_so_far = 0; | |
3666 | |
3667 this_result = traverse_keymaps (maps[i], Qnil, where_is_recursive_mapper, | |
3668 &c); | |
3669 if (!NILP (firstonly)) | |
3670 { | |
3671 result = this_result; | |
3672 if (!NILP (result)) | |
3673 break; | |
3674 } | |
3675 else | |
3676 result = nconc2 (this_result, result); | |
3677 } | |
3678 | |
3679 if (NILP (firstonly)) | |
3680 result = Fnreverse (result); | |
3681 | |
3682 if (c.keys_so_far_malloced) | |
3683 xfree (c.keys_so_far); | |
3684 return (result); | |
3685 } | |
3686 | |
3687 | |
3688 /************************************************************************/ | |
3689 /* Describing keymaps */ | |
3690 /************************************************************************/ | |
3691 | |
3692 DEFUN ("describe-bindings-internal", | |
3693 Fdescribe_bindings_internal, Sdescribe_bindings_internal, 1, 5, 0 /* | |
3694 Insert a list of all defined keys and their definitions in MAP. | |
3695 Optional second argument ALL says whether to include even \"uninteresting\" | |
3696 definitions (ie symbols with a non-nil `suppress-keymap' property. | |
3697 Third argument SHADOW is a list of keymaps whose bindings shadow those | |
3698 of map; if a binding is present in any shadowing map, it is not printed. | |
3699 Fourth argument PREFIX, if non-nil, should be a key sequence; | |
3700 only bindings which start with that key sequence will be printed. | |
3701 Fifth argument MOUSE-ONLY-P says to only print bindings for mouse clicks. | |
3702 */ ) | |
3703 (map, all, shadow, prefix, mouse_only_p) | |
3704 Lisp_Object map, all, shadow, prefix, mouse_only_p; | |
3705 { | |
3706 /* This function can GC */ | |
3707 describe_map_tree (map, NILP (all), shadow, prefix, | |
3708 !NILP (mouse_only_p)); | |
3709 return (Qnil); | |
3710 } | |
3711 | |
3712 | |
3713 /* Insert a desription of the key bindings in STARTMAP, | |
3714 followed by those of all maps reachable through STARTMAP. | |
3715 If PARTIAL is nonzero, omit certain "uninteresting" commands | |
3716 (such as `undefined'). | |
3717 If SHADOW is non-nil, it is a list of other maps; | |
3718 don't mention keys which would be shadowed by any of them | |
3719 If PREFIX is non-nil, only list bindings which start with those keys | |
3720 */ | |
3721 | |
3722 void | |
3723 describe_map_tree (Lisp_Object startmap, int partial, Lisp_Object shadow, | |
3724 Lisp_Object prefix, int mice_only_p) | |
3725 { | |
3726 /* This function can GC */ | |
3727 Lisp_Object maps = Qnil; | |
3728 struct gcpro gcpro1, gcpro2; /* get_keymap may autoload */ | |
3729 GCPRO2 (maps, shadow); | |
3730 | |
3731 maps = Faccessible_keymaps (startmap, prefix); | |
3732 | |
3733 for (; !NILP (maps); maps = Fcdr (maps)) | |
3734 { | |
3735 Lisp_Object sub_shadow = Qnil; | |
3736 Lisp_Object elt = Fcar (maps); | |
3737 Lisp_Object tail = shadow; | |
3738 int no_prefix = (VECTORP (Fcar (elt)) | |
3739 && XINT (Flength (Fcar (elt))) == 0); | |
3740 struct gcpro ngcpro1, ngcpro2, ngcpro3; | |
3741 NGCPRO3 (sub_shadow, elt, tail); | |
3742 | |
3743 for (; CONSP (tail); tail = XCDR (tail)) | |
3744 { | |
3745 Lisp_Object sh = XCAR (tail); | |
3746 | |
3747 /* If the sequence by which we reach this keymap is zero-length, | |
3748 then the shadow maps for this keymap are just SHADOW. */ | |
3749 if (no_prefix) | |
3750 ; | |
3751 /* If the sequence by which we reach this keymap actually has | |
3752 some elements, then the sequence's definition in SHADOW is | |
3753 what we should use. */ | |
3754 else | |
3755 { | |
3756 sh = Flookup_key (sh, Fcar (elt), Qt); | |
3757 if (CHARP (sh)) | |
3758 sh = Qnil; | |
3759 } | |
3760 | |
3761 if (!NILP (sh)) | |
3762 { | |
3763 Lisp_Object shm = get_keymap (sh, 0, 1); | |
3764 if (!KEYMAPP (shm)) | |
3765 /* If sh is not nil and not a keymap, it completely shadows | |
3766 this map, so don't describe this map at all. */ | |
3767 goto SKIP; | |
3768 sub_shadow = Fcons (shm, sub_shadow); | |
3769 } | |
3770 } | |
3771 | |
3772 { | |
3773 /* Describe the contents of map MAP, assuming that this map | |
3774 itself is reached by the sequence of prefix keys KEYS (a vector). | |
3775 PARTIAL and SHADOW are as in `describe_map_tree'. */ | |
3776 Lisp_Object keysdesc | |
3777 = ((!no_prefix) | |
3778 ? concat2 (Fkey_description (Fcar (elt)), Vsingle_space_string) | |
3779 : Qnil); | |
3780 describe_map (Fcdr (elt), keysdesc, | |
3781 describe_command, | |
3782 partial, | |
3783 sub_shadow, | |
3784 mice_only_p); | |
3785 } | |
3786 SKIP: | |
3787 NUNGCPRO; | |
3788 } | |
3789 UNGCPRO; | |
3790 } | |
3791 | |
3792 | |
3793 static void | |
3794 describe_command (Lisp_Object definition) | |
3795 { | |
3796 /* This function can GC */ | |
3797 Lisp_Object buffer; | |
3798 int keymapp = !NILP (Fkeymapp (definition)); | |
3799 struct gcpro gcpro1, gcpro2; | |
3800 GCPRO2 (definition, buffer); | |
3801 | |
3802 XSETBUFFER (buffer, current_buffer); | |
3803 Findent_to (make_int (16), make_int (3), buffer); | |
3804 if (keymapp) | |
3805 buffer_insert_c_string (XBUFFER (buffer), "<< "); | |
3806 | |
3807 if (SYMBOLP (definition)) | |
3808 { | |
3809 buffer_insert1 (XBUFFER (buffer), Fsymbol_name (definition)); | |
3810 } | |
3811 else if (STRINGP (definition) || VECTORP (definition)) | |
3812 { | |
3813 buffer_insert_c_string (XBUFFER (buffer), "Kbd Macro: "); | |
3814 buffer_insert1 (XBUFFER (buffer), Fkey_description (definition)); | |
3815 } | |
3816 else if (COMPILED_FUNCTIONP (definition)) | |
3817 buffer_insert_c_string (XBUFFER (buffer), "Anonymous Compiled Function"); | |
3818 else if (CONSP (definition) && EQ (XCAR (definition), Qlambda)) | |
3819 buffer_insert_c_string (XBUFFER (buffer), "Anonymous Lambda"); | |
3820 else if (KEYMAPP (definition)) | |
3821 { | |
3822 Lisp_Object name = XKEYMAP (definition)->name; | |
3823 if (STRINGP (name) || (SYMBOLP (name) && !NILP (name))) | |
3824 { | |
3825 buffer_insert_c_string (XBUFFER (buffer), "Prefix command "); | |
3826 if (SYMBOLP (name) | |
3827 && EQ (find_symbol_value (name), definition)) | |
3828 buffer_insert1 (XBUFFER (buffer), Fsymbol_name (name)); | |
3829 else | |
3830 { | |
3831 buffer_insert1 (XBUFFER (buffer), Fprin1_to_string (name, Qnil)); | |
3832 } | |
3833 } | |
3834 else | |
3835 buffer_insert_c_string (XBUFFER (buffer), "Prefix Command"); | |
3836 } | |
3837 else | |
3838 buffer_insert_c_string (XBUFFER (buffer), "??"); | |
3839 | |
3840 if (keymapp) | |
3841 buffer_insert_c_string (XBUFFER (buffer), " >>"); | |
3842 buffer_insert_c_string (XBUFFER (buffer), "\n"); | |
3843 UNGCPRO; | |
3844 } | |
3845 | |
3846 struct describe_map_closure | |
3847 { | |
3848 Lisp_Object *list; /* pointer to the list to update */ | |
3849 Lisp_Object partial; /* whether to ignore suppressed commands */ | |
3850 Lisp_Object shadow; /* list of maps shadowing this one */ | |
3851 Lisp_Object self; /* this map */ | |
3852 Lisp_Object self_root; /* this map, or some map that has this map as | |
3853 a parent. this is the base of the tree */ | |
3854 int mice_only_p; /* whether we are to display only button bindings */ | |
3855 }; | |
3856 | |
3857 struct describe_map_shadow_closure | |
3858 { | |
3859 CONST struct key_data *raw_key; | |
3860 Lisp_Object self; | |
3861 }; | |
3862 | |
3863 static Lisp_Object | |
3864 describe_map_mapper_shadow_search (Lisp_Object map, void *arg) | |
3865 { | |
3866 struct describe_map_shadow_closure *c = arg; | |
3867 | |
3868 if (EQ (map, c->self)) | |
3869 return (Qzero); /* Not shadowed; terminate search */ | |
3870 else if (!NILP (keymap_lookup_directly (map, | |
3871 c->raw_key->keysym, | |
3872 c->raw_key->modifiers))) | |
3873 return (Qt); | |
3874 else | |
3875 return (Qnil); | |
3876 } | |
3877 | |
3878 | |
3879 static Lisp_Object | |
3880 keymap_lookup_inherited_mapper (Lisp_Object km, void *arg) | |
3881 { | |
3882 struct key_data *k = arg; | |
3883 return (keymap_lookup_directly (km, k->keysym, k->modifiers)); | |
3884 } | |
3885 | |
3886 | |
3887 static void | |
3888 describe_map_mapper (CONST struct key_data *key, | |
3889 Lisp_Object binding, | |
3890 void *describe_map_closure) | |
3891 { | |
3892 /* This function can GC */ | |
3893 struct describe_map_closure *closure = describe_map_closure; | |
3894 Lisp_Object keysym = key->keysym; | |
3895 unsigned int modifiers = key->modifiers; | |
3896 | |
3897 /* Dont mention suppressed commands. */ | |
3898 if (SYMBOLP (binding) | |
3899 && !NILP (closure->partial) | |
3900 && !NILP (Fget (binding, closure->partial, Qnil))) | |
3901 return; | |
3902 | |
3903 /* If we're only supposed to display mouse bindings and this isn't one, | |
3904 then bug out. */ | |
3905 if (closure->mice_only_p && | |
3906 (! (EQ (keysym, Qbutton0) || EQ (keysym, Qbutton1) | |
3907 || EQ (keysym, Qbutton2) || EQ (keysym, Qbutton3) | |
3908 || EQ (keysym, Qbutton4) || EQ (keysym, Qbutton5) | |
3909 || EQ (keysym, Qbutton6) || EQ (keysym, Qbutton7)))) | |
3910 return; | |
3911 | |
3912 /* If this command in this map is shadowed by some other map, ignore it. */ | |
3913 { | |
3914 Lisp_Object tail; | |
3915 | |
3916 for (tail = closure->shadow; CONSP (tail); tail = XCDR (tail)) | |
3917 { | |
3918 QUIT; | |
3919 if (!NILP (traverse_keymaps (XCAR (tail), Qnil, | |
3920 keymap_lookup_inherited_mapper, | |
3921 /* Cast to discard `const' */ | |
3922 (void *)key))) | |
3923 return; | |
3924 } | |
3925 } | |
3926 | |
3927 /* If this key is in some map of which this map is a parent, then ignore | |
3928 it (in that case, it has been shadowed). | |
3929 */ | |
3930 { | |
3931 Lisp_Object sh; | |
3932 struct describe_map_shadow_closure c; | |
3933 c.raw_key = key; | |
3934 c.self = closure->self; | |
3935 | |
3936 sh = traverse_keymaps (closure->self_root, Qnil, | |
3937 describe_map_mapper_shadow_search, &c); | |
3938 if (!NILP (sh) && !ZEROP (sh)) | |
3939 return; | |
3940 } | |
3941 | |
3942 /* Otherwise add it to the list to be sorted. */ | |
3943 *(closure->list) = Fcons (Fcons (Fcons (keysym, make_int (modifiers)), | |
3944 binding), | |
3945 *(closure->list)); | |
3946 } | |
3947 | |
3948 | |
3949 static int | |
3950 describe_map_sort_predicate (Lisp_Object obj1, Lisp_Object obj2, | |
3951 Lisp_Object pred) | |
3952 { | |
3953 /* obj1 and obj2 are conses of the form | |
3954 ( ( <keysym> . <modifiers> ) . <binding> ) | |
3955 keysym and modifiers are used, binding is ignored. | |
3956 */ | |
3957 unsigned int bit1, bit2; | |
3958 obj1 = XCAR (obj1); | |
3959 obj2 = XCAR (obj2); | |
3960 bit1 = XINT (XCDR (obj1)); | |
3961 bit2 = XINT (XCDR (obj2)); | |
3962 if (bit1 != bit2) | |
3963 return ((bit1 < bit2) ? 1 : -1); | |
3964 else | |
3965 return map_keymap_sort_predicate (obj1, obj2, pred); | |
3966 } | |
3967 | |
3968 /* Elide 2 or more consecutive numeric keysyms bound to the same thing, | |
3969 or 2 or more symbolic keysyms that are bound to the same thing and | |
3970 have consecutive character-set-properties. | |
3971 */ | |
3972 static int | |
3973 elide_next_two_p (Lisp_Object list) | |
3974 { | |
3975 Lisp_Object s1, s2; | |
3976 | |
3977 if (NILP (XCDR (list))) | |
3978 return 0; | |
3979 | |
3980 /* next two bindings differ */ | |
3981 if (!EQ (XCDR (XCAR (list)), | |
3982 XCDR (XCAR (XCDR (list))))) | |
3983 return 0; | |
3984 | |
3985 /* next two modifier-sets differ */ | |
3986 if (!EQ (XCDR (XCAR (XCAR (list))), | |
3987 XCDR (XCAR (XCAR (XCDR (list)))))) | |
3988 return 0; | |
3989 | |
3990 s1 = XCAR (XCAR (XCAR (list))); | |
3991 s2 = XCAR (XCAR (XCAR (XCDR (list)))); | |
3992 | |
3993 if (SYMBOLP (s1)) | |
3994 { | |
3995 Lisp_Object code = Fget (s1, Vcharacter_set_property, Qnil); | |
3996 if (INTP (code)) s1 = code; | |
3997 else return 0; | |
3998 } | |
3999 if (SYMBOLP (s2)) | |
4000 { | |
4001 Lisp_Object code = Fget (s2, Vcharacter_set_property, Qnil); | |
4002 if (INTP (code)) s2 = code; | |
4003 else return 0; | |
4004 } | |
4005 | |
4006 if (XCHAR (s1) == XCHAR (s2) || | |
4007 XCHAR (s1) + 1 == XCHAR (s2)) | |
4008 return 1; | |
4009 return 0; | |
4010 } | |
4011 | |
4012 | |
4013 static Lisp_Object | |
4014 describe_map_parent_mapper (Lisp_Object keymap, void *arg) | |
4015 { | |
4016 /* This function can GC */ | |
4017 struct describe_map_closure *describe_map_closure = arg; | |
4018 describe_map_closure->self = keymap; | |
4019 map_keymap (XKEYMAP (keymap)->table, | |
4020 0, /* don't sort: we'll do it later */ | |
4021 describe_map_mapper, describe_map_closure); | |
4022 return (Qnil); | |
4023 } | |
4024 | |
4025 | |
4026 static void | |
4027 describe_map (Lisp_Object keymap, Lisp_Object elt_prefix, | |
4028 void (*elt_describer) (Lisp_Object), | |
4029 int partial, | |
4030 Lisp_Object shadow, | |
4031 int mice_only_p) | |
4032 { | |
4033 /* This function can GC */ | |
4034 struct describe_map_closure describe_map_closure; | |
4035 Lisp_Object list = Qnil; | |
4036 struct buffer *buf = current_buffer; | |
4037 Emchar printable_min = (CHAR_OR_CHAR_INTP (buf->ctl_arrow) | |
4038 ? XCHAR_OR_CHAR_INT (buf->ctl_arrow) | |
4039 : ((EQ (buf->ctl_arrow, Qt) | |
4040 || EQ (buf->ctl_arrow, Qnil)) | |
4041 ? 256 : 160)); | |
4042 int elided = 0; | |
4043 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4; | |
4044 | |
4045 keymap = get_keymap (keymap, 1, 1); | |
4046 describe_map_closure.partial = (partial ? Qsuppress_keymap : Qnil); | |
4047 describe_map_closure.shadow = shadow; | |
4048 describe_map_closure.list = &list; | |
4049 describe_map_closure.self_root = keymap; | |
4050 describe_map_closure.mice_only_p = mice_only_p; | |
4051 | |
4052 GCPRO4 (keymap, elt_prefix, shadow, list); | |
4053 | |
4054 traverse_keymaps (keymap, Qnil, | |
4055 describe_map_parent_mapper, &describe_map_closure); | |
4056 | |
4057 if (!NILP (list)) | |
4058 { | |
4059 list = list_sort (list, Qnil, describe_map_sort_predicate); | |
4060 buffer_insert_c_string (buf, "\n"); | |
4061 while (!NILP (list)) | |
4062 { | |
4063 Lisp_Object elt = XCAR (XCAR (list)); | |
4064 Lisp_Object keysym = XCAR (elt); | |
4065 unsigned int modifiers = XINT (XCDR (elt)); | |
4066 | |
4067 if (!NILP (elt_prefix)) | |
4068 buffer_insert_lisp_string (buf, elt_prefix); | |
4069 | |
4070 if (modifiers & MOD_META) buffer_insert_c_string (buf, "M-"); | |
4071 if (modifiers & MOD_CONTROL) buffer_insert_c_string (buf, "C-"); | |
4072 if (modifiers & MOD_SUPER) buffer_insert_c_string (buf, "S-"); | |
4073 if (modifiers & MOD_HYPER) buffer_insert_c_string (buf, "H-"); | |
4074 if (modifiers & MOD_ALT) buffer_insert_c_string (buf, "Alt-"); | |
4075 if (modifiers & MOD_SHIFT) buffer_insert_c_string (buf, "Sh-"); | |
4076 if (SYMBOLP (keysym)) | |
4077 { | |
4078 Lisp_Object code = Fget (keysym, Vcharacter_set_property, Qnil); | |
4079 Emchar c = (CHAR_OR_CHAR_INTP (code) | |
4080 ? XCHAR_OR_CHAR_INT (code) : -1); | |
4081 /* Calling Fsingle_key_description() would cons more */ | |
4082 #if 0 /* This is bogus */ | |
4083 if (EQ (keysym, QKlinefeed)) | |
4084 buffer_insert_c_string (buf, "LFD"); | |
4085 else if (EQ (keysym, QKtab)) | |
4086 buffer_insert_c_string (buf, "TAB"); | |
4087 else if (EQ (keysym, QKreturn)) | |
4088 buffer_insert_c_string (buf, "RET"); | |
4089 else if (EQ (keysym, QKescape)) | |
4090 buffer_insert_c_string (buf, "ESC"); | |
4091 else if (EQ (keysym, QKdelete)) | |
4092 buffer_insert_c_string (buf, "DEL"); | |
4093 else if (EQ (keysym, QKspace)) | |
4094 buffer_insert_c_string (buf, "SPC"); | |
4095 else if (EQ (keysym, QKbackspace)) | |
4096 buffer_insert_c_string (buf, "BS"); | |
4097 else | |
4098 #endif | |
4099 if (c >= printable_min) | |
4100 buffer_insert_emacs_char (buf, c); | |
4101 else buffer_insert1 (buf, Fsymbol_name (keysym)); | |
4102 } | |
4103 else if (CHARP (keysym)) | |
4104 buffer_insert_emacs_char (buf, XCHAR (keysym)); | |
4105 else | |
4106 buffer_insert_c_string (buf, "---bad keysym---"); | |
4107 | |
4108 if (elided) | |
4109 elided = 0; | |
4110 else | |
4111 { | |
4112 int k = 0; | |
4113 | |
4114 while (elide_next_two_p (list)) | |
4115 { | |
4116 k++; | |
4117 list = XCDR (list); | |
4118 } | |
4119 if (k != 0) | |
4120 { | |
4121 if (k == 1) | |
4122 buffer_insert_c_string (buf, ", "); | |
4123 else | |
4124 buffer_insert_c_string (buf, " .. "); | |
4125 elided = 1; | |
4126 continue; | |
4127 } | |
4128 } | |
4129 | |
4130 /* Print a description of the definition of this character. */ | |
4131 (*elt_describer) (XCDR (XCAR (list))); | |
4132 list = XCDR (list); | |
4133 } | |
4134 } | |
4135 UNGCPRO; | |
4136 } | |
4137 | |
4138 | |
4139 void | |
4140 syms_of_keymap (void) | |
4141 { | |
4142 defsymbol (&Qminor_mode_map_alist, "minor-mode-map-alist"); | |
4143 | |
4144 defsymbol (&Qkeymapp, "keymapp"); | |
4145 | |
4146 defsymbol (&Qsuppress_keymap, "suppress-keymap"); | |
4147 | |
4148 defsymbol (&Qmodeline_map, "modeline-map"); | |
4149 defsymbol (&Qtoolbar_map, "toolbar-map"); | |
4150 | |
4151 defsubr (&Skeymap_parents); | |
4152 defsubr (&Sset_keymap_parents); | |
4153 defsubr (&Skeymap_name); | |
4154 defsubr (&Sset_keymap_name); | |
4155 defsubr (&Skeymap_prompt); | |
4156 defsubr (&Sset_keymap_prompt); | |
4157 defsubr (&Skeymap_default_binding); | |
4158 defsubr (&Sset_keymap_default_binding); | |
4159 | |
4160 defsubr (&Skeymapp); | |
4161 defsubr (&Smake_keymap); | |
4162 defsubr (&Smake_sparse_keymap); | |
4163 | |
4164 defsubr (&Scopy_keymap); | |
4165 defsubr (&Skeymap_fullness); | |
4166 defsubr (&Smap_keymap); | |
4167 defsubr (&Sevent_matches_key_specifier_p); | |
4168 defsubr (&Sdefine_key); | |
4169 defsubr (&Slookup_key); | |
4170 defsubr (&Skey_binding); | |
4171 defsubr (&Suse_global_map); | |
4172 defsubr (&Suse_local_map); | |
4173 defsubr (&Scurrent_local_map); | |
4174 defsubr (&Scurrent_global_map); | |
4175 defsubr (&Scurrent_keymaps); | |
4176 defsubr (&Saccessible_keymaps); | |
4177 defsubr (&Skey_description); | |
4178 defsubr (&Ssingle_key_description); | |
4179 defsubr (&Swhere_is_internal); | |
4180 defsubr (&Sdescribe_bindings_internal); | |
4181 | |
4182 defsubr (&Stext_char_description); | |
4183 | |
4184 defsymbol (&Qcontrol, "control"); | |
4185 defsymbol (&Qctrl, "ctrl"); | |
4186 defsymbol (&Qmeta, "meta"); | |
4187 defsymbol (&Qsuper, "super"); | |
4188 defsymbol (&Qhyper, "hyper"); | |
4189 defsymbol (&Qalt, "alt"); | |
4190 defsymbol (&Qshift, "shift"); | |
4191 defsymbol (&Qbutton0, "button0"); | |
4192 defsymbol (&Qbutton1, "button1"); | |
4193 defsymbol (&Qbutton2, "button2"); | |
4194 defsymbol (&Qbutton3, "button3"); | |
4195 defsymbol (&Qbutton4, "button4"); | |
4196 defsymbol (&Qbutton5, "button5"); | |
4197 defsymbol (&Qbutton6, "button6"); | |
4198 defsymbol (&Qbutton7, "button7"); | |
4199 defsymbol (&Qbutton0up, "button0up"); | |
4200 defsymbol (&Qbutton1up, "button1up"); | |
4201 defsymbol (&Qbutton2up, "button2up"); | |
4202 defsymbol (&Qbutton3up, "button3up"); | |
4203 defsymbol (&Qbutton4up, "button4up"); | |
4204 defsymbol (&Qbutton5up, "button5up"); | |
4205 defsymbol (&Qbutton6up, "button6up"); | |
4206 defsymbol (&Qbutton7up, "button7up"); | |
4207 defsymbol (&Qmenu_selection, "menu-selection"); | |
4208 defsymbol (&QLFD, "LFD"); | |
4209 defsymbol (&QTAB, "TAB"); | |
4210 defsymbol (&QRET, "RET"); | |
4211 defsymbol (&QESC, "ESC"); | |
4212 defsymbol (&QDEL, "DEL"); | |
4213 defsymbol (&QBS, "BS"); | |
4214 } | |
4215 | |
4216 void | |
4217 vars_of_keymap (void) | |
4218 { | |
4219 DEFVAR_LISP ("meta-prefix-char", &Vmeta_prefix_char /* | |
4220 Meta-prefix character. | |
4221 This character followed by some character `foo' turns into `Meta-foo'. | |
4222 This can be any form recognized as a single key specifier. | |
4223 To disable the meta-prefix-char, set it to a negative number. | |
4224 */ ); | |
4225 Vmeta_prefix_char = make_char (033); | |
4226 | |
4227 DEFVAR_LISP ("mouse-grabbed-buffer", &Vmouse_grabbed_buffer /* | |
4228 A buffer which should be consulted first for all mouse activity. | |
4229 When a mouse-click is processed, it will first be looked up in the | |
4230 local-map of this buffer, and then through the normal mechanism if there | |
4231 is no binding for that click. This buffer's value of `mode-motion-hook' | |
4232 will be consulted instead of the `mode-motion-hook' of the buffer of the | |
4233 window under the mouse. You should *bind* this, not set it. | |
4234 */ ); | |
4235 Vmouse_grabbed_buffer = Qnil; | |
4236 | |
4237 DEFVAR_LISP ("overriding-local-map", &Voverriding_local_map /* | |
4238 Keymap that overrides all other local keymaps. | |
4239 If this variable is non-nil, it is used as a keymap instead of the | |
4240 buffer's local map, and the minor mode keymaps and extent-local keymaps. | |
4241 You should *bind* this, not set it. | |
4242 */ ); | |
4243 Voverriding_local_map = Qnil; | |
4244 | |
4245 Fset (Qminor_mode_map_alist, Qnil); | |
4246 | |
4247 DEFVAR_LISP ("key-translation-map", &Vkey_translation_map /* | |
4248 Keymap of key translations that can override keymaps. | |
4249 This keymap works like `function-key-map', but comes after that, | |
4250 and applies even for keys that have ordinary bindings. | |
4251 */ ); | |
4252 | |
4253 DEFVAR_INT ("keymap-tick", &keymap_tick /* | |
4254 Incremented for each change to any keymap. | |
4255 */ ); | |
4256 keymap_tick = 0; | |
4257 | |
4258 staticpro (&Vcurrent_global_map); | |
4259 | |
4260 Vsingle_space_string = make_pure_string ((CONST Bufbyte *) " ", 1, Qnil, 1); | |
4261 staticpro (&Vsingle_space_string); | |
4262 } | |
4263 | |
4264 void | |
4265 complex_vars_of_keymap (void) | |
4266 { | |
4267 /* This function can GC */ | |
4268 Lisp_Object ESC_prefix = intern ("ESC-prefix"); | |
4269 Lisp_Object meta_disgustitute; | |
4270 | |
4271 Vcurrent_global_map = Fmake_keymap (Qnil); | |
4272 | |
4273 meta_disgustitute = Fmake_keymap (Qnil); | |
4274 Ffset (ESC_prefix, meta_disgustitute); | |
4275 /* no need to protect meta_disgustitute, though */ | |
4276 keymap_store_internal (MAKE_MODIFIER_HASH_KEY (MOD_META), | |
4277 XKEYMAP (Vcurrent_global_map), | |
4278 meta_disgustitute); | |
4279 XKEYMAP (Vcurrent_global_map)->sub_maps_cache = Qt; | |
4280 | |
4281 Vkey_translation_map = Fmake_sparse_keymap (intern ("key-translation-map")); | |
4282 } |