|
|
1.1 root 1: /* Manipulation of keymaps
2: Copyright (C) 1985 Richard M. Stallman.
3:
4: This file is part of GNU Emacs.
5:
6: GNU Emacs is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU Emacs General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU Emacs, but only under the conditions described in the
15: GNU Emacs General Public License. A copy of this license is
16: supposed to have been given to you along with GNU Emacs so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: #include "config.h"
23: #include <stdio.h>
24: #undef NULL
25: #include "lisp.h"
26: #include "commands.h"
27: #include "buffer.h"
28:
29: /* Actually allocate storage for these variables */
30:
31: #ifdef HAVE_X_WINDOWS
32: struct Lisp_Vector *MouseMap; /* Keymap for mouse commands */
33: #endif /* HAVE_X_WINDOWS */
34:
35: struct Lisp_Vector *CurrentGlobalMap; /* Current global keymap */
36:
37: struct Lisp_Vector *GlobalMap; /* default global key bindings */
38:
39: struct Lisp_Vector *ESCmap; /* The keymap used for globally
40: bound ESC-prefixed default
41: commands */
42:
43: struct Lisp_Vector *CtlXmap; /* The keymap used for globally
44: bound C-x-prefixed default
45: commands */
46:
47: /* was MinibufLocalMap */
48: Lisp_Object Vminibuffer_local_map;
49: /* The keymap used by the minibuf for local
50: bindings when spaces are allowed in the
51: minibuf */
52:
53: /* was MinibufLocalNSMap */
54: Lisp_Object Vminibuffer_local_ns_map;
55: /* The keymap used by the minibuf for local
56: bindings when spaces are not encouraged
57: in the minibuf */
58:
59: /* keymap used for minibuffers when doing completion */
60: /* was MinibufLocalCompletionMap */
61: Lisp_Object Vminibuffer_local_completion_map;
62:
63: /* keymap used for minibuffers when doing completion and require a match */
64: /* was MinibufLocalMustMatchMap */
65: Lisp_Object Vminibuffer_local_must_match_map;
66:
67: Lisp_Object Qkeymapp, Qkeymap;
68:
69: DEFUN ("make-keymap", Fmake_keymap, Smake_keymap, 0, 0, 0,
70: "Construct and return a new keymap, a vector of length 128.\n\
71: All entries in it are nil, meaning \"command undefined\".")
72: ()
73: {
74: Lisp_Object val;
75: XFASTINT (val) = 0200;
76: return Fmake_vector (val, Qnil);
77: }
78:
79: DEFUN ("make-sparse-keymap", Fmake_sparse_keymap, Smake_sparse_keymap, 0, 0, 0,
80: "Construct and return a new sparse-keymap list.\n\
81: Its car is 'keymap and its cdr is an alist of (CHAR . DEFINITION).\n\
82: Initially the alist is nil.")
83: ()
84: {
85: return Fcons (Qkeymap, Qnil);
86: }
87:
88: /* This is used for installing the standard key bindings at initialization time.
89: For example, defkey (CtlXmap, Ctl('X'), "exchange-point-and-mark"); */
90:
91: void
92: defkey (keymap, key, defname)
93: struct Lisp_Vector *keymap;
94: int key;
95: char *defname;
96: {
97: keymap->contents[key] = intern (defname);
98: }
99:
100: void
101: ndefkey (keymap, key, defname)
102: Lisp_Object keymap;
103: int key;
104: char *defname;
105: {
106: store_in_keymap (keymap, key, intern (defname));
107: }
108:
109: /* Define character fromchar in map frommap as an alias for character tochar in map tomap.
110: Subsequent redefinitions of the latter WILL affect the former. */
111:
112: #ifdef NOTDEF
113: void
114: synkey (frommap, fromchar, tomap, tochar)
115: struct Lisp_Vector *frommap, *tomap;
116: int fromchar, tochar;
117: {
118: Lisp_Object v, c;
119: XSET (v, Lisp_Vector, tomap);
120: XFASTINT (c) = tochar;
121: frommap->contents[fromchar] = Fcons (v, c);
122: }
123: #endif /* NOTDEF */
124:
125: DEFUN ("keymapp", Fkeymapp, Skeymapp, 1, 1, 0,
126: "Return t if ARG is a keymap.\n\
127: A keymap is a vector of length 128, or a list (keymap . ALIST),\n\
128: where alist elements look like (CHAR . DEFN).")
129: (object)
130: Lisp_Object object;
131: {
132: Lisp_Object tem;
133: tem = object;
134: while (XTYPE (tem) == Lisp_Symbol)
135: {
136: tem = XSYMBOL (tem)->function;
137: if (EQ (tem, Qunbound))
138: return Qnil;
139: }
140:
141: if ((XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == 0200)
142: || (LISTP (tem) && EQ (XCONS (tem)->car, Qkeymap)))
143: return Qt;
144: return Qnil;
145: }
146:
147: Lisp_Object
148: get_keymap (object, argnumber)
149: Lisp_Object object;
150: int argnumber;
151: {
152: Lisp_Object tem;
153:
154: while (1)
155: {
156: tem = object;
157: while (XTYPE (tem) == Lisp_Symbol && !EQ (tem, Qunbound))
158: tem = XSYMBOL (tem)->function;
159:
160: if ((XTYPE (tem) == Lisp_Vector && XVECTOR (tem)->size == 0200)
161: || (LISTP (tem) && EQ (XCONS (tem)->car, Qkeymap)))
162: return tem;
163: if (argnumber >= 0)
164: object = wrong_type_argument (Qkeymapp, object);
165: else return Qnil;
166: }
167: }
168:
169: Lisp_Object
170: get_keyelt (object)
171: Lisp_Object object;
172: {
173: Lisp_Object map, tem;
174:
175: while (map = get_keymap (Fcar_safe (object), -1),
176: tem = Fkeymapp (map),
177: !NULL (tem))
178: /*(XTYPE (object) == Lisp_Cons && !EQ (XCONS (object)->car, Qkeymap))*/
179: {
180: object = Fcdr (object);
181: if (LISTP (map))
182: object = Fcdr (Fassq (object, Fcdr (map)));
183: else
184: object = Faref (map, object);
185: }
186: return object;
187: }
188:
189: Lisp_Object
190: access_keymap (map, idx)
191: Lisp_Object map;
192: register int idx;
193: {
194: register Lisp_Object val;
195: if (idx < 0 || idx >= 0200)
196: error ("Command key out of range 0-127");
197:
198: /* Get definition for character `idx' proper. */
199: if (LISTP (map))
200: val = Fcdr (Fassq (make_number (idx), Fcdr (map)));
201: else
202: val = XVECTOR (map)->contents[idx];
203:
204: /* If nothing there, and `idx' is upper case,
205: look under corresponding lower case character. */
206:
207: if (NULL (val) && idx >= 'A' && idx <= 'Z')
208: {
209: if (LISTP (map))
210: val = Fcdr (Fassq (make_number (idx + 'a' - 'A'), Fcdr (map)));
211: else
212: val = XVECTOR (map)->contents[idx + 'a' - 'A'];
213: }
214: return val;
215: }
216:
217: Lisp_Object
218: store_in_keymap (keymap, idx, def)
219: Lisp_Object keymap;
220: int idx;
221: Lisp_Object def;
222: {
223: Lisp_Object tem;
224:
225: if (idx < 0 || idx >= 0200)
226: error ("Command key out of range 0-127");
227:
228: if (LISTP (keymap))
229: {
230: tem = Fassq (make_number (idx), Fcdr (keymap));
231: if (!NULL (tem))
232: Fsetcdr (tem, def);
233: else
234: Fsetcdr (keymap, Fcons (Fcons (make_number (idx), def),
235: Fcdr (keymap)));
236: }
237: else
238: XVECTOR (keymap)->contents[idx] = def;
239:
240: return def;
241: }
242:
243: DEFUN ("define-key", Fdefine_key, Sdefine_key, 3, 3, 0,
244: "Args KEYMAP, KEYS, DEF. Define key sequence KEYS, in KEYMAP, as DEF.\n\
245: KEYMAP is a keymap. KEYS is a string meaning a sequence of keystrokes.\n\
246: DEF is usually a symbol with a function definition, suitable for use as a command.")
247: (keymap, keys, def)
248: Lisp_Object keymap;
249: Lisp_Object keys;
250: Lisp_Object def;
251: {
252: unsigned char *p;
253: int level;
254: Lisp_Object tem;
255: Lisp_Object cmd;
256:
257: keymap = get_keymap (keymap, 0);
258:
259: CHECK_STRING (keys, 1);
260: p = XSTRING (keys)->data;
261: level = XSTRING (keys)->size;
262:
263: while (1)
264: {
265: level--;
266:
267: if (!level)
268: return store_in_keymap (keymap, *p, def);
269:
270: cmd = get_keyelt (access_keymap (keymap, *p));
271: if (NULL (cmd))
272: {
273: cmd = Fmake_sparse_keymap ();
274: store_in_keymap (keymap, *p, cmd);
275: }
276: tem = Fkeymapp (cmd);
277: if (NULL (tem))
278: error ("Key sequence %s uses invalid prefix characters",
279: XSTRING (keys)->data);
280:
281: keymap = get_keymap (cmd, 0);
282: p++;
283: }
284: }
285:
286: /* Value is T if `keys' is too long; NIL if valid but has no definition. */
287:
288: DEFUN ("lookup-key", Flookup_key, Slookup_key, 2, 2, 0,
289: "In keymap KEYMAP, look up key sequence KEYS. Return the definition.\n\
290: nil means undefined.\n\
291: Number as value means KEYS is \"too long\";\n\
292: that is, characters in it except for the last one\n\
293: fail to be a valid sequence of prefix characters in KEYMAP.\n\
294: The number is how many characters at the front of KEYS\n\
295: it takes to reach a non-prefix command.")
296: (keymap, keys)
297: Lisp_Object keymap;
298: Lisp_Object keys;
299: {
300: unsigned char *p;
301: int level;
302: Lisp_Object tem;
303: Lisp_Object cmd;
304:
305: keymap = get_keymap (keymap, 0);
306:
307: CHECK_STRING (keys, 1);
308: p = XSTRING (keys)->data;
309: level = XSTRING (keys)->size;
310:
311: while (1)
312: {
313: level--;
314: cmd = get_keyelt (access_keymap (keymap, *p++));
315: if (!level)
316: return cmd;
317:
318: tem = Fkeymapp (cmd);
319: if (NULL (tem))
320: return make_number (XSTRING (keys)->size - level);
321:
322: keymap = get_keymap (cmd, 0);
323: }
324: }
325:
326: DEFUN ("key-binding", Fkey_binding, Skey_binding, 1, 1, 0,
327: "Return the definition for command KEYS in current keymaps.\n\
328: KEYS is a string, a sequence of keystrokes.\n\
329: The definition is probably a symbol with a function definition.")
330: (keys)
331: Lisp_Object keys;
332: {
333: Lisp_Object map, value, value1;
334: map = bf_cur->keymap;
335: if (!NULL (map))
336: {
337: value = Flookup_key (map, keys);
338: if (NULL (value))
339: {
340: XSET (map, Lisp_Vector, CurrentGlobalMap);
341: value1 = Flookup_key (map, keys);
342: if (XTYPE (value1) == Lisp_Int)
343: return Qnil;
344: return value1;
345: }
346: else if (XTYPE (value) != Lisp_Int)
347: return value;
348: }
349: XSET (map, Lisp_Vector, CurrentGlobalMap);
350: return Flookup_key (map, keys);
351: }
352:
353: DEFUN ("local-key-binding", Flocal_key_binding, Slocal_key_binding, 1, 1, 0,
354: "Return the definition for command KEYS in current local keymap only.\n\
355: KEYS is a string, a sequence of keystrokes.\n\
356: The definition is probably a symbol with a function definition.")
357: (keys)
358: Lisp_Object keys;
359: {
360: Lisp_Object map;
361: map = bf_cur->keymap;
362: if (NULL (map))
363: return Qnil;
364: return Flookup_key (map, keys);
365: }
366:
367: DEFUN ("global-key-binding", Fglobal_key_binding, Sglobal_key_binding, 1, 1, 0,
368: "Return the definition for command KEYS in current global keymap only.\n\
369: KEYS is a string, a sequence of keystrokes.\n\
370: The definition is probably a symbol with a function definition.")
371: (keys)
372: Lisp_Object keys;
373: {
374: Lisp_Object map;
375: XSET (map, Lisp_Vector, CurrentGlobalMap);
376: return Flookup_key (map, keys);
377: }
378:
379: DEFUN ("global-set-key", Fglobal_set_key, Sglobal_set_key, 2, 2,
380: "kSet key globally: \nCSet key %s to command: ",
381: "Give KEY a definition of COMMAND.\n\
382: COMMAND is a symbol naming an interactively-callable function.\n\
383: KEY is a string representing a sequence of keystrokes.\n\
384: Note that if KEY has a local definition in the current buffer\n\
385: that local definition will continue to shadow any global definition.")
386: (keys, function)
387: Lisp_Object keys, function;
388: {
389: Lisp_Object map;
390: XSET (map, Lisp_Vector, CurrentGlobalMap);
391: CHECK_STRING (keys, 1);
392: Fdefine_key (map, keys, function);
393: return Qnil;
394: }
395:
396: DEFUN ("local-set-key", Flocal_set_key, Slocal_set_key, 2, 2,
397: "kSet key locally: \nCSet key %s locally to command: ",
398: "Give KEY a local definition of COMMAND.\n\
399: COMMAND is a symbol naming an interactively-callable function.\n\
400: KEY is a string representing a sequence of keystrokes.\n\
401: The definition goes in the current buffer's local map,\n\
402: which is shared with other buffers in the same major mode.")
403: (keys, function)
404: Lisp_Object keys, function;
405: {
406: Lisp_Object map;
407: map = bf_cur->keymap;
408: if (NULL (map))
409: {
410: map = Fmake_sparse_keymap ();
411: bf_cur->keymap = map;
412: }
413:
414: CHECK_STRING (keys, 1);
415: Fdefine_key (map, keys, function);
416: return Qnil;
417: }
418:
419: DEFUN ("global-unset-key", Fglobal_unset_key, Sglobal_unset_key,
420: 1, 1, "kUnset key globally: ",
421: "Remove global definition of KEY.\n\
422: KEY is a string representing a sequence of keystrokes.")
423: (keys)
424: Lisp_Object keys;
425: {
426: return Fglobal_set_key (keys, Qnil);
427: }
428:
429: DEFUN ("local-unset-key", Flocal_unset_key, Slocal_unset_key, 1, 1,
430: "kUnset key locally: ",
431: "Remove local definition of KEY.\n\
432: KEY is a string representing a sequence of keystrokes.")
433: (keys)
434: Lisp_Object keys;
435: {
436: if (!NULL (bf_cur->keymap))
437: Flocal_set_key (keys, Qnil);
438: return Qnil;
439: }
440:
441: DEFUN ("define-prefix-command", Fdefine_prefix_command, Sdefine_prefix_command, 1, 1, 0,
442: "Define SYMBOL as a prefix command.\n\
443: A keymap is created and stored as SYMBOL's function definition.")
444: (name)
445: Lisp_Object name;
446: {
447: Fset (name, Fmake_keymap ());
448: return name;
449: }
450:
451: DEFUN ("use-global-map", Fuse_global_map, Suse_global_map, 1, 1, 0,
452: "Selects KEYMAP as the global keymap.")
453: (keymap)
454: Lisp_Object keymap;
455: {
456: keymap = get_keymap (keymap, 0);
457: CHECK_VECTOR (keymap, 0);
458: CurrentGlobalMap = XVECTOR (keymap);
459: return Qnil;
460: }
461:
462: DEFUN ("use-local-map", Fuse_local_map, Suse_local_map, 1, 1, 0,
463: "Selects KEYMAP as the local keymap.\n\
464: nil for KEYMAP means no local keymap.")
465: (keymap)
466: Lisp_Object keymap;
467: {
468: if (!NULL (keymap))
469: keymap = get_keymap (keymap, 0);
470:
471: bf_cur->keymap = keymap;
472:
473: return Qnil;
474: }
475:
476: DEFUN ("current-local-map", Fcurrent_local_map, Scurrent_local_map, 0, 0, 0,
477: "Return current buffer's local keymap, or nil if it has none.")
478: ()
479: {
480: return bf_cur->keymap;
481: }
482:
483: DEFUN ("accessible-keymaps", Faccessible_keymaps, Saccessible_keymaps,
484: 1, 1, 0,
485: "Find all keymaps accessible via prefix characters from KEYMAP.\n\
486: Returns a list of elements of the form (KEYS . MAP), where the sequence\n\
487: KEYS starting from KEYMAP gets you to MAP. These elements are ordered\n\
488: so that the KEYS increase in length. The first element is (\"\" . KEYMAP).")
489: (startmap)
490: Lisp_Object startmap;
491: {
492: Lisp_Object maps, tail;
493: Lisp_Object thismap, thisseq;
494: Lisp_Object dummy;
495: Lisp_Object tem;
496: Lisp_Object cmd;
497: int i;
498:
499: maps = Fcons (Fcons (build_string (""), get_keymap (startmap, 0)), Qnil);
500: tail = maps;
501:
502: /* For each map in the list maps,
503: look at any other maps it points to
504: and stick them at the end if they are not already in the list */
505:
506: while (!NULL (tail))
507: {
508: thisseq = Fcar (Fcar (tail));
509: thismap = Fcdr (Fcar (tail));
510: for (i = 0; i < 0200; i++)
511: {
512: cmd = get_keyelt (access_keymap (thismap, i));
513: if (NULL (cmd)) continue;
514: tem = Fkeymapp (cmd);
515: if (!NULL (tem))
516: {
517: cmd = get_keymap (cmd, 0);
518: tem = Frassq (cmd, maps);
519: if (NULL (tem)) {
520: XFASTINT (dummy) = i;
521: dummy = concat2 (thisseq, Fchar_to_string (dummy));
522: nconc2 (tail, Fcons (Fcons (dummy, cmd), Qnil));
523: }
524: }
525: }
526: tail = Fcdr (tail);
527: }
528:
529: return maps;
530: }
531:
532: Lisp_Object Qsingle_key_description, Qkey_description;
533:
534: DEFUN ("key-description", Fkey_description, Skey_description, 1, 1, 0,
535: "Return a pretty description of key-sequence KEYS.\n\
536: Control characters turn into \"C-foo\" sequences, meta into \"M-foo\"\n\
537: spaces are put between sequence elements, etc.")
538: (keys)
539: Lisp_Object keys;
540: {
541: return Fmapconcat (Qsingle_key_description, keys, build_string (" "));
542: }
543:
544: char *
545: push_key_description (c, p)
546: register unsigned int c;
547: register char *p;
548: {
549: if (c >= 0200)
550: {
551: *p++ = 'M';
552: *p++ = '-';
553: c -= 0200;
554: }
555: if (c < 040)
556: {
557: if (c == 033)
558: {
559: *p++ = 'E';
560: *p++ = 'S';
561: *p++ = 'C';
562: }
563: else if (c == Ctl('I'))
564: {
565: *p++ = 'T';
566: *p++ = 'A';
567: *p++ = 'B';
568: }
569: else if (c == Ctl('J'))
570: {
571: *p++ = 'L';
572: *p++ = 'F';
573: *p++ = 'D';
574: }
575: else if (c == Ctl('M'))
576: {
577: *p++ = 'R';
578: *p++ = 'E';
579: *p++ = 'T';
580: }
581: else
582: {
583: *p++ = 'C';
584: *p++ = '-';
585: if (c > 0 && c <= Ctl ('Z'))
586: *p++ = c + 0140;
587: else
588: *p++ = c + 0100;
589: }
590: }
591: else if (c == 0177)
592: {
593: *p++ = 'D';
594: *p++ = 'E';
595: *p++ = 'L';
596: }
597: else if (c == ' ')
598: {
599: *p++ = 'S';
600: *p++ = 'P';
601: *p++ = 'C';
602: }
603: else
604: *p++ = c;
605: return p;
606: }
607:
608: DEFUN ("single-key-description", Fsingle_key_description, Ssingle_key_description, 1, 1, 0,
609: "Return a pretty description of command character KEY.\n\
610: Control characters turn into C-whatever, etc.")
611: (key)
612: Lisp_Object key;
613: {
614: unsigned char c;
615: char tem[6];
616:
617: CHECK_NUMBER (key, 0);
618: c = XINT (key) & 0377;
619:
620: *push_key_description (c, tem) = 0;
621:
622: return build_string (tem);
623: }
624:
625: char *
626: push_text_char_description (c, p)
627: register unsigned int c;
628: register char *p;
629: {
630: if (c >= 0200)
631: {
632: *p++ = 'M';
633: *p++ = '-';
634: c -= 0200;
635: }
636: if (c < 040)
637: {
638: *p++ = '^';
639: *p++ = c + 64; /* 'A' - 1 */
640: }
641: else if (c == 0177)
642: {
643: *p++ = '^';
644: *p++ = '?';
645: }
646: else
647: *p++ = c;
648: return p;
649: }
650:
651: DEFUN ("text-char-description", Ftext_char_description, Stext_char_description, 1, 1, 0,
652: "Return a pretty description of file-character CHAR.\n\
653: Control characters turn into \"C-char\", etc.")
654: (chr)
655: Lisp_Object chr;
656: {
657: char tem[6];
658:
659: CHECK_NUMBER (chr, 0);
660:
661: *push_text_char_description (XINT (chr) & 0377, tem) = 0;
662:
663: return build_string (tem);
664: }
665:
666: Lisp_Object where_is_in_buffer ();
667:
668: DEFUN ("where-is-internal", Fwhere_is_internal, Swhere_is_internal, 1, 1, 0,
669: "Return list of key sequences that currently invoke command DEFINITION.")
670: (definition)
671: Lisp_Object definition;
672: {
673: return where_is_in_buffer (definition, bf_cur, 0);
674: }
675:
676: Lisp_Object
677: where_is_in_buffer (definition, buf, firstonly)
678: Lisp_Object definition;
679: struct buffer *buf;
680: int firstonly; /* if true, return after finding one */
681: {
682: Lisp_Object start1, start2;
683: Lisp_Object maps;
684: Lisp_Object this, map;
685: Lisp_Object dummy;
686: Lisp_Object found;
687: Lisp_Object tem;
688: register int i;
689:
690: XSET (start1, Lisp_Vector, CurrentGlobalMap);
691: start2 = buf->keymap;
692:
693: if (!NULL (start2))
694: maps = nconc2 (Faccessible_keymaps (start2),
695: Faccessible_keymaps (start1));
696: else
697: maps = Faccessible_keymaps (start1);
698:
699: found = Qnil;
700:
701: for (; !NULL (maps); maps = Fcdr (maps))
702: {
703: this = Fcar (Fcar (maps)); /* Key sequence to reach map */
704: map = Fcdr (Fcar (maps)); /* The map that it reaches */
705: if (LISTP (map))
706: for (map = Fcdr (map); !NULL (map); map = Fcdr (map))
707: {
708: QUIT;
709: tem = Fcdr (Fcar (map));
710: if (EQ (tem, definition))
711: {
712: dummy = Fcar (Fcar (map));
713: dummy = concat2 (this, Fchar_to_string (dummy));
714: if (firstonly)
715: return dummy;
716: found = Fcons (dummy, found);
717: }
718: }
719: else
720: for (i = 0; i < 0200; i++) /* Search that map for a match */
721: {
722: QUIT;
723: tem = XVECTOR (map)->contents[i];
724: if (EQ (tem, definition)) /* Match found: record key sequence */
725: {
726: XFASTINT (dummy) = i; /* which is `this' followed by character i */
727: dummy = concat2 (this, Fchar_to_string (dummy));
728: if (firstonly)
729: return dummy;
730: found = Fcons (dummy, found);
731: }
732: }
733: }
734: return Fnreverse (found);
735: }
736:
737: DEFUN ("where-is", Fwhere_is, Swhere_is, 1, 1, "CWhere is command: ",
738: "Print message listing key sequences that invoke specified command.\n\
739: Argument is a command definition, usually a symbol with a function definition.")
740: (definition)
741: Lisp_Object definition;
742: {
743: Lisp_Object tem;
744: CHECK_SYMBOL (definition, 0);
745: tem = Fmapconcat (Qkey_description, Fwhere_is_internal (definition), build_string (", "));
746: if (XSTRING (tem)->size)
747: message ("%s is on %s", XSYMBOL (definition)->name->data, XSTRING (tem)->data);
748: else
749: message ("%s is not on any keys", XSYMBOL (definition)->name->data);
750: return Qnil;
751: }
752:
753: Lisp_Object describe_buffer_bindings ();
754:
755: DEFUN ("describe-bindings", Fdescribe_bindings, Sdescribe_bindings, 0, 0, "",
756: "Show a list of all defined keys, and their definitions.\n\
757: The list is put in a buffer, which is displayed.")
758: ()
759: {
760: Lisp_Object thisbuf;
761: XSETTYPE (thisbuf, Lisp_Buffer), XSETBUFFER (thisbuf, bf_cur);
762: internal_with_output_to_temp_buffer ("*Help*", describe_buffer_bindings, thisbuf);
763: return Qnil;
764: }
765:
766: Lisp_Object
767: describe_buffer_bindings (descbuf)
768: Lisp_Object descbuf;
769: {
770: register Lisp_Object start1;
771: char *heading = "key binding\n--- -------\n";
772:
773: Fset_buffer (Vstandard_output);
774:
775: start1 = XBUFFER (descbuf)->keymap;
776: if (!NULL (start1))
777: {
778: InsStr ("Local Bindings:\n");
779: InsStr (heading);
780: heading = 0;
781: describe_map_tree (start1, 0);
782: InsStr ("\n");
783: }
784:
785: InsStr ("Global Bindings:\n");
786: if (heading)
787: InsStr (heading);
788:
789: XSET (start1, Lisp_Vector, CurrentGlobalMap);
790: describe_map_tree (start1, 0);
791:
792: Fset_buffer (descbuf);
793: return Qnil;
794: }
795:
796: /* Insert a desription of the key bindings in STARTMAP,
797: followed by those of all maps reachable through STARTMAP.
798: If PARTIAL is nonzero, omit certain "uninteresting" commands
799: (such as `undefined'). */
800:
801: describe_map_tree (startmap, partial)
802: Lisp_Object startmap;
803: int partial;
804: {
805: register Lisp_Object maps, elt;
806:
807: maps = Faccessible_keymaps (startmap);
808:
809: for (; !NULL (maps); maps = Fcdr (maps))
810: {
811: elt = Fcar (maps);
812: describe_map (Fcdr (elt), Fcar (elt), partial);
813: }
814: }
815:
816: describe_command (definition)
817: Lisp_Object definition;
818: {
819: register Lisp_Object tem1;
820:
821: if (XTYPE (definition) == Lisp_Symbol)
822: {
823: XSETSTRING (tem1, XSYMBOL (definition)->name);
824: InsCStr (XSTRING (tem1)->data, XSTRING (tem1)->size);
825: }
826: else
827: {
828: tem1 = Fkeymapp (definition);
829: if (!NULL (tem1))
830: InsStr ("Prefix Command");
831: else
832: InsStr ("??");
833: }
834: }
835:
836: /* Describe the contents of map MAP, assuming that this map
837: itself is reached by the sequence of prefix keys KEYS (a string).
838: PARTIAL is the same as in `describe_map_tree', above. */
839:
840: describe_map (map, keys, partial)
841: Lisp_Object map, keys;
842: int partial;
843: {
844: register Lisp_Object keysdesc;
845:
846: InsStr ("\n");
847:
848: if (!NULL (keys) && XSTRING (keys)->size > 0)
849: keysdesc = Fkey_description (keys);
850: else
851: keysdesc = Qnil;
852:
853: if (LISTP (map))
854: describe_alist (Fcdr (map), keysdesc, describe_command, partial);
855: else
856: describe_vector (map, keysdesc, describe_command, partial);
857: }
858:
859: describe_alist (alist, elt_prefix, elt_describer, partial)
860: register Lisp_Object alist;
861: register Lisp_Object elt_prefix;
862: int (*elt_describer) ();
863: int partial;
864: {
865: Lisp_Object this;
866: register Lisp_Object tem1, tem2;
867: int indent;
868: Lisp_Object suppress;
869:
870: if (partial)
871: suppress = intern ("suppress-keymap");
872:
873: for (; LISTP (alist); alist = Fcdr (alist))
874: {
875: QUIT;
876: tem1 = Fcar (Fcar (alist));
877: tem2 = Fcdr (Fcar (alist));
878: if (NULL (tem2)) continue;
879: if (XTYPE (tem2) == Lisp_Symbol && partial)
880: {
881: this = Fget (tem2, suppress);
882: if (!NULL (this))
883: continue;
884: }
885:
886: indent = 0;
887:
888: if (!NULL (elt_prefix))
889: {
890: InsCStr (XSTRING (elt_prefix)->data, XSTRING (elt_prefix)->size);
891: InsCStr (" ", 1);
892: indent += XSTRING (elt_prefix)->size + 1;
893: }
894:
895: this = Fsingle_key_description (tem1);
896: InsCStr (XSTRING (this)->data, XSTRING (this)->size);
897: indent += XSTRING (this)->size;
898:
899: InsCStr (" ", indent<16 ? 16-indent : 1);
900:
901: (*elt_describer) (tem2);
902: InsCStr ("\n", 1);
903: }
904: }
905:
906: describe_vector (vector, elt_prefix, elt_describer, partial)
907: register Lisp_Object vector;
908: register Lisp_Object elt_prefix;
909: int (*elt_describer) ();
910: int partial;
911: {
912: Lisp_Object this;
913: Lisp_Object dummy;
914: Lisp_Object tem1, tem2;
915: register int i, size = XVECTOR (vector)->size;
916: int indent;
917: Lisp_Object suppress;
918:
919: if (partial)
920: suppress = intern ("suppress-keymap");
921:
922: for (i = 0; i < size; i++)
923: {
924: QUIT;
925: tem1 = XVECTOR (vector)->contents[i];
926: if (NULL (tem1)) continue;
927: if (XTYPE (tem1) == Lisp_Symbol && partial)
928: {
929: this = Fget (tem1, suppress);
930: if (!NULL (this))
931: continue;
932: }
933:
934: indent = 0;
935:
936: if (!NULL (elt_prefix))
937: {
938: InsCStr (XSTRING (elt_prefix)->data, XSTRING (elt_prefix)->size);
939: InsCStr (" ", 1);
940: indent += XSTRING (elt_prefix)->size + 1;
941: }
942: XFASTINT (dummy) = i;
943: this = Fsingle_key_description (dummy);
944: InsCStr (XSTRING (this)->data, XSTRING (this)->size);
945: indent += XSTRING (this)->size;
946:
947: while (i + 1 < size && (tem2 = XVECTOR (vector)->contents[i+1], EQ(tem2, tem1)))
948: i++;
949:
950: if (i != XINT (dummy))
951: {
952: InsCStr (" .. ", 4);
953: indent += 4;
954: if (!NULL (elt_prefix))
955: {
956: InsCStr (XSTRING (elt_prefix)->data, XSTRING (elt_prefix)->size);
957: InsCStr (" ", 1);
958: indent += XSTRING (elt_prefix)->size + 1;
959: }
960: XFASTINT (dummy) = i;
961: this = Fsingle_key_description (dummy);
962: InsCStr (XSTRING (this)->data, XSTRING (this)->size);
963: indent += XSTRING (this)->size;
964: }
965:
966: InsCStr (" ", indent<16 ? 16-indent : 1);
967:
968: tem1 = XVECTOR (vector)->contents[i];
969: (*elt_describer) (tem1);
970: InsCStr ("\n", 1);
971: }
972: }
973:
974: /* Apropos */
975: Lisp_Object apropos_predicate;
976: Lisp_Object apropos_accumulate;
977:
978: static
979: apropos_accum (symbol, string)
980: Lisp_Object symbol, string;
981: {
982: register Lisp_Object tem;
983:
984: tem = Fstring_match (string, Fsymbol_name (symbol), Qnil);
985: if (!NULL (tem) && !NULL (apropos_predicate))
986: tem = call1 (apropos_predicate, symbol);
987: if (!NULL (tem))
988: apropos_accumulate = Fcons (symbol, apropos_accumulate);
989: }
990:
991: static Lisp_Object
992: apropos1 (list)
993: register Lisp_Object list;
994: {
995: struct buffer *old = bf_cur;
996: register Lisp_Object symbol, col, tem;
997:
998: while (!NULL (list))
999: {
1000: QUIT;
1001:
1002: symbol = Fcar (list);
1003: list = Fcdr (list);
1004:
1005: tem = where_is_in_buffer (symbol, bf_cur, 0);
1006: tem = Fmapconcat (Qkey_description, tem, build_string (", "));
1007: XFASTINT (col) = 30;
1008:
1009: SetBfp (XBUFFER (Vstandard_output));
1010: Fprin1 (symbol, Qnil);
1011: Findent_to (col, Qnil);
1012: Fprinc (tem, Qnil);
1013: Fterpri (Qnil);
1014: tem = Ffboundp (symbol);
1015: if (!NULL (tem))
1016: tem = Fdocumentation (symbol);
1017: if (XTYPE (tem) == Lisp_String)
1018: insert_first_line (" Function: ", tem);
1019: tem = Fget (symbol, Qvariable_documentation);
1020: if (XTYPE (tem) == Lisp_String)
1021: insert_first_line (" Variable: ", tem);
1022: SetBfp (old);
1023: }
1024: return Qnil;
1025: }
1026:
1027: static
1028: insert_first_line (prefix, str)
1029: char *prefix;
1030: Lisp_Object str;
1031: {
1032: extern char *index ();
1033: register unsigned char *p;
1034: register unsigned char *p1;
1035: register unsigned char *p2;
1036:
1037: InsStr (prefix);
1038:
1039: retry:
1040: p = XSTRING (str)->data;
1041: p1 = (unsigned char *) index (p, '\n');
1042:
1043: for (p2 = p; *p2 && p2 != p1; p2++)
1044: if (p2[0] == '\\' && p2[1] == '[')
1045: {
1046: str = Fsubstitute_command_keys (str);
1047: goto retry;
1048: }
1049:
1050: InsCStr (p, p1 ? p1 - p : strlen (p));
1051: InsCStr ("\n", 1);
1052: }
1053:
1054: DEFUN ("apropos", Fapropos, Sapropos, 1, 3, "sApropos: ",
1055: "Show all symbols whose names contain match for REGEXP.\n\
1056: If optional arg PRED is non-nil, (funcall PRED SYM) is done\n\
1057: for each symbol and a symbol is mentioned if that returns non-nil.\n\
1058: Returns list of symbols found; if third arg NOPRINT is non-nil,\n\
1059: does not display them, just returns the list.")
1060: (string, pred, noprint)
1061: Lisp_Object string, pred, noprint;
1062: {
1063: struct gcpro gcpro1, gcpro2;
1064: CHECK_STRING (string, 0);
1065: apropos_predicate = pred;
1066: GCPRO2 (apropos_predicate, apropos_accumulate);
1067: apropos_accumulate = Qnil;
1068: map_obarray (Vobarray, apropos_accum, string);
1069: apropos_accumulate = Fsort (apropos_accumulate, Qstring_lessp);
1070: if (NULL (noprint))
1071: internal_with_output_to_temp_buffer ("*Help*", apropos1,
1072: apropos_accumulate);
1073: UNGCPRO;
1074: return apropos_accumulate;
1075: }
1076:
1077: DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_command,
1078: 1, 1, "P",
1079: "Read function name, then read its arguments and call it.")
1080: (prefixarg)
1081: Lisp_Object prefixarg;
1082: {
1083: Lisp_Object function;
1084: char buf[40];
1085:
1086: buf[0] = 0;
1087:
1088: if (EQ (prefixarg, Qminus))
1089: strcpy (buf, "- ");
1090: else if (LISTP (prefixarg) && XINT (XCONS (prefixarg)->car) == 4)
1091: strcpy (buf, "C-u ");
1092: else if (LISTP (prefixarg) && XTYPE (XCONS (prefixarg)->car) == Lisp_Int)
1093: sprintf (buf, "%d ", XINT (XCONS (prefixarg)->car));
1094: else if (XTYPE (prefixarg) == Lisp_Int)
1095: sprintf (buf, "%d ", XINT (prefixarg));
1096:
1097: strcat (buf, "M-x ");
1098:
1099: function = Fcompleting_read (build_string (buf), Vobarray, Qcommandp, Qt, Qnil);
1100:
1101: Vprefix_arg = prefixarg;
1102: return Fcommand_execute (Fintern (function, Vobarray), Qt);
1103: }
1104:
1105: syms_of_keymap ()
1106: {
1107: Lisp_Object tem;
1108:
1109: Qkeymap = intern ("keymap");
1110: staticpro (&Qkeymap);
1111:
1112: /* Initialize the keymaps standardly used.
1113: Each one is the value of a Lisp variable, and is also
1114: pointed to by a C variable */
1115:
1116: #ifdef HAVE_X_WINDOWS
1117: tem = Fmake_keymap ();
1118: MouseMap = XVECTOR (tem);
1119: Fset (intern ("mouse-map"), tem);
1120: #endif /* HAVE_X_WINDOWS */
1121:
1122: tem = Fmake_keymap ();
1123: GlobalMap = XVECTOR (tem);
1124: Fset (intern ("global-map"), tem);
1125:
1126: tem = Fmake_keymap ();
1127: ESCmap = XVECTOR (tem);
1128: Fset (intern ("esc-map"), tem);
1129: Ffset (intern ("ESC-prefix"), tem);
1130:
1131: tem = Fmake_keymap ();
1132: CtlXmap = XVECTOR (tem);
1133: Fset (intern ("ctl-x-map"), tem);
1134: Ffset (intern ("Control-X-prefix"), tem);
1135:
1136: DefLispVar ("minibuffer-local-map", &Vminibuffer_local_map,
1137: "Default keymap to use when reading from the minibuffer.");
1138: Vminibuffer_local_map = Fmake_sparse_keymap ();
1139:
1140: DefLispVar ("minibuffer-local-ns-map", &Vminibuffer_local_ns_map,
1141: "The keymap used by the minibuf for local bindings when spaces are not\n\
1142: to be allowed in input string.");
1143: Vminibuffer_local_ns_map = Fmake_sparse_keymap ();
1144:
1145: DefLispVar ("minibuffer-local-completion-map", &Vminibuffer_local_completion_map,
1146: "Keymap to use when reading from the minibuffer with completion.");
1147: Vminibuffer_local_completion_map = Fmake_sparse_keymap ();
1148:
1149: DefLispVar ("minibuffer-local-must-match-map", &Vminibuffer_local_must_match_map,
1150: "Keymap to use when reading from the minibuffer with completion and\n\
1151: an exact match of one of the completions is required.");
1152: Vminibuffer_local_must_match_map = Fmake_sparse_keymap ();
1153:
1154: CurrentGlobalMap = GlobalMap;
1155:
1156: Qsingle_key_description = intern ("single-key-description");
1157: staticpro (&Qsingle_key_description);
1158:
1159: Qkey_description = intern ("key-description");
1160: staticpro (&Qkey_description);
1161:
1162: Qkeymapp = intern ("keymapp");
1163: staticpro (&Qkeymapp);
1164:
1165: defsubr (&Skeymapp);
1166: defsubr (&Smake_keymap);
1167: defsubr (&Smake_sparse_keymap);
1168: defsubr (&Skey_binding);
1169: defsubr (&Slocal_key_binding);
1170: defsubr (&Sglobal_key_binding);
1171: defsubr (&Sglobal_set_key);
1172: defsubr (&Slocal_set_key);
1173: defsubr (&Sdefine_key);
1174: defsubr (&Slookup_key);
1175: defsubr (&Sglobal_unset_key);
1176: defsubr (&Slocal_unset_key);
1177: defsubr (&Suse_global_map);
1178: defsubr (&Suse_local_map);
1179: defsubr (&Scurrent_local_map);
1180: defsubr (&Saccessible_keymaps);
1181: defsubr (&Skey_description);
1182: defsubr (&Ssingle_key_description);
1183: defsubr (&Stext_char_description);
1184: defsubr (&Swhere_is_internal);
1185: defsubr (&Swhere_is);
1186: defsubr (&Sdescribe_bindings);
1187: defsubr (&Sapropos);
1188: defsubr (&Sexecute_extended_command);
1189: }
1190:
1191: keys_of_keymap ()
1192: {
1193: defkey (GlobalMap, 033, "ESC-prefix");
1194: defkey (GlobalMap, Ctl('X'), "Control-X-prefix");
1195: defkey (ESCmap, 'x', "execute-extended-command");
1196: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.