This source file includes following definitions.
- CHECK_VECTOR_OR_CHAR_TABLE
- DEFUN
- DEFUN
- initial_define_lispy_key
- DEFUN
- DEFUN
- get_keymap
- keymap_parent
- DEFUN
- keymap_memberp
- access_keymap_1
- access_keymap
- map_keymap_item
- map_keymap_char_table_item
- map_keymap_internal
- map_keymap_call
- map_keymap
- map_keymap_canonical
- get_keyelt
- store_in_keymap
- copy_keymap_item
- copy_keymap_set_char_table
- copy_keymap_1
- DEFUN
- possibly_translate_key_sequence
- lookup_key_1
- define_as_prefix
- append_key
- silly_event_symbol_error
- current_minor_maps
- click_position
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- DEFUN
- accessible_keymaps_1
- push_key_description
- push_text_char_description
- DEFUN
- preferred_sequence_p
- shadow_lookup
- where_is_internal
- where_is_internal_1
- describe_vector_princ
- describe_vector_basic
- describe_key_maybe_fontify
- describe_vector
- syms_of_keymap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42 #include <config.h>
43 #include <stdio.h>
44 #include <stdlib.h>
45
46 #include "lisp.h"
47 #include "commands.h"
48 #include "character.h"
49 #include "buffer.h"
50 #include "keyboard.h"
51 #include "termhooks.h"
52 #include "blockinput.h"
53 #include "puresize.h"
54 #include "intervals.h"
55 #include "keymap.h"
56 #include "window.h"
57
58
59
60 Lisp_Object current_global_map;
61
62
63 static Lisp_Object exclude_keys;
64
65
66 static Lisp_Object command_remapping_vector;
67
68
69 static Lisp_Object unicode_case_table;
70
71
72 static Lisp_Object where_is_cache;
73
74 static Lisp_Object where_is_cache_keymaps;
75
76 static Lisp_Object store_in_keymap (Lisp_Object, Lisp_Object, Lisp_Object,
77 bool);
78
79 static Lisp_Object define_as_prefix (Lisp_Object, Lisp_Object);
80 static void describe_vector (Lisp_Object, Lisp_Object, Lisp_Object,
81 void (*) (Lisp_Object, Lisp_Object), bool,
82 Lisp_Object, Lisp_Object, bool, bool);
83 static void silly_event_symbol_error (Lisp_Object);
84 static Lisp_Object get_keyelt (Lisp_Object, bool);
85
86 static void
87 CHECK_VECTOR_OR_CHAR_TABLE (Lisp_Object x)
88 {
89 CHECK_TYPE (VECTORP (x) || CHAR_TABLE_P (x), Qvector_or_char_table_p, x);
90 }
91
92
93
94 DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 1, 0,
95 doc:
96
97
98
99
100
101
102
103 )
104 (Lisp_Object string)
105 {
106 Lisp_Object tail = !NILP (string) ? list1 (string) : Qnil;
107 return Fcons (Qkeymap,
108 Fcons (Fmake_char_table (Qkeymap, Qnil), tail));
109 }
110
111 DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 1, 0,
112 doc:
113
114
115
116
117
118
119 )
120 (Lisp_Object string)
121 {
122 if (!NILP (string))
123 {
124 if (!NILP (Vpurify_flag))
125 string = Fpurecopy (string);
126 return list2 (Qkeymap, string);
127 }
128 return list1 (Qkeymap);
129 }
130
131 void
132 initial_define_lispy_key (Lisp_Object keymap, const char *keyname, const char *defname)
133 {
134 store_in_keymap (keymap, intern_c_string (keyname),
135 intern_c_string (defname), false);
136 }
137
138 DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
139 doc:
140
141
142
143
144
145 )
146 (Lisp_Object object)
147 {
148 return (KEYMAPP (object) ? Qt : Qnil);
149 }
150
151 DEFUN ("keymap-prompt", Fkeymap_prompt, Skeymap_prompt, 1, 1, 0,
152 doc:
153
154 )
155 (Lisp_Object map)
156 {
157 map = get_keymap (map, 0, 0);
158 while (CONSP (map))
159 {
160 Lisp_Object tem = XCAR (map);
161 if (STRINGP (tem))
162 return tem;
163 else if (KEYMAPP (tem))
164 {
165 tem = Fkeymap_prompt (tem);
166 if (!NILP (tem))
167 return tem;
168 }
169 map = XCDR (map);
170 }
171 return Qnil;
172 }
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194 Lisp_Object
195 get_keymap (Lisp_Object object, bool error_if_not_keymap, bool autoload)
196 {
197 autoload_retry:
198 if (NILP (object))
199 goto end;
200 if (CONSP (object) && EQ (XCAR (object), Qkeymap))
201 return object;
202
203 Lisp_Object tem = indirect_function (object);
204 if (CONSP (tem))
205 {
206 if (EQ (XCAR (tem), Qkeymap))
207 return tem;
208
209
210
211 if ((autoload || !error_if_not_keymap) && EQ (XCAR (tem), Qautoload)
212 && SYMBOLP (object))
213 {
214 Lisp_Object tail;
215
216 tail = Fnth (make_fixnum (4), tem);
217 if (EQ (tail, Qkeymap))
218 {
219 if (autoload)
220 {
221 Fautoload_do_load (tem, object, Qnil);
222 goto autoload_retry;
223 }
224 else
225 return object;
226 }
227 }
228 }
229
230 end:
231 if (error_if_not_keymap)
232 wrong_type_argument (Qkeymapp, object);
233 return Qnil;
234 }
235
236
237
238
239 static Lisp_Object
240 keymap_parent (Lisp_Object keymap, bool autoload)
241 {
242 keymap = get_keymap (keymap, 1, autoload);
243
244
245 Lisp_Object list = XCDR (keymap);
246 for (; CONSP (list); list = XCDR (list))
247 {
248
249 if (KEYMAPP (list))
250 return list;
251 }
252
253 return get_keymap (list, 0, autoload);
254 }
255
256 DEFUN ("keymap-parent", Fkeymap_parent, Skeymap_parent, 1, 1, 0,
257 doc:
258 )
259 (Lisp_Object keymap)
260 {
261 return keymap_parent (keymap, 1);
262 }
263
264
265 static bool
266 keymap_memberp (Lisp_Object map, Lisp_Object maps)
267 {
268 if (NILP (map)) return 0;
269 while (KEYMAPP (maps) && !EQ (map, maps))
270 maps = keymap_parent (maps, 0);
271 return (EQ (map, maps));
272 }
273
274
275
276 DEFUN ("set-keymap-parent", Fset_keymap_parent, Sset_keymap_parent, 2, 2, 0,
277 doc:
278 )
279 (Lisp_Object keymap, Lisp_Object parent)
280 {
281
282 where_is_cache = Qnil; where_is_cache_keymaps = Qt;
283
284 keymap = get_keymap (keymap, 1, 1);
285
286 if (!NILP (parent))
287 {
288 parent = get_keymap (parent, 1, 0);
289
290
291 if (keymap_memberp (keymap, parent))
292 error ("Cyclic keymap inheritance");
293 }
294
295
296 Lisp_Object prev = keymap;
297 while (1)
298 {
299 Lisp_Object list = XCDR (prev);
300
301
302 if (!CONSP (list) || KEYMAPP (list))
303 {
304 CHECK_IMPURE (prev, XCONS (prev));
305 XSETCDR (prev, parent);
306 return parent;
307 }
308 prev = list;
309 }
310 }
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330 static Lisp_Object
331 access_keymap_1 (Lisp_Object map, Lisp_Object idx,
332 bool t_ok, bool noinherit, bool autoload)
333 {
334
335
336
337 idx = EVENT_HEAD (idx);
338
339
340
341 if (SYMBOLP (idx))
342 idx = reorder_modifiers (idx);
343 else if (FIXNUMP (idx))
344
345
346 XSETFASTINT (idx, XFIXNUM (idx) & (CHAR_META | (CHAR_META - 1)));
347
348
349 if (FIXNUMP (idx) && XFIXNAT (idx) & meta_modifier)
350 {
351
352
353 Lisp_Object event_meta_binding, event_meta_map;
354
355
356 if (XFIXNUM (meta_prefix_char) & CHAR_META)
357 meta_prefix_char = make_fixnum (27);
358 event_meta_binding = access_keymap_1 (map, meta_prefix_char, t_ok,
359 noinherit, autoload);
360 event_meta_map = get_keymap (event_meta_binding, 0, autoload);
361 if (CONSP (event_meta_map))
362 {
363 map = event_meta_map;
364 idx = make_fixnum (XFIXNAT (idx) & ~meta_modifier);
365 }
366 else if (t_ok)
367
368 idx = Qt;
369 else
370
371 return NILP (event_meta_binding) ? Qnil : Qunbound;
372 }
373
374
375
376
377 {
378 Lisp_Object tail;
379 Lisp_Object t_binding = Qunbound;
380 Lisp_Object retval = Qunbound;
381 Lisp_Object retval_tail = Qnil;
382
383 for (tail = (CONSP (map) && EQ (Qkeymap, XCAR (map))) ? XCDR (map) : map;
384 (CONSP (tail)
385 || (tail = get_keymap (tail, 0, autoload), CONSP (tail)));
386 tail = XCDR (tail))
387 {
388
389 Lisp_Object val = Qunbound;
390 Lisp_Object binding = XCAR (tail);
391 Lisp_Object submap = get_keymap (binding, 0, autoload);
392
393 if (EQ (binding, Qkeymap))
394 {
395 if (noinherit || NILP (retval))
396
397 break;
398 else if (!BASE_EQ (retval, Qunbound))
399 {
400 Lisp_Object parent_entry;
401 eassert (KEYMAPP (retval));
402 parent_entry
403 = get_keymap (access_keymap_1 (tail, idx,
404 t_ok, 0, autoload),
405 0, autoload);
406 if (KEYMAPP (parent_entry))
407 {
408 if (CONSP (retval_tail))
409 XSETCDR (retval_tail, parent_entry);
410 else
411 {
412 retval_tail = Fcons (retval, parent_entry);
413 retval = Fcons (Qkeymap, retval_tail);
414 }
415 }
416 break;
417 }
418 }
419 else if (CONSP (submap))
420 {
421 val = access_keymap_1 (submap, idx, t_ok, noinherit, autoload);
422 }
423 else if (CONSP (binding))
424 {
425 Lisp_Object key = XCAR (binding);
426
427 if (EQ (key, idx))
428 val = XCDR (binding);
429 else if (t_ok && EQ (key, Qt))
430 {
431 t_binding = XCDR (binding);
432 t_ok = 0;
433 }
434 }
435 else if (VECTORP (binding))
436 {
437 if (FIXNUMP (idx) && XFIXNAT (idx) < ASIZE (binding))
438 val = AREF (binding, XFIXNAT (idx));
439 }
440 else if (CHAR_TABLE_P (binding))
441 {
442
443
444
445 if (FIXNUMP (idx) && (XFIXNAT (idx) & CHAR_MODIFIER_MASK) == 0)
446 {
447 val = Faref (binding, idx);
448
449
450
451 if (NILP (val))
452 val = Qunbound;
453 }
454 }
455
456
457 if (!BASE_EQ (val, Qunbound))
458 {
459 if (EQ (val, Qt))
460
461
462
463 val = Qnil;
464
465 val = get_keyelt (val, autoload);
466
467 if (!KEYMAPP (val))
468 {
469 if (NILP (retval) || BASE_EQ (retval, Qunbound))
470 retval = val;
471 if (!NILP (val))
472 break;
473 }
474 else if (NILP (retval) || BASE_EQ (retval, Qunbound))
475 retval = val;
476 else if (CONSP (retval_tail))
477 {
478 XSETCDR (retval_tail, list1 (val));
479 retval_tail = XCDR (retval_tail);
480 }
481 else
482 {
483 retval_tail = list1 (val);
484 retval = Fcons (Qkeymap, Fcons (retval, retval_tail));
485 }
486 }
487 maybe_quit ();
488 }
489
490 return BASE_EQ (Qunbound, retval)
491 ? get_keyelt (t_binding, autoload) : retval;
492 }
493 }
494
495 Lisp_Object
496 access_keymap (Lisp_Object map, Lisp_Object idx,
497 bool t_ok, bool noinherit, bool autoload)
498 {
499 Lisp_Object val = access_keymap_1 (map, idx, t_ok, noinherit, autoload);
500 return BASE_EQ (val, Qunbound) ? Qnil : val;
501 }
502
503 static void
504 map_keymap_item (map_keymap_function_t fun, Lisp_Object args, Lisp_Object key, Lisp_Object val, void *data)
505 {
506 if (EQ (val, Qt))
507 val = Qnil;
508 (*fun) (key, val, args, data);
509 }
510
511 union map_keymap
512 {
513 struct
514 {
515 map_keymap_function_t fun;
516 Lisp_Object args;
517 void *data;
518 } s;
519 GCALIGNED_UNION_MEMBER
520 };
521 verify (GCALIGNED (union map_keymap));
522
523 static void
524 map_keymap_char_table_item (Lisp_Object args, Lisp_Object key, Lisp_Object val)
525 {
526 if (!NILP (val))
527 {
528
529
530 if (CONSP (key))
531 key = Fcons (XCAR (key), XCDR (key));
532 union map_keymap *md = XFIXNUMPTR (args);
533 map_keymap_item (md->s.fun, md->s.args, key, val, md->s.data);
534 }
535 }
536
537
538
539 static Lisp_Object
540 map_keymap_internal (Lisp_Object map,
541 map_keymap_function_t fun,
542 Lisp_Object args,
543 void *data)
544 {
545 Lisp_Object tail
546 = (CONSP (map) && EQ (Qkeymap, XCAR (map))) ? XCDR (map) : map;
547
548 for (; CONSP (tail) && !EQ (Qkeymap, XCAR (tail)); tail = XCDR (tail))
549 {
550 Lisp_Object binding = XCAR (tail);
551
552 if (KEYMAPP (binding))
553 break;
554 else if (CONSP (binding))
555 map_keymap_item (fun, args, XCAR (binding), XCDR (binding), data);
556 else if (VECTORP (binding))
557 {
558
559 int len = ASIZE (binding);
560 int c;
561 for (c = 0; c < len; c++)
562 {
563 Lisp_Object character;
564 XSETFASTINT (character, c);
565 map_keymap_item (fun, args, character, AREF (binding, c), data);
566 }
567 }
568 else if (CHAR_TABLE_P (binding))
569 {
570 union map_keymap mapdata = {{fun, args, data}};
571 map_char_table (map_keymap_char_table_item, Qnil, binding,
572 make_pointer_integer (&mapdata));
573 }
574 }
575
576 return tail;
577 }
578
579 static void
580 map_keymap_call (Lisp_Object key, Lisp_Object val, Lisp_Object fun, void *dummy)
581 {
582 call2 (fun, key, val);
583 }
584
585
586
587 void
588 map_keymap (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args,
589 void *data, bool autoload)
590 {
591 map = get_keymap (map, 1, autoload);
592 while (CONSP (map))
593 {
594 if (KEYMAPP (XCAR (map)))
595 {
596 map_keymap (XCAR (map), fun, args, data, autoload);
597 map = XCDR (map);
598 }
599 else
600 map = map_keymap_internal (map, fun, args, data);
601 if (!CONSP (map))
602 map = get_keymap (map, 0, autoload);
603 }
604 }
605
606
607
608 void
609 map_keymap_canonical (Lisp_Object map, map_keymap_function_t fun, Lisp_Object args, void *data)
610 {
611
612
613 map = safe_call1 (Qkeymap_canonicalize, map);
614
615 map_keymap_internal (map, fun, args, data);
616 }
617
618 DEFUN ("map-keymap-internal", Fmap_keymap_internal, Smap_keymap_internal, 2, 2, 0,
619 doc:
620
621
622 )
623 (Lisp_Object function, Lisp_Object keymap)
624 {
625 keymap = get_keymap (keymap, 1, 1);
626 keymap = map_keymap_internal (keymap, map_keymap_call, function, NULL);
627 return keymap;
628 }
629
630 DEFUN ("map-keymap", Fmap_keymap, Smap_keymap, 2, 3, 0,
631 doc:
632
633
634
635
636
637
638
639
640
641 )
642 (Lisp_Object function, Lisp_Object keymap, Lisp_Object sort_first)
643 {
644 if (! NILP (sort_first))
645 return call2 (intern ("map-keymap-sorted"), function, keymap);
646
647 map_keymap (keymap, map_keymap_call, function, NULL, 1);
648 return Qnil;
649 }
650
651 DEFUN ("keymap--get-keyelt", Fkeymap__get_keyelt, Skeymap__get_keyelt, 2, 2, 0,
652 doc:
653
654
655
656
657
658
659
660
661
662 )
663 (Lisp_Object object, Lisp_Object autoload)
664 {
665 return get_keyelt (object, NILP (autoload) ? false : true);
666 }
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682 static Lisp_Object
683 get_keyelt (Lisp_Object object, bool autoload)
684 {
685 while (1)
686 {
687 if (!(CONSP (object)))
688
689 return object;
690
691
692
693
694 else if (EQ (XCAR (object), Qmenu_item))
695 {
696 if (CONSP (XCDR (object)))
697 {
698 Lisp_Object tem;
699
700 object = XCDR (XCDR (object));
701 tem = object;
702 if (CONSP (object))
703 object = XCAR (object);
704
705
706
707
708 for (; CONSP (tem) && CONSP (XCDR (tem)); tem = XCDR (tem))
709 if (EQ (XCAR (tem), QCfilter) && autoload)
710 {
711 Lisp_Object filter;
712 filter = XCAR (XCDR (tem));
713 filter = list2 (filter, list2 (Qquote, object));
714 object = menu_item_eval_property (filter);
715 break;
716 }
717 }
718 else
719
720 return object;
721 }
722
723
724
725
726 else if (STRINGP (XCAR (object)))
727 object = XCDR (object);
728
729 else
730 return object;
731 }
732 }
733
734 static Lisp_Object
735 store_in_keymap (Lisp_Object keymap, register Lisp_Object idx,
736 Lisp_Object def, bool remove)
737 {
738
739 where_is_cache = Qnil;
740 where_is_cache_keymaps = Qt;
741
742 if (EQ (idx, Qkeymap))
743 error ("`keymap' is reserved for embedded parent maps");
744
745
746
747 if (CONSP (def) && PURE_P (XCONS (def))
748 && (EQ (XCAR (def), Qmenu_item) || STRINGP (XCAR (def))))
749 def = Fcons (XCAR (def), XCDR (def));
750
751 if (!CONSP (keymap) || !EQ (XCAR (keymap), Qkeymap))
752 error ("attempt to define a key in a non-keymap");
753
754
755
756 if (CONSP (idx) && CHARACTERP (XCAR (idx)))
757 CHECK_CHARACTER_CDR (idx);
758 else
759
760
761
762 idx = EVENT_HEAD (idx);
763
764
765
766 if (SYMBOLP (idx))
767 idx = reorder_modifiers (idx);
768 else if (FIXNUMP (idx))
769
770
771 XSETFASTINT (idx, XFIXNUM (idx) & (CHAR_META | (CHAR_META - 1)));
772
773
774 {
775 Lisp_Object tail;
776
777
778
779
780
781
782
783 Lisp_Object insertion_point = keymap;
784 for (tail = XCDR (keymap); CONSP (tail); tail = XCDR (tail))
785 {
786 Lisp_Object elt = XCAR (tail);
787 if (VECTORP (elt))
788 {
789 if (FIXNATP (idx) && XFIXNAT (idx) < ASIZE (elt))
790 {
791 CHECK_IMPURE (elt, XVECTOR (elt));
792 ASET (elt, XFIXNAT (idx), def);
793 return def;
794 }
795 else if (CONSP (idx) && CHARACTERP (XCAR (idx)))
796 {
797 int from = XFIXNAT (XCAR (idx));
798 int to = XFIXNAT (XCDR (idx));
799
800 if (to >= ASIZE (elt))
801 to = ASIZE (elt) - 1;
802 for (; from <= to; from++)
803 ASET (elt, from, def);
804 if (to == XFIXNAT (XCDR (idx)))
805
806 return def;
807 }
808 insertion_point = tail;
809 }
810 else if (CHAR_TABLE_P (elt))
811 {
812 Lisp_Object sdef = def;
813 if (remove)
814 sdef = Qnil;
815
816
817
818 else if (NILP (sdef))
819 sdef = Qt;
820
821
822
823
824 if (FIXNATP (idx) && !(XFIXNAT (idx) & CHAR_MODIFIER_MASK))
825 {
826 Faset (elt, idx, sdef);
827 return def;
828 }
829 else if (CONSP (idx) && CHARACTERP (XCAR (idx)))
830 {
831 Fset_char_table_range (elt, idx, sdef);
832 return def;
833 }
834 insertion_point = tail;
835 }
836 else if (CONSP (elt))
837 {
838 if (EQ (Qkeymap, XCAR (elt)))
839 {
840
841
842
843
844
845 tail = insertion_point = elt;
846 }
847 else if (EQ (idx, XCAR (elt)))
848 {
849 CHECK_IMPURE (elt, XCONS (elt));
850 if (remove)
851
852 insertion_point = Fdelq (elt, insertion_point);
853 else
854
855 XSETCDR (elt, def);
856 return def;
857 }
858 else if (CONSP (idx)
859 && CHARACTERP (XCAR (idx))
860 && CHARACTERP (XCAR (elt)))
861 {
862 int from = XFIXNAT (XCAR (idx));
863 int to = XFIXNAT (XCDR (idx));
864
865 if (from <= XFIXNAT (XCAR (elt))
866 && to >= XFIXNAT (XCAR (elt)))
867 {
868 if (remove)
869 insertion_point = Fdelq (elt, insertion_point);
870 else
871 XSETCDR (elt, def);
872 if (from == to)
873 return def;
874 }
875 }
876 }
877 else if (EQ (elt, Qkeymap))
878
879
880
881
882 goto keymap_end;
883
884 maybe_quit ();
885 }
886
887 keymap_end:
888
889
890 if (!remove)
891 {
892 Lisp_Object elt;
893
894 if (CONSP (idx) && CHARACTERP (XCAR (idx)))
895 {
896
897
898
899 elt = Fmake_char_table (Qkeymap, Qnil);
900 Fset_char_table_range (elt, idx, NILP (def) ? Qt : def);
901 }
902 else
903 elt = Fcons (idx, def);
904 CHECK_IMPURE (insertion_point, XCONS (insertion_point));
905 XSETCDR (insertion_point, Fcons (elt, XCDR (insertion_point)));
906 }
907 }
908
909 return def;
910 }
911
912 static Lisp_Object copy_keymap_1 (Lisp_Object keymap, int depth);
913
914 static Lisp_Object
915 copy_keymap_item (Lisp_Object elt, int depth)
916 {
917 Lisp_Object res, tem;
918
919 if (!CONSP (elt))
920 return elt;
921
922 res = tem = elt;
923
924
925 if (EQ (XCAR (tem), Qmenu_item))
926 {
927
928 res = elt = Fcons (XCAR (tem), XCDR (tem));
929 tem = XCDR (elt);
930 if (CONSP (tem))
931 {
932
933 XSETCDR (elt, Fcons (XCAR (tem), XCDR (tem)));
934 elt = XCDR (elt);
935 tem = XCDR (elt);
936 }
937 if (CONSP (tem))
938 {
939
940
941 XSETCDR (elt, Fcons (XCAR (tem), XCDR (tem)));
942 elt = XCDR (elt);
943 tem = XCAR (elt);
944 if (CONSP (tem) && EQ (XCAR (tem), Qkeymap))
945 XSETCAR (elt, copy_keymap_1 (tem, depth));
946 tem = XCDR (elt);
947 }
948 }
949 else
950 {
951
952
953 if (STRINGP (XCAR (tem)))
954 {
955
956 res = elt = Fcons (XCAR (tem), XCDR (tem));
957 tem = XCDR (elt);
958
959 if (CONSP (tem) && STRINGP (XCAR (tem)))
960 {
961 XSETCDR (elt, Fcons (XCAR (tem), XCDR (tem)));
962 elt = XCDR (elt);
963 tem = XCDR (elt);
964 }
965 if (CONSP (tem) && EQ (XCAR (tem), Qkeymap))
966 XSETCDR (elt, copy_keymap_1 (tem, depth));
967 }
968 else if (EQ (XCAR (tem), Qkeymap))
969 res = copy_keymap_1 (elt, depth);
970 }
971 return res;
972 }
973
974 static void
975 copy_keymap_set_char_table (Lisp_Object chartable_and_depth, Lisp_Object idx,
976 Lisp_Object elt)
977 {
978 Fset_char_table_range
979 (XCAR (chartable_and_depth), idx,
980 copy_keymap_item (elt, XFIXNUM (XCDR (chartable_and_depth))));
981 }
982
983 static Lisp_Object
984 copy_keymap_1 (Lisp_Object keymap, int depth)
985 {
986 Lisp_Object copy, tail;
987
988 if (depth > 100)
989 error ("Possible infinite recursion when copying keymap");
990
991 keymap = get_keymap (keymap, 1, 0);
992 copy = tail = list1 (Qkeymap);
993 keymap = XCDR (keymap);
994
995 while (CONSP (keymap) && !EQ (XCAR (keymap), Qkeymap))
996 {
997 Lisp_Object elt = XCAR (keymap);
998 if (CHAR_TABLE_P (elt))
999 {
1000 elt = Fcopy_sequence (elt);
1001 map_char_table (copy_keymap_set_char_table, Qnil, elt,
1002 Fcons (elt, make_fixnum (depth + 1)));
1003 }
1004 else if (VECTORP (elt))
1005 {
1006 elt = Fcopy_sequence (elt);
1007 for (int i = 0; i < ASIZE (elt); i++)
1008 ASET (elt, i, copy_keymap_item (AREF (elt, i), depth + 1));
1009 }
1010 else if (CONSP (elt))
1011 {
1012 if (EQ (XCAR (elt), Qkeymap))
1013
1014 elt = copy_keymap_1 (elt, depth + 1);
1015 else
1016 elt = Fcons (XCAR (elt), copy_keymap_item (XCDR (elt), depth + 1));
1017 }
1018 XSETCDR (tail, list1 (elt));
1019 tail = XCDR (tail);
1020 keymap = XCDR (keymap);
1021 }
1022 XSETCDR (tail, keymap);
1023 return copy;
1024 }
1025
1026 DEFUN ("copy-keymap", Fcopy_keymap, Scopy_keymap, 1, 1, 0,
1027 doc:
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048 )
1049 (Lisp_Object keymap)
1050 {
1051 return copy_keymap_1 (keymap, 0);
1052 }
1053
1054
1055
1056
1057 static Lisp_Object
1058 possibly_translate_key_sequence (Lisp_Object key, ptrdiff_t *length)
1059 {
1060 if (VECTORP (key) && ASIZE (key) == 1 && STRINGP (AREF (key, 0)))
1061 {
1062
1063
1064 if (NILP (Ffboundp (Qkey_valid_p)))
1065 xsignal2 (Qerror,
1066 build_string ("`key-valid-p' is not defined, so this syntax can't be used: %s"),
1067 key);
1068
1069
1070
1071
1072 if (NILP (call1 (Qkey_valid_p, AREF (key, 0))))
1073 return key;
1074 key = call1 (Qkey_parse, AREF (key, 0));
1075 *length = CHECK_VECTOR_OR_STRING (key);
1076 if (*length == 0)
1077 xsignal2 (Qerror, build_string ("Invalid `key-parse' syntax: %S"), key);
1078 }
1079
1080 return key;
1081 }
1082
1083
1084
1085 DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 4, 0,
1086 doc:
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124 )
1125 (Lisp_Object keymap, Lisp_Object key, Lisp_Object def, Lisp_Object remove)
1126 {
1127 bool metized = false;
1128
1129 keymap = get_keymap (keymap, 1, 1);
1130
1131 ptrdiff_t length = CHECK_VECTOR_OR_STRING (key);
1132 if (length == 0)
1133 return Qnil;
1134
1135 int meta_bit = (VECTORP (key) || (STRINGP (key) && STRING_MULTIBYTE (key))
1136 ? meta_modifier : 0x80);
1137
1138 if (VECTORP (def) && ASIZE (def) > 0 && CONSP (AREF (def, 0)))
1139 {
1140 Lisp_Object tmp = make_nil_vector (ASIZE (def));
1141 ptrdiff_t i = ASIZE (def);
1142 while (--i >= 0)
1143 {
1144 Lisp_Object defi = AREF (def, i);
1145 if (CONSP (defi) && lucid_event_type_list_p (defi))
1146 defi = Fevent_convert_list (defi);
1147 ASET (tmp, i, defi);
1148 }
1149 def = tmp;
1150 }
1151
1152 key = possibly_translate_key_sequence (key, &length);
1153
1154 ptrdiff_t idx = 0;
1155 while (1)
1156 {
1157 Lisp_Object c = Faref (key, make_fixnum (idx));
1158
1159 if (CONSP (c))
1160 {
1161
1162
1163 if (lucid_event_type_list_p (c))
1164 c = Fevent_convert_list (c);
1165 else if (CHARACTERP (XCAR (c)))
1166 CHECK_CHARACTER_CDR (c);
1167 }
1168
1169 if (SYMBOLP (c))
1170 silly_event_symbol_error (c);
1171
1172 if (FIXNUMP (c)
1173 && (XFIXNUM (c) & meta_bit)
1174 && !metized)
1175 {
1176 c = meta_prefix_char;
1177 metized = true;
1178 }
1179 else
1180 {
1181 if (FIXNUMP (c))
1182 XSETINT (c, XFIXNUM (c) & ~meta_bit);
1183
1184 metized = false;
1185 idx++;
1186 }
1187
1188 if (!FIXNUMP (c) && !SYMBOLP (c)
1189 && (!CONSP (c)
1190
1191 || (FIXNUMP (XCAR (c)) && idx != length)))
1192 message_with_string ("Key sequence contains invalid event %s", c, 1);
1193
1194 if (idx == length)
1195 return store_in_keymap (keymap, c, def, !NILP (remove));
1196
1197 Lisp_Object cmd = access_keymap (keymap, c, 0, 1, 1);
1198
1199
1200 if (NILP (cmd))
1201 cmd = define_as_prefix (keymap, c);
1202
1203 keymap = get_keymap (cmd, 0, 1);
1204 if (!CONSP (keymap))
1205 {
1206 const char *trailing_esc = ((EQ (c, meta_prefix_char) && metized)
1207 ? (idx == 0 ? "ESC" : " ESC")
1208 : "");
1209
1210
1211
1212 error ("Key sequence %s starts with non-prefix key %s%s",
1213 SDATA (Fkey_description (key, Qnil)),
1214 SDATA (Fkey_description (Fsubstring (key, make_fixnum (0),
1215 make_fixnum (idx)),
1216 Qnil)),
1217 trailing_esc);
1218 }
1219 }
1220 }
1221
1222
1223
1224 DEFUN ("command-remapping", Fcommand_remapping, Scommand_remapping, 1, 3, 0,
1225 doc:
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237 )
1238 (Lisp_Object command, Lisp_Object position, Lisp_Object keymaps)
1239 {
1240 if (!SYMBOLP (command))
1241 return Qnil;
1242
1243 ASET (command_remapping_vector, 1, command);
1244
1245 if (NILP (keymaps))
1246 command = Fkey_binding (command_remapping_vector, Qnil, Qt, position);
1247 else
1248 command = Flookup_key (keymaps, command_remapping_vector, Qnil);
1249 return FIXNUMP (command) ? Qnil : command;
1250 }
1251
1252 static Lisp_Object
1253 lookup_key_1 (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
1254 {
1255 bool t_ok = !NILP (accept_default);
1256
1257 if (!CONSP (keymap) && !NILP (keymap))
1258 keymap = get_keymap (keymap, true, true);
1259
1260 ptrdiff_t length = CHECK_VECTOR_OR_STRING (key);
1261 if (length == 0)
1262 return keymap;
1263
1264 key = possibly_translate_key_sequence (key, &length);
1265
1266 ptrdiff_t idx = 0;
1267 while (1)
1268 {
1269 Lisp_Object c = Faref (key, make_fixnum (idx++));
1270
1271 if (CONSP (c) && lucid_event_type_list_p (c))
1272 c = Fevent_convert_list (c);
1273
1274
1275 if (STRINGP (key) && XFIXNUM (c) & 0x80 && !STRING_MULTIBYTE (key))
1276 XSETINT (c, (XFIXNUM (c) | meta_modifier) & ~0x80);
1277
1278
1279
1280 if (!FIXNUMP (c) && !SYMBOLP (c) && !CONSP (c) && !STRINGP (c))
1281 message_with_string ("Key sequence contains invalid event %s", c, 1);
1282
1283 Lisp_Object cmd = access_keymap (keymap, c, t_ok, 0, 1);
1284 if (idx == length)
1285 return cmd;
1286
1287 keymap = get_keymap (cmd, 0, 1);
1288 if (!CONSP (keymap))
1289 return make_fixnum (idx);
1290
1291 maybe_quit ();
1292 }
1293 }
1294
1295
1296
1297
1298 DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 3, 0,
1299 doc:
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317 )
1318 (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default)
1319 {
1320 Lisp_Object found = lookup_key_1 (keymap, key, accept_default);
1321 if (!NILP (found) && !NUMBERP (found))
1322 return found;
1323
1324
1325
1326
1327
1328
1329
1330 if (!VECTORP (key) || !(ASIZE (key) > 0)
1331 || !EQ (AREF (key, 0), Qmenu_bar))
1332 return found;
1333
1334
1335 if (NILP (unicode_case_table))
1336 {
1337 unicode_case_table = uniprop_table (intern ("lowercase"));
1338
1339 if (NILP (unicode_case_table))
1340 return found;
1341 staticpro (&unicode_case_table);
1342 }
1343
1344 ptrdiff_t key_len = ASIZE (key);
1345 Lisp_Object new_key = make_vector (key_len, Qnil);
1346
1347
1348
1349
1350 Lisp_Object tables[2] = {unicode_case_table, Fcurrent_case_table ()};
1351 for (int tbl_num = 0; tbl_num < 2; tbl_num++)
1352 {
1353
1354
1355 for (int i = 0; i < key_len; i++)
1356 {
1357 Lisp_Object item = AREF (key, i);
1358 if (!SYMBOLP (item))
1359 ASET (new_key, i, item);
1360 else
1361 {
1362 Lisp_Object key_item = Fsymbol_name (item);
1363 Lisp_Object new_item;
1364 if (!STRING_MULTIBYTE (key_item))
1365 new_item = Fdowncase (key_item);
1366 else
1367 {
1368 USE_SAFE_ALLOCA;
1369 ptrdiff_t size = SCHARS (key_item), n;
1370 if (ckd_mul (&n, size, MAX_MULTIBYTE_LENGTH))
1371 n = PTRDIFF_MAX;
1372 unsigned char *dst = SAFE_ALLOCA (n);
1373 unsigned char *p = dst;
1374 ptrdiff_t j_char = 0, j_byte = 0;
1375
1376 while (j_char < size)
1377 {
1378 int ch = fetch_string_char_advance (key_item,
1379 &j_char, &j_byte);
1380 Lisp_Object ch_conv = CHAR_TABLE_REF (tables[tbl_num],
1381 ch);
1382 if (!NILP (ch_conv))
1383 CHAR_STRING (XFIXNUM (ch_conv), p);
1384 else
1385 CHAR_STRING (ch, p);
1386 p = dst + j_byte;
1387 }
1388 new_item = make_multibyte_string ((char *) dst,
1389 SCHARS (key_item),
1390 SBYTES (key_item));
1391 SAFE_FREE ();
1392 }
1393 ASET (new_key, i, Fintern (new_item, Qnil));
1394 }
1395 }
1396
1397
1398 found = lookup_key_1 (keymap, new_key, accept_default);
1399 if (!NILP (found) && !NUMBERP (found))
1400 break;
1401
1402
1403
1404
1405 for (int i = 0; i < key_len; i++)
1406 {
1407 if (!SYMBOLP (AREF (new_key, i)))
1408 continue;
1409
1410 Lisp_Object lc_key = Fsymbol_name (AREF (new_key, i));
1411
1412
1413 if (!strstr (SSDATA (lc_key), " "))
1414 continue;
1415
1416 USE_SAFE_ALLOCA;
1417 ptrdiff_t size = SCHARS (lc_key), n;
1418 if (ckd_mul (&n, size, MAX_MULTIBYTE_LENGTH))
1419 n = PTRDIFF_MAX;
1420 unsigned char *dst = SAFE_ALLOCA (n);
1421
1422
1423
1424
1425
1426 memcpy (dst, SSDATA (lc_key), SBYTES (lc_key));
1427 for (int i = 0; i < SBYTES (lc_key); ++i)
1428 {
1429 if (dst[i] == ' ')
1430 dst[i] = '-';
1431 }
1432 Lisp_Object new_it =
1433 make_multibyte_string ((char *) dst,
1434 SCHARS (lc_key), SBYTES (lc_key));
1435 ASET (new_key, i, Fintern (new_it, Qnil));
1436 SAFE_FREE ();
1437 }
1438
1439
1440 found = lookup_key_1 (keymap, new_key, accept_default);
1441 if (!NILP (found) && !NUMBERP (found))
1442 break;
1443 }
1444
1445 return found;
1446 }
1447
1448
1449
1450
1451
1452 static Lisp_Object
1453 define_as_prefix (Lisp_Object keymap, Lisp_Object c)
1454 {
1455 Lisp_Object cmd = Fmake_sparse_keymap (Qnil);
1456 store_in_keymap (keymap, c, cmd, false);
1457
1458 return cmd;
1459 }
1460
1461
1462
1463 static Lisp_Object
1464 append_key (Lisp_Object key_sequence, Lisp_Object key)
1465 {
1466 AUTO_LIST1 (key_list, key);
1467 return CALLN (Fvconcat, key_sequence, key_list);
1468 }
1469
1470
1471
1472
1473 static void
1474 silly_event_symbol_error (Lisp_Object c)
1475 {
1476 Lisp_Object parsed = parse_modifiers (c);
1477 int modifiers = XFIXNAT (XCAR (XCDR (parsed)));
1478 Lisp_Object base = XCAR (parsed);
1479 Lisp_Object name = Fsymbol_name (base);
1480
1481 Lisp_Object assoc = Fassoc (name, exclude_keys, Qnil);
1482
1483 if (! NILP (assoc))
1484 {
1485 char new_mods[sizeof ("\\A-\\C-\\H-\\M-\\S-\\s-")];
1486 char *p = new_mods;
1487 Lisp_Object keystring;
1488 if (modifiers & alt_modifier)
1489 { *p++ = '\\'; *p++ = 'A'; *p++ = '-'; }
1490 if (modifiers & ctrl_modifier)
1491 { *p++ = '\\'; *p++ = 'C'; *p++ = '-'; }
1492 if (modifiers & hyper_modifier)
1493 { *p++ = '\\'; *p++ = 'H'; *p++ = '-'; }
1494 if (modifiers & meta_modifier)
1495 { *p++ = '\\'; *p++ = 'M'; *p++ = '-'; }
1496 if (modifiers & shift_modifier)
1497 { *p++ = '\\'; *p++ = 'S'; *p++ = '-'; }
1498 if (modifiers & super_modifier)
1499 { *p++ = '\\'; *p++ = 's'; *p++ = '-'; }
1500 *p = 0;
1501
1502 c = reorder_modifiers (c);
1503 AUTO_STRING_WITH_LEN (new_mods_string, new_mods, p - new_mods);
1504 keystring = concat2 (new_mods_string, XCDR (assoc));
1505
1506 error ("To bind the key %s, use [?%s], not [%s]",
1507 SDATA (SYMBOL_NAME (c)), SDATA (keystring),
1508 SDATA (SYMBOL_NAME (c)));
1509 }
1510 }
1511
1512
1513
1514
1515
1516
1517 static Lisp_Object *cmm_modes = NULL, *cmm_maps = NULL;
1518 static ptrdiff_t cmm_size = 0;
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538 ptrdiff_t
1539 current_minor_maps (Lisp_Object **modeptr, Lisp_Object **mapptr)
1540 {
1541 ptrdiff_t i = 0;
1542 Lisp_Object alist, assoc, var, val;
1543 Lisp_Object emulation_alists = Vemulation_mode_map_alists;
1544 Lisp_Object lists[2];
1545
1546 lists[0] = Vminor_mode_overriding_map_alist;
1547 lists[1] = Vminor_mode_map_alist;
1548
1549 for (int list_number = 0; list_number < 2; list_number++)
1550 {
1551 if (CONSP (emulation_alists))
1552 {
1553 alist = XCAR (emulation_alists);
1554 emulation_alists = XCDR (emulation_alists);
1555 if (SYMBOLP (alist))
1556 alist = find_symbol_value (alist);
1557 list_number = -1;
1558 }
1559 else
1560 alist = lists[list_number];
1561
1562 for ( ; CONSP (alist); alist = XCDR (alist))
1563 if ((assoc = XCAR (alist), CONSP (assoc))
1564 && (var = XCAR (assoc), SYMBOLP (var))
1565 && (val = find_symbol_value (var), !BASE_EQ (val, Qunbound))
1566 && !NILP (val))
1567 {
1568 Lisp_Object temp;
1569
1570
1571
1572
1573 if (list_number == 1)
1574 {
1575 val = assq_no_quit (var, lists[0]);
1576 if (!NILP (val))
1577 continue;
1578 }
1579
1580 if (i >= cmm_size)
1581 {
1582 ptrdiff_t newsize, allocsize;
1583 Lisp_Object *newmodes, *newmaps;
1584
1585
1586
1587
1588 if (min (PTRDIFF_MAX, SIZE_MAX) / (2 * sizeof *newmodes) - 3
1589 < cmm_size)
1590 break;
1591
1592 newsize = cmm_size == 0 ? 30 : cmm_size * 2;
1593 allocsize = newsize * sizeof *newmodes;
1594
1595
1596
1597 block_input ();
1598 newmodes = malloc (allocsize);
1599 if (newmodes)
1600 {
1601 if (cmm_modes)
1602 {
1603 memcpy (newmodes, cmm_modes,
1604 cmm_size * sizeof cmm_modes[0]);
1605 free (cmm_modes);
1606 }
1607 cmm_modes = newmodes;
1608 }
1609
1610 newmaps = malloc (allocsize);
1611 if (newmaps)
1612 {
1613 if (cmm_maps)
1614 {
1615 memcpy (newmaps, cmm_maps,
1616 cmm_size * sizeof cmm_maps[0]);
1617 free (cmm_maps);
1618 }
1619 cmm_maps = newmaps;
1620 }
1621 unblock_input ();
1622
1623 if (newmodes == NULL || newmaps == NULL)
1624 break;
1625 cmm_size = newsize;
1626 }
1627
1628
1629 temp = Findirect_function (XCDR (assoc), Qt);
1630 if (!NILP (temp))
1631 {
1632 cmm_modes[i] = var;
1633 cmm_maps [i] = temp;
1634 i++;
1635 }
1636 }
1637 }
1638
1639 if (modeptr) *modeptr = cmm_modes;
1640 if (mapptr) *mapptr = cmm_maps;
1641 return i;
1642 }
1643
1644
1645
1646 static ptrdiff_t
1647 click_position (Lisp_Object position)
1648 {
1649 EMACS_INT pos = (FIXNUMP (position) ? XFIXNUM (position)
1650 : MARKERP (position) ? marker_position (position)
1651 : PT);
1652 if (! (BEGV <= pos && pos <= ZV))
1653 args_out_of_range (Fcurrent_buffer (), position);
1654 return pos;
1655 }
1656
1657 DEFUN ("current-active-maps", Fcurrent_active_maps, Scurrent_active_maps,
1658 0, 2, 0,
1659 doc:
1660
1661
1662 )
1663 (Lisp_Object olp, Lisp_Object position)
1664 {
1665 specpdl_ref count = SPECPDL_INDEX ();
1666
1667 Lisp_Object keymaps = list1 (current_global_map);
1668
1669
1670
1671
1672
1673 if (CONSP (position))
1674 {
1675 Lisp_Object window = POSN_WINDOW (position);
1676
1677 if (WINDOWP (window)
1678 && BUFFERP (XWINDOW (window)->contents)
1679 && XBUFFER (XWINDOW (window)->contents) != current_buffer)
1680 {
1681
1682
1683
1684
1685
1686
1687
1688 record_unwind_current_buffer ();
1689 set_buffer_internal (XBUFFER (XWINDOW (window)->contents));
1690 }
1691 }
1692
1693 if (!NILP (olp)
1694
1695
1696
1697 && NILP (KVAR (current_kboard, Voverriding_terminal_local_map))
1698 && !NILP (Voverriding_local_map))
1699 keymaps = Fcons (Voverriding_local_map, keymaps);
1700
1701 if (NILP (XCDR (keymaps)))
1702 {
1703 Lisp_Object *maps;
1704 int nmaps;
1705 ptrdiff_t pt = click_position (position);
1706
1707
1708 Lisp_Object local_map = get_local_map (pt, current_buffer, Qlocal_map);
1709
1710 Lisp_Object keymap = get_local_map (pt, current_buffer, Qkeymap);
1711 Lisp_Object otlp = KVAR (current_kboard, Voverriding_terminal_local_map);
1712
1713 if (CONSP (position))
1714 {
1715 Lisp_Object string = POSN_STRING (position);
1716
1717
1718
1719
1720 if (POSN_INBUFFER_P (position))
1721 {
1722 Lisp_Object pos = POSN_BUFFER_POSN (position);
1723 if (FIXNUMP (pos)
1724 && XFIXNUM (pos) >= BEG && XFIXNUM (pos) <= Z)
1725 {
1726 local_map = get_local_map (XFIXNUM (pos),
1727 current_buffer, Qlocal_map);
1728
1729 keymap = get_local_map (XFIXNUM (pos),
1730 current_buffer, Qkeymap);
1731 }
1732 }
1733
1734
1735
1736
1737
1738
1739
1740 if (CONSP (string) && STRINGP (XCAR (string)))
1741 {
1742 Lisp_Object pos = XCDR (string);
1743 string = XCAR (string);
1744 if (FIXNUMP (pos)
1745 && XFIXNUM (pos) >= 0
1746 && XFIXNUM (pos) < SCHARS (string))
1747 {
1748 Lisp_Object map = Fget_text_property (pos, Qlocal_map, string);
1749 if (!NILP (map))
1750 local_map = map;
1751
1752 map = Fget_text_property (pos, Qkeymap, string);
1753 if (!NILP (map))
1754 keymap = map;
1755 }
1756 }
1757
1758 }
1759
1760 if (!NILP (local_map))
1761 keymaps = Fcons (local_map, keymaps);
1762
1763
1764 nmaps = current_minor_maps (0, &maps);
1765
1766 for (int i = --nmaps; i >= 0; i--)
1767 if (!NILP (maps[i]))
1768 keymaps = Fcons (maps[i], keymaps);
1769
1770 if (!NILP (keymap))
1771 keymaps = Fcons (keymap, keymaps);
1772
1773 if (!NILP (olp) && !NILP (otlp))
1774 keymaps = Fcons (otlp, keymaps);
1775 }
1776
1777 return unbind_to (count, keymaps);
1778 }
1779
1780
1781
1782 DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 4, 0,
1783 doc:
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807 )
1808 (Lisp_Object key, Lisp_Object accept_default, Lisp_Object no_remap, Lisp_Object position)
1809 {
1810 if (NILP (position) && VECTORP (key))
1811 {
1812 if (ASIZE (key) == 0)
1813 return Qnil;
1814
1815
1816
1817 Lisp_Object event
1818 = AREF (key, SYMBOLP (AREF (key, 0)) && ASIZE (key) > 1 ? 1 : 0);
1819
1820
1821
1822 if (EVENT_HAS_PARAMETERS (event) && CONSP (XCDR (event)))
1823 {
1824 Lisp_Object kind = EVENT_HEAD_KIND (EVENT_HEAD (event));
1825 if (EQ (kind, Qmouse_click))
1826 position = EVENT_START (event);
1827 }
1828 }
1829
1830 Lisp_Object value = Flookup_key (Fcurrent_active_maps (Qt, position),
1831 key, accept_default);
1832
1833 if (NILP (value) || FIXNUMP (value))
1834 return Qnil;
1835
1836
1837
1838
1839 if (NILP (no_remap) && SYMBOLP (value))
1840 {
1841 Lisp_Object value1;
1842 if (value1 = Fcommand_remapping (value, position, Qnil), !NILP (value1))
1843 value = value1;
1844 }
1845
1846 return value;
1847 }
1848
1849
1850
1851 DEFUN ("minor-mode-key-binding", Fminor_mode_key_binding, Sminor_mode_key_binding, 1, 2, 0,
1852 doc:
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862 )
1863 (Lisp_Object key, Lisp_Object accept_default)
1864 {
1865 Lisp_Object *modes, *maps;
1866 int nmaps = current_minor_maps (&modes, &maps);
1867 Lisp_Object binding = Qnil;
1868
1869 int j;
1870 for (int i = j = 0; i < nmaps; i++)
1871 if (!NILP (maps[i])
1872 && !NILP (binding = Flookup_key (maps[i], key, accept_default))
1873 && !FIXNUMP (binding))
1874 {
1875 if (KEYMAPP (binding))
1876 maps[j++] = Fcons (modes[i], binding);
1877 else if (j == 0)
1878 return list1 (Fcons (modes[i], binding));
1879 }
1880
1881 return Flist (j, maps);
1882 }
1883
1884 DEFUN ("use-global-map", Fuse_global_map, Suse_global_map, 1, 1, 0,
1885 doc: )
1886 (Lisp_Object keymap)
1887 {
1888 keymap = get_keymap (keymap, 1, 1);
1889 current_global_map = keymap;
1890
1891 return Qnil;
1892 }
1893
1894 DEFUN ("use-local-map", Fuse_local_map, Suse_local_map, 1, 1, 0,
1895 doc:
1896 )
1897 (Lisp_Object keymap)
1898 {
1899 if (!NILP (keymap))
1900 keymap = get_keymap (keymap, 1, 1);
1901
1902 bset_keymap (current_buffer, keymap);
1903
1904 return Qnil;
1905 }
1906
1907 DEFUN ("current-local-map", Fcurrent_local_map, Scurrent_local_map, 0, 0, 0,
1908 doc:
1909 )
1910 (void)
1911 {
1912 return BVAR (current_buffer, keymap);
1913 }
1914
1915 DEFUN ("current-global-map", Fcurrent_global_map, Scurrent_global_map, 0, 0, 0,
1916 doc: )
1917 (void)
1918 {
1919 return current_global_map;
1920 }
1921
1922 DEFUN ("current-minor-mode-maps", Fcurrent_minor_mode_maps, Scurrent_minor_mode_maps, 0, 0, 0,
1923 doc: )
1924 (void)
1925 {
1926 Lisp_Object *maps;
1927 int nmaps = current_minor_maps (0, &maps);
1928
1929 return Flist (nmaps, maps);
1930 }
1931
1932
1933
1934 struct accessible_keymaps_data {
1935 Lisp_Object maps, tail, thisseq;
1936
1937 bool is_metized;
1938 };
1939
1940 static void
1941 accessible_keymaps_1 (Lisp_Object key, Lisp_Object cmd, Lisp_Object args, void *data)
1942
1943 {
1944 struct accessible_keymaps_data *d = data;
1945 Lisp_Object maps = d->maps;
1946 Lisp_Object tail = d->tail;
1947 Lisp_Object thisseq = d->thisseq;
1948 bool is_metized = d->is_metized && FIXNUMP (key);
1949 Lisp_Object tem;
1950
1951 cmd = get_keymap (get_keyelt (cmd, 0), 0, 0);
1952 if (NILP (cmd))
1953 return;
1954
1955
1956 while (!NILP (tem = Frassq (cmd, maps)))
1957 {
1958 Lisp_Object prefix = XCAR (tem);
1959 ptrdiff_t lim = XFIXNUM (Flength (XCAR (tem)));
1960 if (lim <= XFIXNUM (Flength (thisseq)))
1961 {
1962 ptrdiff_t i = 0;
1963 while (i < lim && EQ (Faref (prefix, make_fixnum (i)),
1964 Faref (thisseq, make_fixnum (i))))
1965 i++;
1966 if (i >= lim)
1967
1968 return;
1969 }
1970
1971
1972
1973 maps = XCDR (Fmemq (tem, maps));
1974 }
1975
1976
1977
1978
1979
1980
1981 if (is_metized)
1982 {
1983 int meta_bit = meta_modifier;
1984 Lisp_Object last = make_fixnum (XFIXNUM (Flength (thisseq)) - 1);
1985 tem = Fcopy_sequence (thisseq);
1986
1987 Faset (tem, last, make_fixnum (XFIXNUM (key) | meta_bit));
1988
1989
1990
1991
1992 XSETCDR (tail,
1993 Fcons (Fcons (tem, cmd), XCDR (tail)));
1994 }
1995 else
1996 {
1997 tem = append_key (thisseq, key);
1998 nconc2 (tail, list1 (Fcons (tem, cmd)));
1999 }
2000 }
2001
2002
2003
2004 DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps,
2005 1, 2, 0,
2006 doc:
2007
2008
2009
2010
2011 )
2012 (Lisp_Object keymap, Lisp_Object prefix)
2013 {
2014 Lisp_Object maps, tail;
2015 EMACS_INT prefixlen = XFIXNAT (Flength (prefix));
2016
2017 if (!NILP (prefix))
2018 {
2019
2020
2021 Lisp_Object tem = Flookup_key (keymap, prefix, Qt);
2022
2023
2024
2025 tem = get_keymap (tem, 0, 0);
2026
2027
2028 if (!NILP (tem))
2029 {
2030
2031
2032 if (STRINGP (prefix))
2033 {
2034 ptrdiff_t i_byte = 0;
2035 Lisp_Object copy = make_nil_vector (SCHARS (prefix));
2036 for (ptrdiff_t i = 0; i < SCHARS (prefix); )
2037 {
2038 ptrdiff_t i_before = i;
2039 int c = fetch_string_char_advance (prefix, &i, &i_byte);
2040 if (SINGLE_BYTE_CHAR_P (c) && (c & 0200))
2041 c ^= 0200 | meta_modifier;
2042 ASET (copy, i_before, make_fixnum (c));
2043 }
2044 prefix = copy;
2045 }
2046 maps = list1 (Fcons (prefix, tem));
2047 }
2048 else
2049 return Qnil;
2050 }
2051 else
2052 maps = list1 (Fcons (zero_vector, get_keymap (keymap, 1, 0)));
2053
2054
2055
2056
2057
2058
2059
2060
2061 for (tail = maps; CONSP (tail); tail = XCDR (tail))
2062 {
2063 struct accessible_keymaps_data data;
2064 register Lisp_Object thismap = Fcdr (XCAR (tail));
2065 Lisp_Object last;
2066
2067 data.thisseq = Fcar (XCAR (tail));
2068 data.maps = maps;
2069 data.tail = tail;
2070 last = make_fixnum (XFIXNUM (Flength (data.thisseq)) - 1);
2071
2072 data.is_metized = (XFIXNUM (last) >= 0
2073
2074 && XFIXNUM (last) >= prefixlen
2075 && EQ (Faref (data.thisseq, last), meta_prefix_char));
2076
2077
2078 if (CONSP (thismap))
2079 map_keymap (thismap, accessible_keymaps_1, Qnil, &data, 0);
2080 }
2081 return maps;
2082 }
2083
2084
2085
2086 DEFUN ("key-description", Fkey_description, Skey_description, 1, 2, 0,
2087 doc:
2088
2089
2090
2091 )
2092 (Lisp_Object keys, Lisp_Object prefix)
2093 {
2094 ptrdiff_t len = 0;
2095 Lisp_Object *args;
2096 EMACS_INT nkeys = XFIXNUM (Flength (keys));
2097 EMACS_INT nprefix = XFIXNUM (Flength (prefix));
2098 Lisp_Object sep = build_string (" ");
2099 bool add_meta = false;
2100 USE_SAFE_ALLOCA;
2101
2102
2103 ptrdiff_t size4;
2104 if (ckd_mul (&size4, nkeys + nprefix, 4))
2105 memory_full (SIZE_MAX);
2106 SAFE_ALLOCA_LISP (args, size4);
2107
2108
2109
2110
2111
2112 Lisp_Object lists[2] = { prefix, keys };
2113 ptrdiff_t listlens[2] = { nprefix, nkeys };
2114 for (int li = 0; li < ARRAYELTS (lists); li++)
2115 {
2116 Lisp_Object list = lists[li];
2117 ptrdiff_t listlen = listlens[li], i_byte = 0;
2118
2119 if (! (NILP (list) || STRINGP (list) || VECTORP (list) || CONSP (list)))
2120 wrong_type_argument (Qarrayp, list);
2121
2122 for (ptrdiff_t i = 0; i < listlen; )
2123 {
2124 Lisp_Object key;
2125 if (STRINGP (list))
2126 {
2127 int c = fetch_string_char_advance (list, &i, &i_byte);
2128 if (SINGLE_BYTE_CHAR_P (c) && (c & 0200))
2129 c ^= 0200 | meta_modifier;
2130 key = make_fixnum (c);
2131 }
2132 else if (VECTORP (list))
2133 {
2134 key = AREF (list, i);
2135 i++;
2136 }
2137 else
2138 {
2139 key = XCAR (list);
2140 list = XCDR (list);
2141 i++;
2142 }
2143
2144 if (add_meta)
2145 {
2146 if (!FIXNUMP (key)
2147 || EQ (key, meta_prefix_char)
2148 || (XFIXNUM (key) & meta_modifier))
2149 {
2150 args[len++] = Fsingle_key_description (meta_prefix_char,
2151 Qnil);
2152 args[len++] = sep;
2153 if (EQ (key, meta_prefix_char))
2154 continue;
2155 }
2156 else
2157 key = make_fixnum (XFIXNUM (key) | meta_modifier);
2158 add_meta = false;
2159 }
2160 else if (EQ (key, meta_prefix_char))
2161 {
2162 add_meta = true;
2163 continue;
2164 }
2165 args[len++] = Fsingle_key_description (key, Qnil);
2166 args[len++] = sep;
2167 }
2168 }
2169
2170 Lisp_Object result;
2171 if (add_meta)
2172 {
2173 args[len] = Fsingle_key_description (meta_prefix_char, Qnil);
2174 result = Fconcat (len + 1, args);
2175 }
2176 else if (len == 0)
2177 result = empty_unibyte_string;
2178 else
2179 result = Fconcat (len - 1, args);
2180 SAFE_FREE ();
2181 return result;
2182 }
2183
2184
2185 char *
2186 push_key_description (EMACS_INT ch, char *p)
2187 {
2188 int c, c2;
2189 bool tab_as_ci;
2190
2191
2192 c = ch & (meta_modifier | ~ - meta_modifier);
2193 c2 = c & ~(alt_modifier | ctrl_modifier | hyper_modifier
2194 | meta_modifier | shift_modifier | super_modifier);
2195
2196 if (! CHARACTERP (make_fixnum (c2)))
2197 {
2198
2199 p += sprintf (p, "[%d]", c);
2200 return p;
2201 }
2202
2203 tab_as_ci = (c2 == '\t' && (c & meta_modifier));
2204
2205 if (c & alt_modifier)
2206 {
2207 *p++ = 'A';
2208 *p++ = '-';
2209 c -= alt_modifier;
2210 }
2211 if ((c & ctrl_modifier) != 0
2212 || (c2 < ' ' && c2 != 27 && c2 != '\t' && c2 != Ctl ('M'))
2213 || tab_as_ci)
2214 {
2215 *p++ = 'C';
2216 *p++ = '-';
2217 c &= ~ctrl_modifier;
2218 }
2219 if (c & hyper_modifier)
2220 {
2221 *p++ = 'H';
2222 *p++ = '-';
2223 c -= hyper_modifier;
2224 }
2225 if (c & meta_modifier)
2226 {
2227 *p++ = 'M';
2228 *p++ = '-';
2229 c -= meta_modifier;
2230 }
2231 if (c & shift_modifier)
2232 {
2233 *p++ = 'S';
2234 *p++ = '-';
2235 c -= shift_modifier;
2236 }
2237 if (c & super_modifier)
2238 {
2239 *p++ = 's';
2240 *p++ = '-';
2241 c -= super_modifier;
2242 }
2243 if (c < 040)
2244 {
2245 if (c == 033)
2246 {
2247 *p++ = 'E';
2248 *p++ = 'S';
2249 *p++ = 'C';
2250 }
2251 else if (tab_as_ci)
2252 {
2253 *p++ = 'i';
2254 }
2255 else if (c == '\t')
2256 {
2257 *p++ = 'T';
2258 *p++ = 'A';
2259 *p++ = 'B';
2260 }
2261 else if (c == Ctl ('M'))
2262 {
2263 *p++ = 'R';
2264 *p++ = 'E';
2265 *p++ = 'T';
2266 }
2267 else
2268 {
2269
2270 if (c > 0 && c <= Ctl ('Z'))
2271 *p++ = c + 0140;
2272 else
2273 *p++ = c + 0100;
2274 }
2275 }
2276 else if (c == 0177)
2277 {
2278 *p++ = 'D';
2279 *p++ = 'E';
2280 *p++ = 'L';
2281 }
2282 else if (c == ' ')
2283 {
2284 *p++ = 'S';
2285 *p++ = 'P';
2286 *p++ = 'C';
2287 }
2288 else if (c < 128)
2289 *p++ = c;
2290 else
2291 {
2292
2293 p += CHAR_STRING (c, (unsigned char *) p);
2294 }
2295
2296 return p;
2297 }
2298
2299
2300
2301 DEFUN ("single-key-description", Fsingle_key_description,
2302 Ssingle_key_description, 1, 2, 0,
2303 doc:
2304
2305
2306
2307
2308 )
2309 (Lisp_Object key, Lisp_Object no_angles)
2310 {
2311 USE_SAFE_ALLOCA;
2312
2313 if (CONSP (key) && lucid_event_type_list_p (key))
2314 key = Fevent_convert_list (key);
2315
2316 if (CONSP (key) && FIXNUMP (XCAR (key)) && FIXNUMP (XCDR (key)))
2317
2318 {
2319 AUTO_STRING (dot_dot, "..");
2320 return concat3 (Fsingle_key_description (XCAR (key), no_angles),
2321 dot_dot,
2322 Fsingle_key_description (XCDR (key), no_angles));
2323 }
2324
2325 key = EVENT_HEAD (key);
2326
2327 if (FIXNUMP (key))
2328 {
2329 char tem[KEY_DESCRIPTION_SIZE];
2330 char *p = push_key_description (XFIXNUM (key), tem);
2331 *p = 0;
2332 return make_specified_string (tem, -1, p - tem, 1);
2333 }
2334 else if (SYMBOLP (key))
2335 {
2336 if (NILP (no_angles))
2337 {
2338 Lisp_Object namestr = SYMBOL_NAME (key);
2339 const char *sym = SSDATA (namestr);
2340 ptrdiff_t len = SBYTES (namestr);
2341
2342 int i = 0;
2343 while (i < len - 3 && sym[i + 1] == '-' && strchr ("CMSsHA", sym[i]))
2344 i += 2;
2345
2346 char *buffer = SAFE_ALLOCA (len + 3);
2347 memcpy (buffer, sym, i);
2348 buffer[i] = '<';
2349 memcpy (buffer + i + 1, sym + i, len - i);
2350 buffer [len + 1] = '>';
2351 buffer [len + 2] = '\0';
2352 Lisp_Object result = build_string (buffer);
2353 SAFE_FREE ();
2354 return result;
2355 }
2356 else
2357 return Fsymbol_name (key);
2358 }
2359 else if (STRINGP (key))
2360 return Fcopy_sequence (key);
2361 else
2362 error ("KEY must be an integer, cons, symbol, or string");
2363 }
2364
2365 static char *
2366 push_text_char_description (register unsigned int c, register char *p)
2367 {
2368 if (c < 040)
2369 {
2370 *p++ = '^';
2371 *p++ = c + 64;
2372 }
2373 else if (c == 0177)
2374 {
2375 *p++ = '^';
2376 *p++ = '?';
2377 }
2378 else
2379 *p++ = c;
2380 return p;
2381 }
2382
2383
2384
2385 DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, 1, 1, 0,
2386 doc:
2387
2388
2389
2390
2391
2392
2393 )
2394 (Lisp_Object character)
2395 {
2396 CHECK_CHARACTER (character);
2397
2398 int c = XFIXNUM (character);
2399 if (!ASCII_CHAR_P (c))
2400 {
2401 char str[MAX_MULTIBYTE_LENGTH];
2402 int len = CHAR_STRING (c, (unsigned char *) str);
2403
2404 return make_multibyte_string (str, 1, len);
2405 }
2406 else
2407 {
2408 char desc[4];
2409 int len = push_text_char_description (c, desc) - desc;
2410 return make_string (desc, len);
2411 }
2412 }
2413
2414 static int where_is_preferred_modifier;
2415
2416
2417
2418
2419 static int
2420 preferred_sequence_p (Lisp_Object seq)
2421 {
2422 EMACS_INT i;
2423 EMACS_INT len = XFIXNAT (Flength (seq));
2424 int result = 1;
2425
2426 for (i = 0; i < len; i++)
2427 {
2428 Lisp_Object ii, elt;
2429
2430 XSETFASTINT (ii, i);
2431 elt = Faref (seq, ii);
2432
2433 if (!FIXNUMP (elt))
2434 return 0;
2435 else
2436 {
2437 int modifiers = XFIXNUM (elt) & (CHAR_MODIFIER_MASK & ~CHAR_META);
2438 if (modifiers == where_is_preferred_modifier)
2439 result = 2;
2440 else if (modifiers)
2441 return 0;
2442 }
2443 }
2444
2445 return result;
2446 }
2447
2448
2449
2450
2451 static void where_is_internal_1 (Lisp_Object key, Lisp_Object binding,
2452 Lisp_Object args, void *data);
2453
2454
2455
2456
2457 static Lisp_Object
2458 shadow_lookup (Lisp_Object keymap, Lisp_Object key, Lisp_Object accept_default,
2459 bool remap)
2460 {
2461 Lisp_Object value = Flookup_key (keymap, key, accept_default);
2462
2463 if (FIXNATP (value))
2464 return Qnil;
2465 else if (!NILP (value) && remap && SYMBOLP (value))
2466 {
2467 Lisp_Object remapping = Fcommand_remapping (value, Qnil, keymap);
2468 return (!NILP (remapping) ? remapping : value);
2469 }
2470 else
2471 return value;
2472 }
2473
2474 static Lisp_Object Vmouse_events;
2475
2476 struct where_is_internal_data {
2477 Lisp_Object definition, this, last;
2478 bool last_is_meta, noindirect;
2479 Lisp_Object sequences;
2480 };
2481
2482
2483
2484
2485
2486
2487
2488
2489 static Lisp_Object
2490 where_is_internal (Lisp_Object definition, Lisp_Object keymaps,
2491 bool noindirect, bool nomenus)
2492 {
2493 Lisp_Object maps = Qnil;
2494 struct where_is_internal_data data;
2495
2496
2497
2498 if (nomenus && !noindirect)
2499 {
2500
2501 if (NILP (Fequal (keymaps, where_is_cache_keymaps)))
2502 where_is_cache = Qnil;
2503
2504 if (NILP (where_is_cache))
2505 {
2506
2507 where_is_cache = Fmake_hash_table (0, NULL);
2508 where_is_cache_keymaps = Qt;
2509 }
2510 else
2511
2512 return Fgethash (definition, where_is_cache, Qnil);
2513 }
2514 else
2515
2516
2517 where_is_cache = Qnil;
2518
2519 Lisp_Object found = keymaps;
2520 while (CONSP (found))
2521 {
2522 maps =
2523 nconc2 (maps,
2524 Faccessible_keymaps (get_keymap (XCAR (found), 1, 0), Qnil));
2525 found = XCDR (found);
2526 }
2527
2528 data.sequences = Qnil;
2529 for (; CONSP (maps); maps = XCDR (maps))
2530 {
2531
2532 register Lisp_Object this, map, tem;
2533
2534
2535
2536
2537 Lisp_Object last;
2538 bool last_is_meta;
2539
2540 this = Fcar (XCAR (maps));
2541 map = Fcdr (XCAR (maps));
2542 last = make_fixnum (XFIXNUM (Flength (this)) - 1);
2543 last_is_meta = (XFIXNUM (last) >= 0
2544 && EQ (Faref (this, last), meta_prefix_char));
2545
2546
2547 if (nomenus && XFIXNUM (last) >= 0
2548 && SYMBOLP (tem = Faref (this, make_fixnum (0)))
2549 && !NILP (Fmemq (XCAR (parse_modifiers (tem)), Vmouse_events)))
2550
2551
2552
2553 continue;
2554
2555 maybe_quit ();
2556
2557 data.definition = definition;
2558 data.noindirect = noindirect;
2559 data.this = this;
2560 data.last = last;
2561 data.last_is_meta = last_is_meta;
2562
2563 if (CONSP (map))
2564 map_keymap (map, where_is_internal_1, Qnil, &data, 0);
2565 }
2566
2567 if (nomenus && !noindirect)
2568 {
2569
2570
2571 where_is_cache_keymaps = keymaps;
2572
2573
2574 return Fgethash (definition, where_is_cache, Qnil);
2575 }
2576 else
2577 return data.sequences;
2578 }
2579
2580
2581
2582 DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 5, 0,
2583 doc:
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613 )
2614 (Lisp_Object definition, Lisp_Object keymap, Lisp_Object firstonly, Lisp_Object noindirect, Lisp_Object no_remap)
2615 {
2616
2617 Lisp_Object keymaps;
2618
2619 Lisp_Object sequences = Qnil;
2620
2621 Lisp_Object found = Qnil;
2622
2623 bool nomenus = !NILP (firstonly) && !EQ (firstonly, Qnon_ascii);
2624
2625
2626
2627 Lisp_Object remapped_sequences = Qnil;
2628
2629
2630
2631 bool remapped = false;
2632
2633
2634 where_is_preferred_modifier
2635 = parse_solitary_modifier (Vwhere_is_preferred_modifier);
2636
2637
2638 if (CONSP (keymap) && KEYMAPP (XCAR (keymap)))
2639 keymaps = keymap;
2640 else if (!NILP (keymap))
2641 keymaps = list2 (keymap, current_global_map);
2642 else
2643 keymaps = Fcurrent_active_maps (Qnil, Qnil);
2644
2645 Lisp_Object tem = Fcommand_remapping (definition, Qnil, keymaps);
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660 if (NILP (no_remap) && !NILP (tem))
2661 definition = tem;
2662
2663 if (SYMBOLP (definition)
2664 && !NILP (firstonly)
2665 && !NILP (tem = Fget (definition, QCadvertised_binding)))
2666 {
2667
2668
2669
2670 while (CONSP (tem))
2671 if (EQ (shadow_lookup (keymaps, XCAR (tem), Qnil, 0), definition))
2672 return XCAR (tem);
2673 else
2674 tem = XCDR (tem);
2675 if (EQ (shadow_lookup (keymaps, tem, Qnil, 0), definition))
2676 return tem;
2677 }
2678
2679 sequences = Freverse (where_is_internal (definition, keymaps,
2680 !NILP (noindirect), nomenus));
2681
2682 while (CONSP (sequences)
2683
2684
2685
2686 || (!remapped && (sequences = remapped_sequences,
2687 remapped = true,
2688 CONSP (sequences))))
2689 {
2690 Lisp_Object sequence, function;
2691
2692 sequence = XCAR (sequences);
2693 sequences = XCDR (sequences);
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704 if (NILP (Fequal (shadow_lookup (keymaps, sequence, Qnil, remapped),
2705 definition)))
2706 continue;
2707
2708
2709
2710
2711 if (NILP (no_remap) && !remapped
2712 && VECTORP (sequence) && ASIZE (sequence) == 2
2713 && EQ (AREF (sequence, 0), Qremap)
2714 && (function = AREF (sequence, 1), SYMBOLP (function)))
2715 {
2716 Lisp_Object seqs = where_is_internal (function, keymaps,
2717 !NILP (noindirect), nomenus);
2718 remapped_sequences = nconc2 (Freverse (seqs), remapped_sequences);
2719 continue;
2720 }
2721
2722
2723
2724
2725
2726 if (! NILP (sequence))
2727 {
2728 Lisp_Object tem1;
2729 tem1 = Faref (sequence, make_fixnum (ASIZE (sequence) - 1));
2730 if (STRINGP (tem1))
2731 Faset (sequence, make_fixnum (ASIZE (sequence) - 1),
2732 build_string ("(any string)"));
2733 }
2734
2735
2736
2737 if (NILP (Fmember (sequence, found))
2738
2739 && !(VECTORP (sequence)
2740 && ASIZE (sequence) == 1
2741 && SYMBOLP (AREF (sequence, 0))
2742 && !NILP (Fget (AREF (sequence, 0), Qnon_key_event))))
2743 found = Fcons (sequence, found);
2744
2745
2746
2747
2748
2749 if (EQ (firstonly, Qnon_ascii))
2750 return sequence;
2751 else if (!NILP (firstonly)
2752 && 2 == preferred_sequence_p (sequence))
2753 return sequence;
2754 }
2755
2756 found = Fnreverse (found);
2757
2758
2759
2760
2761 if (NILP (firstonly))
2762 return found;
2763 else if (where_is_preferred_modifier == 0)
2764 return Fcar (found);
2765 else
2766 {
2767
2768 Lisp_Object bindings = found;
2769 while (CONSP (bindings))
2770 if (preferred_sequence_p (XCAR (bindings)))
2771 return XCAR (bindings);
2772 else
2773 bindings = XCDR (bindings);
2774 return Fcar (found);
2775 }
2776 }
2777
2778
2779
2780 static void
2781 where_is_internal_1 (Lisp_Object key, Lisp_Object binding, Lisp_Object args, void *data)
2782 {
2783 struct where_is_internal_data *d = data;
2784 Lisp_Object definition = d->definition;
2785 bool noindirect = d->noindirect;
2786 Lisp_Object this = d->this;
2787 Lisp_Object last = d->last;
2788 bool last_is_meta = d->last_is_meta;
2789 Lisp_Object sequence;
2790
2791
2792 if (!noindirect)
2793 binding = get_keyelt (binding, 0);
2794
2795
2796
2797
2798 if (!(!NILP (where_is_cache)
2799 || EQ (binding, definition)
2800 || (CONSP (definition) && !NILP (Fequal (binding, definition)))))
2801
2802 return;
2803
2804
2805 if (FIXNUMP (key) && last_is_meta)
2806 {
2807 sequence = Fcopy_sequence (this);
2808 Faset (sequence, last, make_fixnum (XFIXNUM (key) | meta_modifier));
2809 }
2810 else
2811 {
2812 if (CONSP (key))
2813 key = Fcons (XCAR (key), XCDR (key));
2814 sequence = append_key (this, key);
2815 }
2816
2817 if (!NILP (where_is_cache))
2818 {
2819 Lisp_Object sequences = Fgethash (binding, where_is_cache, Qnil);
2820 Fputhash (binding, Fcons (sequence, sequences), where_is_cache);
2821 }
2822 else
2823 d->sequences = Fcons (sequence, d->sequences);
2824 }
2825
2826
2827
2828 DEFUN ("describe-buffer-bindings", Fdescribe_buffer_bindings, Sdescribe_buffer_bindings, 1, 3, 0,
2829 doc:
2830
2831
2832
2833
2834
2835 )
2836 (Lisp_Object buffer, Lisp_Object prefix, Lisp_Object menus)
2837 {
2838 Lisp_Object nomenu = NILP (menus) ? Qt : Qnil;
2839
2840 const char *alternate_heading
2841 = "\
2842 Keyboard translations:\n\n\
2843 You type Translation\n\
2844 -------- -----------\n";
2845
2846 CHECK_BUFFER (buffer);
2847
2848 Lisp_Object shadow = Qnil;
2849 Lisp_Object outbuf = Fcurrent_buffer ();
2850
2851
2852 if (STRINGP (KVAR (current_kboard, Vkeyboard_translate_table)) && !NILP (prefix))
2853 {
2854 const unsigned char *translate = SDATA (KVAR (current_kboard, Vkeyboard_translate_table));
2855 int translate_len = SCHARS (KVAR (current_kboard, Vkeyboard_translate_table));
2856
2857 for (int c = 0; c < translate_len; c++)
2858 if (translate[c] != c)
2859 {
2860 char buf[KEY_DESCRIPTION_SIZE];
2861 char *bufend;
2862
2863 if (alternate_heading)
2864 {
2865 insert_string (alternate_heading);
2866 alternate_heading = 0;
2867 }
2868
2869 bufend = push_key_description (translate[c], buf);
2870 insert (buf, bufend - buf);
2871 Findent_to (make_fixnum (16), make_fixnum (1));
2872 bufend = push_key_description (c, buf);
2873 insert (buf, bufend - buf);
2874
2875 insert ("\n", 1);
2876
2877
2878 translate = SDATA (KVAR (current_kboard, Vkeyboard_translate_table));
2879 }
2880
2881 insert ("\n", 1);
2882 }
2883
2884 if (!NILP (Vkey_translation_map))
2885 {
2886 Lisp_Object msg = build_unibyte_string ("Key translations");
2887 CALLN (Ffuncall,
2888 Qdescribe_map_tree,
2889 Vkey_translation_map, Qnil, Qnil, prefix,
2890 msg, nomenu, Qt, Qnil, Qnil, buffer);
2891 }
2892
2893
2894 Lisp_Object start1 = Qnil;
2895 if (!NILP (KVAR (current_kboard, Voverriding_terminal_local_map)))
2896 start1 = KVAR (current_kboard, Voverriding_terminal_local_map);
2897
2898 if (!NILP (start1))
2899 {
2900 Lisp_Object msg = build_unibyte_string ("\f\nOverriding Bindings");
2901 CALLN (Ffuncall,
2902 Qdescribe_map_tree,
2903 start1, Qt, shadow, prefix,
2904 msg, nomenu, Qnil, Qnil, Qnil, buffer);
2905 shadow = Fcons (start1, shadow);
2906 start1 = Qnil;
2907 }
2908 else if (!NILP (Voverriding_local_map))
2909 start1 = Voverriding_local_map;
2910
2911 if (!NILP (start1))
2912 {
2913 Lisp_Object msg = build_unibyte_string ("\f\nOverriding Bindings");
2914 CALLN (Ffuncall,
2915 Qdescribe_map_tree,
2916 start1, Qt, shadow, prefix,
2917 msg, nomenu, Qnil, Qnil, Qnil, buffer);
2918 shadow = Fcons (start1, shadow);
2919 }
2920 else
2921 {
2922
2923 Lisp_Object *modes, *maps;
2924
2925
2926
2927 Fset_buffer (buffer);
2928
2929 int nmaps = current_minor_maps (&modes, &maps);
2930 Fset_buffer (outbuf);
2931
2932 start1 = get_local_map (BUF_PT (XBUFFER (buffer)),
2933 XBUFFER (buffer), Qkeymap);
2934 if (!NILP (start1))
2935 {
2936 Lisp_Object msg = build_unibyte_string ("\f\n`keymap' Property Bindings");
2937 CALLN (Ffuncall,
2938 Qdescribe_map_tree,
2939 start1, Qt, shadow, prefix,
2940 msg, nomenu, Qnil, Qnil, Qnil, buffer);
2941 shadow = Fcons (start1, shadow);
2942 }
2943
2944
2945 for (int i = 0; i < nmaps; i++)
2946 {
2947
2948
2949
2950
2951 char *title, *p;
2952
2953 if (!SYMBOLP (modes[i]))
2954 emacs_abort ();
2955
2956 USE_SAFE_ALLOCA;
2957 p = title = SAFE_ALLOCA (42 + SBYTES (SYMBOL_NAME (modes[i])));
2958 *p++ = '\f';
2959 *p++ = '\n';
2960 *p++ = '`';
2961 memcpy (p, SDATA (SYMBOL_NAME (modes[i])),
2962 SBYTES (SYMBOL_NAME (modes[i])));
2963 p += SBYTES (SYMBOL_NAME (modes[i]));
2964 *p++ = '\'';
2965 memcpy (p, " Minor Mode Bindings", strlen (" Minor Mode Bindings"));
2966 p += strlen (" Minor Mode Bindings");
2967 *p = 0;
2968
2969 Lisp_Object msg = build_unibyte_string (title);
2970 CALLN (Ffuncall,
2971 Qdescribe_map_tree,
2972 maps[i], Qt, shadow, prefix,
2973 msg, nomenu, Qnil, Qnil, Qnil, buffer);
2974 shadow = Fcons (maps[i], shadow);
2975 SAFE_FREE ();
2976 }
2977
2978 start1 = get_local_map (BUF_PT (XBUFFER (buffer)),
2979 XBUFFER (buffer), Qlocal_map);
2980 if (!NILP (start1))
2981 {
2982 if (EQ (start1, BVAR (XBUFFER (buffer), keymap)))
2983 {
2984 Lisp_Object msg =
2985 CALLN (Fformat,
2986 build_unibyte_string ("\f\n`%s' Major Mode Bindings"),
2987 XBUFFER (buffer)->major_mode_);
2988 CALLN (Ffuncall,
2989 Qdescribe_map_tree,
2990 start1, Qt, shadow, prefix,
2991 msg, nomenu, Qnil, Qnil, Qnil, buffer);
2992 }
2993 else
2994 {
2995 Lisp_Object msg = build_unibyte_string ("\f\n`local-map' Property Bindings");
2996 CALLN (Ffuncall,
2997 Qdescribe_map_tree,
2998 start1, Qt, shadow, prefix,
2999 msg, nomenu, Qnil, Qnil, Qnil, buffer);
3000 }
3001
3002 shadow = Fcons (start1, shadow);
3003 }
3004 }
3005
3006 Lisp_Object msg = build_unibyte_string ("\f\nGlobal Bindings");
3007 CALLN (Ffuncall,
3008 Qdescribe_map_tree,
3009 current_global_map, Qt, shadow, prefix,
3010 msg, nomenu, Qnil, Qt, Qnil, buffer);
3011
3012
3013 if (!NILP (KVAR (current_kboard, Vlocal_function_key_map)))
3014 {
3015 Lisp_Object msg = build_unibyte_string ("\f\nFunction key map translations");
3016 CALLN (Ffuncall,
3017 Qdescribe_map_tree,
3018 KVAR (current_kboard, Vlocal_function_key_map), Qnil, Qnil, prefix,
3019 msg, nomenu, Qt, Qnil, Qnil, buffer);
3020 }
3021
3022
3023 if (!NILP (KVAR (current_kboard, Vinput_decode_map)))
3024 {
3025 Lisp_Object msg = build_unibyte_string ("\f\nInput decoding map translations");
3026 CALLN (Ffuncall,
3027 Qdescribe_map_tree,
3028 KVAR (current_kboard, Vinput_decode_map), Qnil, Qnil, prefix,
3029 msg, nomenu, Qt, Qnil, Qnil, buffer);
3030 }
3031 return Qnil;
3032 }
3033
3034 static void
3035 describe_vector_princ (Lisp_Object elt, Lisp_Object fun)
3036 {
3037 Findent_to (make_fixnum (16), make_fixnum (1));
3038 call1 (fun, elt);
3039 Fterpri (Qnil, Qnil);
3040 }
3041
3042 static void
3043 describe_vector_basic (Lisp_Object elt, Lisp_Object fun)
3044 {
3045 call1 (fun, elt);
3046 }
3047
3048 DEFUN ("describe-vector", Fdescribe_vector, Sdescribe_vector, 1, 2, 0,
3049 doc:
3050
3051 )
3052 (Lisp_Object vector, Lisp_Object describer)
3053 {
3054 specpdl_ref count = SPECPDL_INDEX ();
3055 if (NILP (describer))
3056 describer = intern ("princ");
3057 specbind (Qstandard_output, Fcurrent_buffer ());
3058 CHECK_VECTOR_OR_CHAR_TABLE (vector);
3059 describe_vector (vector, Qnil, describer, describe_vector_princ, 0,
3060 Qnil, Qnil, 0, 0);
3061
3062 return unbind_to (count, Qnil);
3063 }
3064
3065 static Lisp_Object fontify_key_properties;
3066
3067 static Lisp_Object
3068 describe_key_maybe_fontify (Lisp_Object str, Lisp_Object prefix,
3069 bool keymap_p)
3070 {
3071 Lisp_Object key_desc = Fkey_description (str, prefix);
3072 if (keymap_p)
3073 Fadd_text_properties (make_fixnum (0),
3074 make_fixnum (SCHARS (key_desc)),
3075 fontify_key_properties,
3076 key_desc);
3077 return key_desc;
3078 }
3079
3080 DEFUN ("help--describe-vector", Fhelp__describe_vector, Shelp__describe_vector, 7, 7, 0,
3081 doc:
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095 )
3096 (Lisp_Object vector, Lisp_Object prefix, Lisp_Object describer,
3097 Lisp_Object partial, Lisp_Object shadow, Lisp_Object entire_map,
3098 Lisp_Object mention_shadow)
3099 {
3100 specpdl_ref count = SPECPDL_INDEX ();
3101 specbind (Qstandard_output, Fcurrent_buffer ());
3102 CHECK_VECTOR_OR_CHAR_TABLE (vector);
3103
3104 bool b_partial = NILP (partial) ? false : true;
3105 bool b_mention_shadow = NILP (mention_shadow) ? false : true;
3106
3107 describe_vector (vector, prefix, describer, describe_vector_basic, b_partial,
3108 shadow, entire_map, true, b_mention_shadow);
3109 return unbind_to (count, Qnil);
3110 }
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144 static void
3145 describe_vector (Lisp_Object vector, Lisp_Object prefix, Lisp_Object args,
3146 void (*elt_describer) (Lisp_Object, Lisp_Object),
3147 bool partial, Lisp_Object shadow, Lisp_Object entire_map,
3148 bool keymap_p, bool mention_shadow)
3149 {
3150 Lisp_Object elt_prefix = Qnil;
3151 Lisp_Object suppress = Qnil;
3152 bool first = true;
3153
3154 int to, stop;
3155
3156 if (!keymap_p)
3157 {
3158 if (!NILP (prefix) && XFIXNAT (Flength (prefix)) > 0)
3159 {
3160 AUTO_STRING (space, " ");
3161 elt_prefix = concat2 (Fkey_description (prefix, Qnil), space);
3162 }
3163 prefix = Qnil;
3164 }
3165
3166
3167
3168
3169 Lisp_Object kludge = make_nil_vector (1);
3170
3171 if (partial)
3172 suppress = intern ("suppress-keymap");
3173
3174
3175
3176
3177 if (CHAR_TABLE_P (vector))
3178 stop = MAX_5_BYTE_CHAR + 1, to = MAX_CHAR + 1;
3179 else
3180 stop = to = ASIZE (vector);
3181
3182 for (int i = 0; ; i++)
3183 {
3184 bool this_shadowed = false;
3185 Lisp_Object shadowed_by = Qnil;
3186 int range_beg;
3187 Lisp_Object val, tem2;
3188
3189 maybe_quit ();
3190
3191 if (i == stop)
3192 {
3193 if (i == to)
3194 break;
3195 stop = to;
3196 }
3197
3198 int starting_i = i;
3199
3200 if (CHAR_TABLE_P (vector))
3201 {
3202
3203
3204
3205
3206 range_beg = i;
3207 i = stop - 1;
3208 val = char_table_ref_and_range (vector, range_beg, &range_beg, &i);
3209 }
3210 else
3211 val = AREF (vector, i);
3212 Lisp_Object definition = get_keyelt (val, 0);
3213
3214 if (NILP (definition)) continue;
3215
3216
3217 if (SYMBOLP (definition) && partial)
3218 {
3219 Lisp_Object tem = Fget (definition, suppress);
3220
3221 if (!NILP (tem)) continue;
3222 }
3223
3224 Lisp_Object character = make_fixnum (starting_i);
3225 ASET (kludge, 0, character);
3226
3227
3228 if (!NILP (shadow))
3229 {
3230 shadowed_by = shadow_lookup (shadow, kludge, Qt, 0);
3231
3232 if (!NILP (shadowed_by) && !EQ (shadowed_by, definition))
3233 {
3234 if (mention_shadow)
3235 this_shadowed = true;
3236 else
3237 continue;
3238 }
3239 }
3240
3241
3242
3243 if (!NILP (entire_map))
3244 {
3245 Lisp_Object tem = Flookup_key (entire_map, kludge, Qt);
3246
3247 if (!EQ (tem, definition))
3248 continue;
3249 }
3250
3251 if (first)
3252 {
3253 insert ("\n", 1);
3254 first = false;
3255 }
3256
3257
3258 if (!NILP (elt_prefix))
3259 insert1 (elt_prefix);
3260
3261 insert1 (describe_key_maybe_fontify (kludge, prefix, keymap_p));
3262
3263
3264
3265 if (!CHAR_TABLE_P (vector))
3266 {
3267 while (i + 1 < stop
3268 && (tem2 = get_keyelt (AREF (vector, i + 1), 0),
3269 !NILP (tem2))
3270 && !NILP (Fequal (tem2, definition)))
3271 i++;
3272 }
3273
3274
3275
3276 if (!NILP (Vdescribe_bindings_check_shadowing_in_ranges)
3277 && CHAR_TABLE_P (vector) && i != starting_i
3278 && (!EQ (Vdescribe_bindings_check_shadowing_in_ranges,
3279 Qignore_self_insert)
3280 || !EQ (definition, Qself_insert_command)))
3281 {
3282 Lisp_Object key = make_nil_vector (1);
3283 for (int j = range_beg + 1; j <= i; j++)
3284 {
3285 ASET (key, 0, make_fixnum (j));
3286 Lisp_Object tem = shadow_lookup (shadow, key, Qt, 0);
3287 if (NILP (Fequal (tem, shadowed_by)))
3288 i = j - 1;
3289 }
3290 }
3291
3292
3293
3294
3295 if (i != starting_i)
3296 {
3297 insert (" .. ", 4);
3298
3299 ASET (kludge, 0, make_fixnum (i));
3300
3301 if (!NILP (elt_prefix))
3302 insert1 (elt_prefix);
3303
3304 insert1 (describe_key_maybe_fontify (kludge, prefix, keymap_p));
3305 }
3306
3307
3308
3309
3310 (*elt_describer) (definition, args);
3311
3312 if (this_shadowed)
3313 {
3314 SET_PT (PT - 1);
3315 if (SYMBOLP (shadowed_by))
3316 {
3317 static char const fmt[] = " (currently shadowed by `%s')";
3318 USE_SAFE_ALLOCA;
3319 char *buffer =
3320 SAFE_ALLOCA (sizeof fmt + SBYTES (SYMBOL_NAME (shadowed_by)));
3321 esprintf (buffer, fmt, SDATA (SYMBOL_NAME (shadowed_by)));
3322 insert_string (buffer);
3323 SAFE_FREE();
3324 }
3325 else
3326 insert_string (" (currently shadowed)");
3327 SET_PT (PT + 1);
3328 }
3329 }
3330
3331 if (CHAR_TABLE_P (vector) && ! NILP (XCHAR_TABLE (vector)->defalt))
3332 {
3333 if (!NILP (elt_prefix))
3334 insert1 (elt_prefix);
3335 insert ("default", 7);
3336 (*elt_describer) (XCHAR_TABLE (vector)->defalt, args);
3337 }
3338 }
3339
3340 void
3341 syms_of_keymap (void)
3342 {
3343 DEFSYM (Qkeymap, "keymap");
3344 DEFSYM (Qdescribe_map_tree, "describe-map-tree");
3345
3346 DEFSYM (Qkeymap_canonicalize, "keymap-canonicalize");
3347
3348
3349
3350 Fput (Qkeymap, Qchar_table_extra_slots, make_fixnum (0));
3351
3352
3353
3354
3355
3356 current_global_map = Qnil;
3357 staticpro (¤t_global_map);
3358
3359 exclude_keys = pure_list
3360 (pure_cons (build_pure_c_string ("DEL"), build_pure_c_string ("\\d")),
3361 pure_cons (build_pure_c_string ("TAB"), build_pure_c_string ("\\t")),
3362 pure_cons (build_pure_c_string ("RET"), build_pure_c_string ("\\r")),
3363 pure_cons (build_pure_c_string ("ESC"), build_pure_c_string ("\\e")),
3364 pure_cons (build_pure_c_string ("SPC"), build_pure_c_string (" ")));
3365 staticpro (&exclude_keys);
3366
3367 DEFVAR_LISP ("minibuffer-local-map", Vminibuffer_local_map,
3368 doc: );
3369 Vminibuffer_local_map = Fmake_sparse_keymap (Qnil);
3370
3371 DEFVAR_LISP ("minor-mode-map-alist", Vminor_mode_map_alist,
3372 doc:
3373
3374
3375
3376 );
3377 Vminor_mode_map_alist = Qnil;
3378
3379 DEFVAR_LISP ("minor-mode-overriding-map-alist", Vminor_mode_overriding_map_alist,
3380 doc:
3381
3382
3383 );
3384 Vminor_mode_overriding_map_alist = Qnil;
3385
3386 DEFVAR_LISP ("emulation-mode-map-alists", Vemulation_mode_map_alists,
3387 doc:
3388
3389
3390
3391
3392 );
3393 Vemulation_mode_map_alists = Qnil;
3394
3395 DEFVAR_LISP ("where-is-preferred-modifier", Vwhere_is_preferred_modifier,
3396 doc:
3397
3398
3399
3400 );
3401 Vwhere_is_preferred_modifier = Qnil;
3402 where_is_preferred_modifier = 0;
3403
3404 DEFVAR_LISP ("describe-bindings-check-shadowing-in-ranges",
3405 Vdescribe_bindings_check_shadowing_in_ranges,
3406 doc:
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416 );
3417 Vdescribe_bindings_check_shadowing_in_ranges = Qnil;
3418
3419 DEFSYM (Qself_insert_command, "self-insert-command");
3420 DEFSYM (Qignore_self_insert, "ignore-self-insert");
3421
3422 DEFSYM (Qmenu_bar, "menu-bar");
3423 DEFSYM (Qmode_line, "mode-line");
3424
3425 staticpro (&Vmouse_events);
3426 Vmouse_events = pure_list (Qmenu_bar, Qtab_bar, Qtool_bar,
3427 Qtab_line, Qheader_line, Qmode_line,
3428 intern_c_string ("mouse-1"),
3429 intern_c_string ("mouse-2"),
3430 intern_c_string ("mouse-3"),
3431 intern_c_string ("mouse-4"),
3432 intern_c_string ("mouse-5"));
3433
3434
3435
3436 DEFSYM (Qkeymapp, "keymapp");
3437 DEFSYM (Qnon_ascii, "non-ascii");
3438 DEFSYM (Qmenu_item, "menu-item");
3439 DEFSYM (Qremap, "remap");
3440 DEFSYM (QCadvertised_binding, ":advertised-binding");
3441
3442 command_remapping_vector = make_vector (2, Qremap);
3443 staticpro (&command_remapping_vector);
3444
3445 where_is_cache_keymaps = Qt;
3446 where_is_cache = Qnil;
3447 staticpro (&where_is_cache);
3448 staticpro (&where_is_cache_keymaps);
3449
3450 DEFSYM (Qfont_lock_face, "font-lock-face");
3451 DEFSYM (Qhelp_key_binding, "help-key-binding");
3452 staticpro (&fontify_key_properties);
3453 fontify_key_properties = Fcons (Qfont_lock_face,
3454 Fcons (Qhelp_key_binding, Qnil));
3455
3456 defsubr (&Skeymapp);
3457 defsubr (&Skeymap_parent);
3458 defsubr (&Skeymap_prompt);
3459 defsubr (&Sset_keymap_parent);
3460 defsubr (&Smake_keymap);
3461 defsubr (&Smake_sparse_keymap);
3462 defsubr (&Smap_keymap_internal);
3463 defsubr (&Smap_keymap);
3464 defsubr (&Scopy_keymap);
3465 defsubr (&Scommand_remapping);
3466 defsubr (&Skey_binding);
3467 defsubr (&Sminor_mode_key_binding);
3468 defsubr (&Sdefine_key);
3469 defsubr (&Slookup_key);
3470 defsubr (&Suse_global_map);
3471 defsubr (&Suse_local_map);
3472 defsubr (&Scurrent_local_map);
3473 defsubr (&Scurrent_global_map);
3474 defsubr (&Scurrent_minor_mode_maps);
3475 defsubr (&Scurrent_active_maps);
3476 defsubr (&Saccessible_keymaps);
3477 defsubr (&Skey_description);
3478 defsubr (&Skeymap__get_keyelt);
3479 defsubr (&Shelp__describe_vector);
3480 defsubr (&Sdescribe_vector);
3481 defsubr (&Ssingle_key_description);
3482 defsubr (&Stext_char_description);
3483 defsubr (&Swhere_is_internal);
3484 defsubr (&Sdescribe_buffer_bindings);
3485
3486 DEFSYM (Qkey_parse, "key-parse");
3487 DEFSYM (Qkey_valid_p, "key-valid-p");
3488
3489 DEFSYM (Qnon_key_event, "non-key-event");
3490 }