1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include <config.h>
25: #include <stdio.h>
26: #if HAVE_ALLOCA_H
27: # include <alloca.h>
28: #endif
29: #include "lisp.h"
30: #include "commands.h"
31: #include "buffer.h"
32: #include "charset.h"
33: #include "keyboard.h"
34: #include "termhooks.h"
35: #include "blockinput.h"
36: #include "puresize.h"
37: #include "intervals.h"
38: #include "keymap.h"
39: #include "window.h"
40:
41:
42: #define DENSE_TABLE_SIZE (0200)
43:
44:
45:
46: Lisp_Object current_global_map;
47:
48: Lisp_Object global_map;
49:
50: Lisp_Object meta_map;
51:
52:
53: Lisp_Object control_x_map;
54:
55:
56:
57: Lisp_Object Vminibuffer_local_map;
58:
59:
60:
61:
62:
63: Lisp_Object Vminibuffer_local_ns_map;
64:
65:
66:
67:
68:
69:
70: Lisp_Object Vminibuffer_local_completion_map;
71:
72:
73: Lisp_Object Vminibuffer_local_filename_completion_map;
74:
75:
76:
77: Lisp_Object Vminibuffer_local_must_match_filename_map;
78:
79:
80:
81: Lisp_Object Vminibuffer_local_must_match_map;
82:
83:
84: Lisp_Object Vminor_mode_map_alist;
85:
86:
87:
88: Lisp_Object Vminor_mode_overriding_map_alist;
89:
90:
91: Lisp_Object Vemulation_mode_map_alists;
92:
93:
94:
95:
96: Lisp_Object Vfunction_key_map;
97:
98:
99: Lisp_Object Vkey_translation_map;
100:
101:
102:
103:
104:
105: Lisp_Object Vdefine_key_rebound_commands;
106:
107: Lisp_Object Qkeymapp, Qkeymap, Qnon_ascii, Qmenu_item, Qremap;
108:
109:
110: static Lisp_Object exclude_keys;
111:
112:
113: static Lisp_Object command_remapping_vector;
114:
115:
116:
117:
118: extern Lisp_Object meta_prefix_char;
119:
120: extern Lisp_Object Voverriding_local_map;
121:
122:
123: static Lisp_Object where_is_cache;
124:
125: static Lisp_Object where_is_cache_keymaps;
126:
127: static Lisp_Object store_in_keymap P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
128: static void fix_submap_inheritance P_ ((Lisp_Object, Lisp_Object, Lisp_Object));
129:
130: static Lisp_Object define_as_prefix P_ ((Lisp_Object, Lisp_Object));
131: static void describe_command P_ ((Lisp_Object, Lisp_Object));
132: static void describe_translation P_ ((Lisp_Object, Lisp_Object));
133: static void describe_map P_ ((Lisp_Object, Lisp_Object,
134: void (*) P_ ((Lisp_Object, Lisp_Object)),
135: int, Lisp_Object, Lisp_Object*, int, int));
136: static void describe_vector P_ ((Lisp_Object, Lisp_Object, Lisp_Object,
137: void (*) (Lisp_Object, Lisp_Object), int,
138: Lisp_Object, Lisp_Object, int *,
139: int, int, int));
140: static void silly_event_symbol_error P_ ((Lisp_Object));
141: ^L
142:
143:
144: DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 1, 0,
145: doc:
146:
147:
148:
149:
150:
151:
152:
153: )
154: (string)
155: Lisp_Object string;
156: {
157: Lisp_Object tail;
158: if (!NILP (string))
159: tail = Fcons (string, Qnil);
160: else
161: tail = Qnil;
162: return Fcons (Qkeymap,
163: Fcons (Fmake_char_table (Qkeymap, Qnil), tail));
164: }
165:
166: DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 1, 0,
167: doc:
168:
169:
170:
171:
172:
173:
174: )
175: (string)
176: Lisp_Object string;
177: {
178: if (!NILP (string))
179: return Fcons (Qkeymap, Fcons (string, Qnil));
180: return Fcons (Qkeymap, Qnil);
181: }
182:
183:
184:
185:
186:
187:
188:
189:
190: void
191: initial_define_key (keymap, key, defname)
192: Lisp_Object keymap;
193: int key;
194: char *defname;
195: {
196: store_in_keymap (keymap, make_number (key), intern (defname));
197: }
198:
199: void
200: initial_define_lispy_key (keymap, keyname, defname)
201: Lisp_Object keymap;
202: char *keyname;
203: char *defname;
204: {
205: store_in_keymap (keymap, intern (keyname), intern (defname));
206: }
207:
208: DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
209: doc:
210:
211:
212:
213:
214:
215: )
216: (object)
217: Lisp_Object object;
218: {
219: return (KEYMAPP (object) ? Qt : Qnil);
220: }
221:
222: DEFUN ("keymap-prompt", Fkeymap_prompt, Skeymap_prompt, 1, 1, 0,
223: doc:
224:
225: )
226: (map)
227: Lisp_Object map;
228: {
229: map = get_keymap (map, 0, 0);
230: while (CONSP (map))
231: {
232: Lisp_Object tem = XCAR (map);
233: if (STRINGP (tem))
234: return tem;
235: map = XCDR (map);
236: }
237: return Qnil;
238: }
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262: Lisp_Object
263: get_keymap (object, error, autoload)
264: Lisp_Object object;
265: int error, autoload;
266: {
267: Lisp_Object tem;
268:
269: autoload_retry:
270: if (NILP (object))
271: goto end;
272: if (CONSP (object) && EQ (XCAR (object), Qkeymap))
273: return object;
274:
275: tem = indirect_function (object);
276: if (CONSP (tem))
277: {
278: if (EQ (XCAR (tem), Qkeymap))
279: return tem;
280:
281:
282:
283: if ((autoload || !error) && EQ (XCAR (tem), Qautoload)
284: && SYMBOLP (object))
285: {
286: Lisp_Object tail;
287:
288: tail = Fnth (make_number (4), tem);
289: if (EQ (tail, Qkeymap))
290: {
291: if (autoload)
292: {
293: struct gcpro gcpro1, gcpro2;
294:
295: GCPRO2 (tem, object);
296: do_autoload (tem, object);
297: UNGCPRO;
298:
299: goto autoload_retry;
300: }
301: else
302: return Qt;
303: }
304: }
305: }
306:
307: end:
308: if (error)
309: wrong_type_argument (Qkeymapp, object);
310: return Qnil;
311: }
312: ^L
313:
314:
315:
316: Lisp_Object
317: keymap_parent (keymap, autoload)
318: Lisp_Object keymap;
319: int autoload;
320: {
321: Lisp_Object list;
322:
323: keymap = get_keymap (keymap, 1, autoload);
324:
325:
326: list = XCDR (keymap);
327: for (; CONSP (list); list = XCDR (list))
328: {
329:
330: if (KEYMAPP (list))
331: return list;
332: }
333:
334: return get_keymap (list, 0, autoload);
335: }
336:
337: DEFUN ("keymap-parent", Fkeymap_parent, Skeymap_parent, 1, 1, 0,
338: doc: )
339: (keymap)
340: Lisp_Object keymap;
341: {
342: return keymap_parent (keymap, 1);
343: }
344:
345:
346: int
347: keymap_memberp (map, maps)
348: Lisp_Object map, maps;
349: {
350: if (NILP (map)) return 0;
351: while (KEYMAPP (maps) && !EQ (map, maps))
352: maps = keymap_parent (maps, 0);
353: return (EQ (map, maps));
354: }
355:
356:
357:
358: DEFUN ("set-keymap-parent", Fset_keymap_parent, Sset_keymap_parent, 2, 2, 0,
359: doc:
360: )
361: (keymap, parent)
362: Lisp_Object keymap, parent;
363: {
364: Lisp_Object list, prev;
365: struct gcpro gcpro1, gcpro2;
366: int i;
367:
368:
369:
370:
371:
372:
373:
374:
375: where_is_cache_keymaps = Qt;
376:
377: GCPRO2 (keymap, parent);
378: keymap = get_keymap (keymap, 1, 1);
379:
380: if (!NILP (parent))
381: {
382: parent = get_keymap (parent, 1, 1);
383:
384:
385: if (keymap_memberp (keymap, parent))
386: error ("Cyclic keymap inheritance");
387: }
388:
389:
390: prev = keymap;
391: while (1)
392: {
393: list = XCDR (prev);
394:
395:
396: if (!CONSP (list) || KEYMAPP (list))
397: {
398:
399:
400: if (EQ (XCDR (prev), parent))
401: RETURN_UNGCPRO (parent);
402:
403: CHECK_IMPURE (prev);
404: XSETCDR (prev, parent);
405: break;
406: }
407: prev = list;
408: }
409:
410:
411:
412: for (list = XCDR (keymap); CONSP (list); list = XCDR (list))
413: {
414:
415: if (EQ (XCAR (list), Qkeymap))
416: break;
417:
418:
419: if (CONSP (XCAR (list))
420: && CONSP (XCDR (XCAR (list))))
421: fix_submap_inheritance (keymap, XCAR (XCAR (list)),
422: XCDR (XCAR (list)));
423:
424: if (VECTORP (XCAR (list)))
425: for (i = 0; i < XVECTOR (XCAR (list))->size; i++)
426: if (CONSP (XVECTOR (XCAR (list))->contents[i]))
427: fix_submap_inheritance (keymap, make_number (i),
428: XVECTOR (XCAR (list))->contents[i]);
429:
430: if (CHAR_TABLE_P (XCAR (list)))
431: {
432: Lisp_Object indices[3];
433:
434: map_char_table (fix_submap_inheritance, Qnil,
435: XCAR (list), XCAR (list),
436: keymap, 0, indices);
437: }
438: }
439:
440: RETURN_UNGCPRO (parent);
441: }
442:
443:
444:
445:
446:
447: static void
448: fix_submap_inheritance (map, event, submap)
449: Lisp_Object map, event, submap;
450: {
451: Lisp_Object map_parent, parent_entry;
452:
453:
454:
455:
456: submap = get_keymap (get_keyelt (submap, 0), 0, 0);
457:
458:
459: if (!CONSP (submap))
460: return;
461:
462: map_parent = keymap_parent (map, 0);
463: if (!NILP (map_parent))
464: parent_entry =
465: get_keymap (access_keymap (map_parent, event, 0, 0, 0), 0, 0);
466: else
467: parent_entry = Qnil;
468:
469:
470:
471: if (!CONSP (parent_entry))
472: return;
473:
474: if (! EQ (parent_entry, submap))
475: {
476: Lisp_Object submap_parent;
477: submap_parent = submap;
478: while (1)
479: {
480: Lisp_Object tem;
481:
482: tem = keymap_parent (submap_parent, 0);
483:
484: if (KEYMAPP (tem))
485: {
486: if (keymap_memberp (tem, parent_entry))
487:
488: return;
489: submap_parent = tem;
490: }
491: else
492: break;
493: }
494: Fset_keymap_parent (submap_parent, parent_entry);
495: }
496: }
497: ^L
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510: Lisp_Object
511: access_keymap (map, idx, t_ok, noinherit, autoload)
512: Lisp_Object map;
513: Lisp_Object idx;
514: int t_ok;
515: int noinherit;
516: int autoload;
517: {
518: Lisp_Object val;
519:
520:
521: val = Qunbound;
522:
523:
524:
525:
526: idx = EVENT_HEAD (idx);
527:
528:
529:
530: if (SYMBOLP (idx))
531: idx = reorder_modifiers (idx);
532: else if (INTEGERP (idx))
533:
534:
535: XSETFASTINT (idx, XINT (idx) & (CHAR_META | (CHAR_META - 1)));
536:
537:
538: if (INTEGERP (idx) && XUINT (idx) & meta_modifier)
539: {
540:
541:
542: struct gcpro gcpro1;
543: Lisp_Object meta_map;
544: GCPRO1 (map);
545:
546:
547: if (XINT (meta_prefix_char) & CHAR_META)
548: meta_prefix_char = make_number (27);
549: meta_map = get_keymap (access_keymap (map, meta_prefix_char,
550: t_ok, noinherit, autoload),
551: 0, autoload);
552: UNGCPRO;
553: if (CONSP (meta_map))
554: {
555: map = meta_map;
556: idx = make_number (XUINT (idx) & ~meta_modifier);
557: }
558: else if (t_ok)
559:
560: idx = Qt;
561: else
562:
563: return Qnil;
564: }
565:
566:
567:
568:
569: {
570: Lisp_Object tail;
571: Lisp_Object t_binding = Qnil;
572: struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
573:
574: GCPRO4 (map, tail, idx, t_binding);
575:
576:
577:
578:
579: t_ok = t_ok ? 2 : 0;
580:
581: for (tail = XCDR (map);
582: (CONSP (tail)
583: || (tail = get_keymap (tail, 0, autoload), CONSP (tail)));
584: tail = XCDR (tail))
585: {
586: Lisp_Object binding;
587:
588: binding = XCAR (tail);
589: if (SYMBOLP (binding))
590: {
591:
592:
593: if (noinherit && EQ (binding, Qkeymap))
594: RETURN_UNGCPRO (Qnil);
595: }
596: else if (CONSP (binding))
597: {
598: Lisp_Object key = XCAR (binding);
599:
600: if (EQ (key, idx))
601: val = XCDR (binding);
602: else if (t_ok
603: && INTEGERP (idx)
604: && (XINT (idx) & CHAR_MODIFIER_MASK) == 0
605: && INTEGERP (key)
606: && (XINT (key) & CHAR_MODIFIER_MASK) == 0
607: && !SINGLE_BYTE_CHAR_P (XINT (idx))
608: && !SINGLE_BYTE_CHAR_P (XINT (key))
609: && CHAR_VALID_P (XINT (key), 1)
610: && !CHAR_VALID_P (XINT (key), 0)
611: && (CHAR_CHARSET (XINT (key))
612: == CHAR_CHARSET (XINT (idx))))
61