Annotation of src/usr.bin/mg/keymap.c, Revision 1.11
1.11 ! mickey 1: /* $OpenBSD: keymap.c,v 1.10 2001/05/23 22:36:14 art Exp $ */
1.5 niklas 2:
1.1 deraadt 3: /*
1.11 ! mickey 4: * Keyboard maps. This is character set dependent. The terminal specific
1.4 millert 5: * parts of building the keymap has been moved to a better place.
1.1 deraadt 6: */
1.4 millert 7:
1.1 deraadt 8: #include "def.h"
9: #include "kbd.h"
10:
1.4 millert 11: static int name_fent __P((char *, int));
1.1 deraadt 12:
13: /*
1.11 ! mickey 14: * initial keymap declarations, deepest first
1.1 deraadt 15: */
16:
17: #ifndef NO_HELP
1.4 millert 18: static PF cHcG[] = {
1.3 millert 19: ctrlg, /* ^G */
20: help_help, /* ^H */
21: };
1.4 millert 22:
23: static PF cHa[] = {
1.3 millert 24: apropos_command, /* a */
25: wallchart, /* b */
26: desckey, /* c */
1.1 deraadt 27: };
1.4 millert 28:
1.3 millert 29: static struct KEYMAPE (2 + IMAPEXT) helpmap = {
1.1 deraadt 30: 2,
1.3 millert 31: 2 + IMAPEXT,
1.1 deraadt 32: rescan,
33: {
1.3 millert 34: {
1.10 art 35: CCHR('G'), CCHR('H'), cHcG, NULL
1.3 millert 36: },
37: {
1.10 art 38: 'a', 'c', cHa, NULL
1.3 millert 39: },
1.1 deraadt 40: }
41: };
1.4 millert 42: #endif /* !NO_HELP */
1.1 deraadt 43:
1.3 millert 44: static struct KEYMAPE (1 + IMAPEXT) extramap1 = {
1.1 deraadt 45: 0,
1.3 millert 46: 1 + IMAPEXT,
1.1 deraadt 47: rescan
48: };
49:
1.3 millert 50: static struct KEYMAPE (1 + IMAPEXT) extramap2 = {
1.1 deraadt 51: 0,
1.3 millert 52: 1 + IMAPEXT,
1.1 deraadt 53: rescan
54: };
55:
1.3 millert 56: static struct KEYMAPE (1 + IMAPEXT) extramap3 = {
1.1 deraadt 57: 0,
1.3 millert 58: 1 + IMAPEXT,
1.1 deraadt 59: rescan
60: };
61:
1.3 millert 62: static struct KEYMAPE (1 + IMAPEXT) extramap4 = {
1.1 deraadt 63: 0,
1.3 millert 64: 1 + IMAPEXT,
1.1 deraadt 65: rescan
66: };
67:
1.3 millert 68: static struct KEYMAPE (1 + IMAPEXT) extramap5 = {
1.1 deraadt 69: 0,
1.3 millert 70: 1 + IMAPEXT,
1.1 deraadt 71: rescan
72: };
73:
1.4 millert 74: static PF cX4cF[] = {
1.3 millert 75: poptofile, /* ^f */
76: ctrlg, /* ^g */
77: };
1.4 millert 78: static PF cX4b[] = {
1.3 millert 79: poptobuffer, /* b */
80: rescan, /* c */
81: rescan, /* d */
82: rescan, /* e */
83: poptofile, /* f */
1.1 deraadt 84: };
1.3 millert 85: static struct KEYMAPE (2 + IMAPEXT) cX4map = {
1.1 deraadt 86: 2,
1.3 millert 87: 2 + IMAPEXT,
1.1 deraadt 88: rescan,
89: {
1.3 millert 90: {
1.10 art 91: CCHR('F'), CCHR('G'), cX4cF, NULL
1.3 millert 92: },
93: {
1.10 art 94: 'b', 'f', cX4b, NULL
1.3 millert 95: },
1.1 deraadt 96: }
97: };
98:
1.4 millert 99: static PF cXcB[] = {
1.3 millert 100: listbuffers, /* ^B */
101: quit, /* ^C */
102: rescan, /* ^D */
103: rescan, /* ^E */
104: filevisit, /* ^F */
105: ctrlg, /* ^G */
106: };
1.4 millert 107:
108: static PF cXcL[] = {
1.3 millert 109: lowerregion, /* ^L */
110: rescan, /* ^M */
111: rescan, /* ^N */
112: deblank, /* ^O */
113: rescan, /* ^P */
114: rescan, /* ^Q */
115: rescan, /* ^R */
116: filesave, /* ^S */
117: rescan, /* ^T */
118: upperregion, /* ^U */
119: rescan, /* ^V */
120: filewrite, /* ^W */
121: swapmark, /* ^X */
1.1 deraadt 122: };
1.4 millert 123:
1.1 deraadt 124: #ifndef NO_MACRO
1.4 millert 125: static PF cXlp[] = {
1.3 millert 126: definemacro, /* ( */
127: finishmacro, /* ) */
128: };
1.4 millert 129: #endif /* !NO_MACRO */
130:
131: static PF cX0[] = {
1.3 millert 132: delwind, /* 0 */
133: onlywind, /* 1 */
134: splitwind, /* 2 */
135: rescan, /* 3 */
1.6 art 136: NULL, /* 4 */
1.3 millert 137: };
1.4 millert 138:
139: static PF cXeq[] = {
1.3 millert 140: showcpos, /* = */
141: };
1.4 millert 142:
143: static PF cXcar[] = {
1.3 millert 144: enlargewind, /* ^ */
145: rescan, /* _ */
146: rescan, /* ` */
147: rescan, /* a */
148: usebuffer, /* b */
149: rescan, /* c */
1.1 deraadt 150: #ifndef NO_DIRED
1.3 millert 151: dired, /* d */
1.4 millert 152: #else /* !NO_DIRED */
1.3 millert 153: rescan, /* d */
1.4 millert 154: #endif /* !NO_DIRED */
1.1 deraadt 155: #ifndef NO_MACRO
1.3 millert 156: executemacro, /* e */
1.4 millert 157: #else /* !NO_MACRO */
1.3 millert 158: rescan, /* e */
1.4 millert 159: #endif /* !NO_MACRO */
1.3 millert 160: setfillcol, /* f */
161: rescan, /* g */
162: rescan, /* h */
163: fileinsert, /* i */
164: rescan, /* j */
165: killbuffer, /* k */
166: rescan, /* l */
167: rescan, /* m */
168: rescan, /* n */
169: nextwind, /* o */
170: rescan, /* p */
171: rescan, /* q */
172: rescan, /* r */
173: savebuffers, /* s */
1.1 deraadt 174: };
1.4 millert 175:
1.1 deraadt 176: #ifndef NO_MACRO
1.3 millert 177: static struct KEYMAPE (6 + IMAPEXT) cXmap = {
1.1 deraadt 178: 6,
1.3 millert 179: 6 + IMAPEXT,
1.4 millert 180: #else /* !NO_MACRO */
1.3 millert 181: static struct KEYMAPE (5 + IMAPEXT) cXmap = {
1.1 deraadt 182: 5,
1.3 millert 183: 5 + IMAPEXT,
1.4 millert 184: #endif /* !NO_MACRO */
1.1 deraadt 185: rescan,
186: {
1.3 millert 187: {
1.10 art 188: CCHR('B'), CCHR('G'), cXcB, NULL
1.3 millert 189: },
190: {
1.10 art 191: CCHR('L'), CCHR('X'), cXcL, NULL
1.3 millert 192: },
1.1 deraadt 193: #ifndef NO_MACRO
1.3 millert 194: {
1.10 art 195: '(', ')', cXlp, NULL
1.3 millert 196: },
1.4 millert 197: #endif /* !NO_MACRO */
1.3 millert 198: {
199: '0', '4', cX0, (KEYMAP *) & cX4map
200: },
201: {
1.10 art 202: '=', '=', cXeq, NULL
1.3 millert 203: },
204: {
1.10 art 205: '^', 's', cXcar, NULL
1.3 millert 206: },
1.1 deraadt 207: }
208: };
209:
1.4 millert 210: static PF metacG[] = {
1.3 millert 211: ctrlg, /* ^G */
1.1 deraadt 212: };
1.4 millert 213:
214: static PF metacV[] = {
1.3 millert 215: pagenext, /* ^V */
1.1 deraadt 216: };
1.4 millert 217:
218: static PF metasp[] = {
1.3 millert 219: justone, /* space */
1.1 deraadt 220: };
1.4 millert 221:
222: static PF metapct[] = {
1.3 millert 223: queryrepl, /* % */
1.1 deraadt 224: };
1.4 millert 225:
226: static PF metami[] = {
1.1 deraadt 227: negative_argument, /* - */
1.3 millert 228: rescan, /* . */
229: rescan, /* / */
230: digit_argument, /* 0 */
231: digit_argument, /* 1 */
232: digit_argument, /* 2 */
233: digit_argument, /* 3 */
234: digit_argument, /* 4 */
235: digit_argument, /* 5 */
236: digit_argument, /* 6 */
237: digit_argument, /* 7 */
238: digit_argument, /* 8 */
239: digit_argument, /* 9 */
240: rescan, /* : */
241: rescan, /* ; */
242: gotobob, /* < */
243: rescan, /* = */
244: gotoeob, /* > */
245: };
1.4 millert 246:
247: static PF metalb[] = {
1.3 millert 248: gotobop, /* [ */
249: delwhite, /* \ */
250: gotoeop, /* ] */
251: rescan, /* ^ */
252: rescan, /* _ */
253: rescan, /* ` */
254: rescan, /* a */
255: backword, /* b */
256: capword, /* c */
257: delfword, /* d */
258: rescan, /* e */
259: forwword, /* f */
260: };
1.4 millert 261:
262: static PF metal[] = {
1.3 millert 263: lowerword, /* l */
264: rescan, /* m */
265: rescan, /* n */
266: rescan, /* o */
267: rescan, /* p */
268: fillpara, /* q */
269: backsearch, /* r */
270: forwsearch, /* s */
271: rescan, /* t */
272: upperword, /* u */
273: backpage, /* v */
274: copyregion, /* w */
275: extend, /* x */
276: };
1.4 millert 277:
278: static PF metatilde[] = {
1.3 millert 279: notmodified, /* ~ */
280: delbword, /* DEL */
1.1 deraadt 281: };
1.4 millert 282:
1.3 millert 283: static struct KEYMAPE (8 + IMAPEXT) metamap = {
1.1 deraadt 284: 8,
1.3 millert 285: 8 + IMAPEXT,
1.1 deraadt 286: rescan,
287: {
1.3 millert 288: {
1.10 art 289: CCHR('G'), CCHR('G'), metacG, NULL
1.3 millert 290: },
291: {
1.10 art 292: CCHR('V'), CCHR('V'), metacV, NULL
1.3 millert 293: },
294: {
1.10 art 295: ' ', ' ', metasp, NULL
1.3 millert 296: },
297: {
1.10 art 298: '%', '%', metapct, NULL
1.3 millert 299: },
300: {
1.10 art 301: '-', '>', metami, NULL
1.3 millert 302: },
303: {
1.10 art 304: '[', 'f', metalb, NULL
1.3 millert 305: },
306: {
1.10 art 307: 'l', 'x', metal, NULL
1.3 millert 308: },
309: {
1.10 art 310: '~', CCHR('?'), metatilde, NULL
1.3 millert 311: },
1.1 deraadt 312: }
313: };
314:
1.4 millert 315: static PF fund_at[] = {
1.3 millert 316: setmark, /* ^@ */
317: gotobol, /* ^A */
318: backchar, /* ^B */
319: rescan, /* ^C */
320: forwdel, /* ^D */
321: gotoeol, /* ^E */
322: forwchar, /* ^F */
323: ctrlg, /* ^G */
1.1 deraadt 324: #ifndef NO_HELP
1.6 art 325: NULL, /* ^H */
1.4 millert 326: #else /* !NO_HELP */
1.3 millert 327: rescan, /* ^H */
1.4 millert 328: #endif /* !NO_HELP */
1.1 deraadt 329: };
1.4 millert 330:
1.1 deraadt 331: /* ^I is selfinsert */
1.4 millert 332: static PF fund_CJ[] = {
1.3 millert 333: indent, /* ^J */
334: killline, /* ^K */
335: reposition, /* ^L */
336: newline, /* ^M */
337: forwline, /* ^N */
338: openline, /* ^O */
339: backline, /* ^P */
340: quote, /* ^Q */
341: backisearch, /* ^R */
342: forwisearch, /* ^S */
343: twiddle, /* ^T */
1.1 deraadt 344: universal_argument, /* ^U */
1.3 millert 345: forwpage, /* ^V */
346: killregion, /* ^W */
1.6 art 347: NULL, /* ^X */
1.3 millert 348: yank, /* ^Y */
349: spawncli, /* ^Z */
1.1 deraadt 350: };
1.4 millert 351:
352: static PF fund_esc[] = {
1.6 art 353: NULL, /* esc */
1.4 millert 354: rescan, /* ^\ selfinsert is default on fundamental */
1.3 millert 355: rescan, /* ^] */
356: rescan, /* ^^ */
357: rescan, /* ^_ */
1.1 deraadt 358: };
1.4 millert 359:
360: static PF fund_del[] = {
1.3 millert 361: backdel, /* DEL */
1.1 deraadt 362: };
363:
364: #ifndef FUND_XMAPS
365: #define NFUND_XMAPS 0 /* extra map sections after normal ones */
366: #endif
367:
1.3 millert 368: static struct KEYMAPE (4 + NFUND_XMAPS + IMAPEXT) fundmap = {
1.1 deraadt 369: 4 + NFUND_XMAPS,
370: 4 + NFUND_XMAPS + IMAPEXT,
371: selfinsert,
372: {
373: #ifndef NO_HELP
1.3 millert 374: {
375: CCHR('@'), CCHR('H'), fund_at, (KEYMAP *) & helpmap
376: },
1.4 millert 377: #else /* !NO_HELP */
1.3 millert 378: {
1.10 art 379: CCHR('@'), CCHR('H'), fund_at, NULL
1.3 millert 380: },
1.4 millert 381: #endif /* !NO_HELP */
1.3 millert 382: {
383: CCHR('J'), CCHR('Z'), fund_CJ, (KEYMAP *) & cXmap
384: },
385: {
386: CCHR('['), CCHR('_'), fund_esc, (KEYMAP *) & metamap
387: },
388: {
1.10 art 389: CCHR('?'), CCHR('?'), fund_del, NULL
1.3 millert 390: },
1.4 millert 391: #ifdef FUND_XMAPS
1.1 deraadt 392: FUND_XMAPS,
1.4 millert 393: #endif /* FUND_XMAPS */
1.1 deraadt 394: }
395: };
396:
1.4 millert 397: static PF fill_sp[] = {
1.3 millert 398: fillword, /* ' ' */
1.1 deraadt 399: };
1.4 millert 400:
1.3 millert 401: static struct KEYMAPE (1 + IMAPEXT) fillmap = {
1.1 deraadt 402: 1,
1.3 millert 403: 1 + IMAPEXT,
1.1 deraadt 404: rescan,
405: {
1.3 millert 406: {
1.10 art 407: ' ', ' ', fill_sp, NULL
1.3 millert 408: },
1.1 deraadt 409: }
410: };
411:
1.4 millert 412: static PF indent_lf[] = {
1.3 millert 413: newline, /* ^J */
414: rescan, /* ^K */
415: rescan, /* ^L */
416: indent, /* ^M */
1.1 deraadt 417: };
1.4 millert 418:
1.3 millert 419: static struct KEYMAPE (1 + IMAPEXT) indntmap = {
1.1 deraadt 420: 1,
1.3 millert 421: 1 + IMAPEXT,
1.1 deraadt 422: rescan,
423: {
1.3 millert 424: {
1.10 art 425: CCHR('J'), CCHR('M'), indent_lf, NULL
1.3 millert 426: },
1.1 deraadt 427: }
428: };
1.4 millert 429:
430: static PF blink_rp[] = {
1.3 millert 431: showmatch, /* ) */
1.1 deraadt 432: };
1.4 millert 433:
1.3 millert 434: static struct KEYMAPE (1 + IMAPEXT) blinkmap = {
1.1 deraadt 435: 1,
1.3 millert 436: 1 + IMAPEXT,
1.1 deraadt 437: rescan,
438: {
1.3 millert 439: {
1.10 art 440: ')', ')', blink_rp, NULL
1.3 millert 441: },
1.1 deraadt 442: }
443: };
444:
1.4 millert 445: #ifdef NOTAB
446: static PF notab_tab[] = {
1.1 deraadt 447: space_to_tabstop, /* ^I */
448: };
1.4 millert 449:
1.3 millert 450: static struct KEYMAPE (1 + IMAPEXT) notabmap = {
1.1 deraadt 451: 1,
1.3 millert 452: 1 + IMAPEXT,
1.1 deraadt 453: rescan,
454: {
1.3 millert 455: {
1.10 art 456: CCHR('I'), CCHR('I'), notab_tab, NULL
1.3 millert 457: },
1.1 deraadt 458: }
459: };
1.4 millert 460: #endif /* NOTAB */
1.1 deraadt 461:
1.3 millert 462: static struct KEYMAPE (1 + IMAPEXT) overwmap = {
1.1 deraadt 463: 0,
1.3 millert 464: 1 + IMAPEXT, /* 1 to avoid 0 sized array */
1.1 deraadt 465: rescan,
466: {
467: /* unused dummy entry for VMS C */
1.3 millert 468: {
1.10 art 469: (KCHAR)0, (KCHAR)0, NULL, NULL
1.3 millert 470: },
1.1 deraadt 471: }
472: };
473:
474: #ifndef NO_DIRED
1.4 millert 475: static PF dirednul[] = {
1.3 millert 476: setmark, /* ^@ */
477: gotobol, /* ^A */
478: backchar, /* ^B */
479: rescan, /* ^C */
480: d_del, /* ^D */
481: gotoeol, /* ^E */
482: forwchar, /* ^F */
483: ctrlg, /* ^G */
1.1 deraadt 484: #ifndef NO_HELP
1.6 art 485: NULL, /* ^H */
1.4 millert 486: #endif /* !NO_HELP */
1.1 deraadt 487: };
1.4 millert 488:
489: static PF diredcl[] = {
1.3 millert 490: reposition, /* ^L */
491: forwline, /* ^M */
492: forwline, /* ^N */
493: rescan, /* ^O */
494: backline, /* ^P */
495: rescan, /* ^Q */
496: backisearch, /* ^R */
497: forwisearch, /* ^S */
498: rescan, /* ^T */
499: universal_argument, /* ^U */
500: forwpage, /* ^V */
501: rescan, /* ^W */
1.6 art 502: NULL, /* ^X */
1.1 deraadt 503: };
1.4 millert 504:
505: static PF diredcz[] = {
1.3 millert 506: spawncli, /* ^Z */
1.6 art 507: NULL, /* esc */
1.3 millert 508: rescan, /* ^\ */
509: rescan, /* ^] */
510: rescan, /* ^^ */
511: rescan, /* ^_ */
512: forwline, /* SP */
513: };
1.4 millert 514:
515: static PF diredc[] = {
1.3 millert 516: d_copy, /* c */
517: d_del, /* d */
518: d_findfile, /* e */
519: d_findfile, /* f */
520: };
1.4 millert 521:
522: static PF diredn[] = {
1.3 millert 523: forwline, /* n */
524: d_ffotherwindow, /* o */
525: backline, /* p */
526: rescan, /* q */
527: d_rename, /* r */
528: rescan, /* s */
529: rescan, /* t */
530: d_undel, /* u */
531: rescan, /* v */
532: rescan, /* w */
533: d_expunge, /* x */
1.1 deraadt 534: };
1.4 millert 535:
536: static PF direddl[] = {
1.3 millert 537: d_undelbak, /* del */
1.1 deraadt 538: };
539:
540: #ifndef DIRED_XMAPS
541: #define NDIRED_XMAPS 0 /* number of extra map sections */
1.4 millert 542: #endif /* DIRED_XMAPS */
1.1 deraadt 543:
1.3 millert 544: static struct KEYMAPE (6 + NDIRED_XMAPS + IMAPEXT) diredmap = {
1.1 deraadt 545: 6 + NDIRED_XMAPS,
546: 6 + NDIRED_XMAPS + IMAPEXT,
547: rescan,
548: {
549: #ifndef NO_HELP
1.3 millert 550: {
551: CCHR('@'), CCHR('H'), dirednul, (KEYMAP *) & helpmap
552: },
1.4 millert 553: #else /* !NO_HELP */
1.3 millert 554: {
1.10 art 555: CCHR('@'), CCHR('G'), dirednul, NULL
1.3 millert 556: },
1.4 millert 557: #endif /* !NO_HELP */
1.3 millert 558: {
559: CCHR('L'), CCHR('X'), diredcl, (KEYMAP *) & cXmap
560: },
561: {
562: CCHR('Z'), ' ', diredcz, (KEYMAP *) & metamap
563: },
564: {
1.10 art 565: 'c', 'f', diredc, NULL
1.3 millert 566: },
567: {
1.10 art 568: 'n', 'x', diredn, NULL
1.3 millert 569: },
570: {
1.10 art 571: CCHR('?'), CCHR('?'), direddl, NULL
1.3 millert 572: },
1.1 deraadt 573: #ifdef DIRED_XMAPS
1.3 millert 574: DIRED_XMAPS, /* map sections for dired mode keys */
1.4 millert 575: #endif /* DIRED_XMAPS */
1.1 deraadt 576: }
577: };
1.4 millert 578: #endif /* !NO_DIRED */
1.1 deraadt 579:
1.3 millert 580: /*
581: * give names to the maps, for use by help etc. If the map is to be bindable,
582: * it must also be listed in the function name table below with the same
583: * name. Maps created dynamicly currently don't get added here, thus are
584: * unnamed. Modes are just named keymaps with functions to add/subtract them
585: * from a buffer's list of modes. If you change a mode name, change it in
1.1 deraadt 586: * modes.c also.
587: */
588:
1.4 millert 589: MAPS map_table[] = {
1.1 deraadt 590: /* fundamental map MUST be first entry */
1.3 millert 591: {(KEYMAP *) & fundmap, "fundamental"},
592: {(KEYMAP *) & fillmap, "fill"},
593: {(KEYMAP *) & indntmap, "indent"},
594: {(KEYMAP *) & blinkmap, "blink"},
1.4 millert 595: #ifdef NOTAB
1.3 millert 596: {(KEYMAP *) & notabmap, "notab"},
1.4 millert 597: #endif /* NOTAB */
1.3 millert 598: {(KEYMAP *) & overwmap, "overwrite"},
599: {(KEYMAP *) & metamap, "esc prefix"},
600: {(KEYMAP *) & cXmap, "c-x prefix"},
601: {(KEYMAP *) & cX4map, "c-x 4 prefix"},
602: {(KEYMAP *) & extramap1, "extra prefix 1"},
603: {(KEYMAP *) & extramap2, "extra prefix 2"},
604: {(KEYMAP *) & extramap3, "extra prefix 3"},
605: {(KEYMAP *) & extramap4, "extra prefix 4"},
606: {(KEYMAP *) & extramap5, "extra prefix 5"},
1.1 deraadt 607: #ifndef NO_HELP
1.3 millert 608: {(KEYMAP *) & helpmap, "help"},
1.1 deraadt 609: #endif
610: #ifndef NO_DIRED
1.3 millert 611: {(KEYMAP *) & diredmap, "dired"},
1.1 deraadt 612: #endif
613: };
614:
615: #define NMAPS (sizeof map_table/sizeof(MAPS))
1.4 millert 616: int nmaps = NMAPS; /* for use by rebind in extend.c */
1.9 art 617:
618: KEYMAP *fundamental_map = (KEYMAP *)&fundmap;
1.1 deraadt 619:
1.4 millert 620: char *
1.3 millert 621: map_name(map)
1.4 millert 622: KEYMAP *map;
1.1 deraadt 623: {
1.4 millert 624: MAPS *mp = &map_table[0];
1.1 deraadt 625:
626: do {
1.3 millert 627: if (mp->p_map == map)
628: return mp->p_name;
629: } while (++mp < &map_table[NMAPS]);
1.10 art 630: return NULL;
1.1 deraadt 631: }
632:
1.4 millert 633: MAPS *
1.3 millert 634: name_mode(name)
1.4 millert 635: char *name;
1.1 deraadt 636: {
1.4 millert 637: MAPS *mp = &map_table[0];
1.1 deraadt 638:
639: do {
1.3 millert 640: if (strcmp(mp->p_name, name) == 0)
641: return mp;
642: } while (++mp < &map_table[NMAPS]);
1.10 art 643: return NULL;
1.1 deraadt 644: }
645:
1.4 millert 646: KEYMAP *
1.3 millert 647: name_map(name)
1.4 millert 648: char *name;
1.1 deraadt 649: {
1.4 millert 650: MAPS *mp;
1.10 art 651: return (mp = name_mode(name)) == NULL ? NULL : mp->p_map;
1.1 deraadt 652: }
653:
1.3 millert 654: /*
655: * Warning: functnames MUST be in alphabetical order! (due to binary search
1.6 art 656: * in name_function.) If the function is NULL, it must be listed with the
1.3 millert 657: * same name in the map_table above.
1.1 deraadt 658: */
1.11 ! mickey 659: const FUNCTNAMES functnames[] = {
1.1 deraadt 660: #ifndef NO_HELP
661: {apropos_command, "apropos"},
1.4 millert 662: #endif /* !NO_HELP */
1.3 millert 663: {fillmode, "auto-fill-mode"},
664: {indentmode, "auto-indent-mode"},
665: {backchar, "backward-char"},
666: {delbword, "backward-kill-word"},
667: {gotobop, "backward-paragraph"},
668: {backword, "backward-word"},
669: {gotobob, "beginning-of-buffer"},
670: {gotobol, "beginning-of-line"},
671: {blinkparen, "blink-matching-paren"},
672: {showmatch, "blink-matching-paren-hack"},
1.4 millert 673: #ifdef BSMAP
1.3 millert 674: {bsmap, "bsmap-mode"},
1.4 millert 675: #endif /* BSMAP */
1.6 art 676: {NULL, "c-x 4 prefix"},
677: {NULL, "c-x prefix"},
1.1 deraadt 678: #ifndef NO_MACRO
1.3 millert 679: {executemacro, "call-last-kbd-macro"},
1.4 millert 680: #endif /* !NO_MACRO */
1.3 millert 681: {capword, "capitalize-word"},
1.1 deraadt 682: #ifndef NO_DIR
1.3 millert 683: {changedir, "cd"},
1.4 millert 684: #endif /* !NO_DIR */
1.3 millert 685: {copyregion, "copy-region-as-kill"},
1.1 deraadt 686: #ifdef REGEX
687: {cntmatchlines, "count-matches"},
1.3 millert 688: {cntnonmatchlines, "count-non-matches"},
1.4 millert 689: #endif /* REGEX */
1.3 millert 690: {define_key, "define-key"},
691: {backdel, "delete-backward-char"},
692: {deblank, "delete-blank-lines"},
693: {forwdel, "delete-char"},
694: {delwhite, "delete-horizontal-space"},
1.1 deraadt 695: #ifdef REGEX
696: {delmatchlines, "delete-matching-lines"},
1.3 millert 697: {delnonmatchlines, "delete-non-matching-lines"},
1.4 millert 698: #endif /* REGEX */
1.3 millert 699: {onlywind, "delete-other-windows"},
700: {delwind, "delete-window"},
1.1 deraadt 701: #ifndef NO_HELP
1.3 millert 702: {wallchart, "describe-bindings"},
703: {desckey, "describe-key-briefly"},
1.4 millert 704: #endif /* !NO_HELP */
1.3 millert 705: {digit_argument, "digit-argument"},
1.1 deraadt 706: #ifndef NO_DIRED
1.3 millert 707: {dired, "dired"},
708: {d_undelbak, "dired-backup-unflag"},
709: {d_copy, "dired-copy-file"},
710: {d_expunge, "dired-do-deletions"},
711: {d_findfile, "dired-find-file"},
1.1 deraadt 712: {d_ffotherwindow, "dired-find-file-other-window"},
1.3 millert 713: {d_del, "dired-flag-file-deleted"},
1.1 deraadt 714: {d_otherwindow, "dired-other-window"},
1.3 millert 715: {d_rename, "dired-rename-file"},
716: {d_undel, "dired-unflag"},
1.4 millert 717: #endif /* !NO_DIRED */
1.3 millert 718: {lowerregion, "downcase-region"},
719: {lowerword, "downcase-word"},
720: {showversion, "emacs-version"},
1.1 deraadt 721: #ifndef NO_MACRO
1.3 millert 722: {finishmacro, "end-kbd-macro"},
1.4 millert 723: #endif /* !NO_MACRO */
1.3 millert 724: {gotoeob, "end-of-buffer"},
725: {gotoeol, "end-of-line"},
726: {enlargewind, "enlarge-window"},
1.6 art 727: {NULL, "esc prefix"},
1.1 deraadt 728: #ifndef NO_STARTUP
1.3 millert 729: {evalbuffer, "eval-current-buffer"},
730: {evalexpr, "eval-expression"},
1.4 millert 731: #endif /* !NO_STARTUP */
1.3 millert 732: {swapmark, "exchange-point-and-mark"},
733: {extend, "execute-extended-command"},
1.6 art 734: {NULL, "extra prefix 1"},
735: {NULL, "extra prefix 2"},
736: {NULL, "extra prefix 3"},
737: {NULL, "extra prefix 4"},
738: {NULL, "extra prefix 5"},
1.3 millert 739: {fillpara, "fill-paragraph"},
740: {filevisit, "find-file"},
741: {poptofile, "find-file-other-window"},
742: {forwchar, "forward-char"},
743: {gotoeop, "forward-paragraph"},
744: {forwword, "forward-word"},
745: {bindtokey, "global-set-key"},
746: {unbindtokey, "global-unset-key"},
747: {gotoline, "goto-line"},
1.1 deraadt 748: #ifndef NO_HELP
1.6 art 749: {NULL, "help"},
1.3 millert 750: {help_help, "help-help"},
1.4 millert 751: #endif /* !NO_HELP */
1.3 millert 752: {insert, "insert"},
753: {bufferinsert, "insert-buffer"},
754: {fileinsert, "insert-file"},
755: {fillword, "insert-with-wrap"},
756: {backisearch, "isearch-backward"},
757: {forwisearch, "isearch-forward"},
758: {justone, "just-one-space"},
759: {ctrlg, "keyboard-quit"},
760: {killbuffer, "kill-buffer"},
761: {killline, "kill-line"},
762: {killpara, "kill-paragraph"},
763: {killregion, "kill-region"},
764: {delfword, "kill-word"},
765: {listbuffers, "list-buffers"},
1.1 deraadt 766: #ifndef NO_STARTUP
1.3 millert 767: {evalfile, "load"},
1.4 millert 768: #endif /* !NO_STARTUP */
1.3 millert 769: {localbind, "local-set-key"},
770: {localunbind, "local-unset-key"},
1.1 deraadt 771: #ifndef NO_BACKUP
1.3 millert 772: {makebkfile, "make-backup-files"},
1.4 millert 773: #endif /* !NO_BACKUP */
774: #ifdef DO_METAKEY
1.3 millert 775: {do_meta, "meta-key-mode"}, /* better name, anyone? */
1.4 millert 776: #endif /* DO_METAKEY */
1.1 deraadt 777: {negative_argument, "negative-argument"},
1.3 millert 778: {newline, "newline"},
779: {indent, "newline-and-indent"},
780: {forwline, "next-line"},
1.4 millert 781: #ifdef NOTAB
1.3 millert 782: {notabmode, "no-tab-mode"},
1.4 millert 783: #endif /* NOTAB */
1.3 millert 784: {notmodified, "not-modified"},
785: {openline, "open-line"},
786: {nextwind, "other-window"},
787: {overwrite, "overwrite-mode"},
1.4 millert 788: #ifdef PREFIXREGION
1.3 millert 789: {prefixregion, "prefix-region"},
1.4 millert 790: #endif /* PREFIXREGION */
1.3 millert 791: {backline, "previous-line"},
1.4 millert 792: #ifdef GOSMACS
1.3 millert 793: {prevwind, "previous-window"},
1.4 millert 794: #endif /* GOSEMACS */
1.3 millert 795: {spawncli, "push-shell"},
1.1 deraadt 796: #ifndef NO_DIR
1.3 millert 797: {showcwdir, "pwd"},
1.4 millert 798: #endif /* !NO_DIR */
1.3 millert 799: {queryrepl, "query-replace"},
1.4 millert 800: #ifdef REGEX
1.3 millert 801: {re_queryrepl, "query-replace-regexp"},
1.4 millert 802: #endif /* REGEX */
1.3 millert 803: {quote, "quoted-insert"},
1.4 millert 804: #ifdef REGEX
1.3 millert 805: {re_searchagain, "re-search-again"},
1.1 deraadt 806: {re_backsearch, "re-search-backward"},
807: {re_forwsearch, "re-search-forward"},
1.4 millert 808: #endif /* REGEX */
1.3 millert 809: {reposition, "recenter"},
810: {refresh, "redraw-display"},
811: {filesave, "save-buffer"},
812: {quit, "save-buffers-kill-emacs"},
813: {savebuffers, "save-some-buffers"},
814: {backpage, "scroll-down"},
1.4 millert 815: #ifdef GOSMACS
1.3 millert 816: {back1page, "scroll-one-line-down"},
817: {forw1page, "scroll-one-line-up"},
1.4 millert 818: #endif /* GOSMACS */
1.3 millert 819: {pagenext, "scroll-other-window"},
820: {forwpage, "scroll-up"},
821: {searchagain, "search-again"},
822: {backsearch, "search-backward"},
823: {forwsearch, "search-forward"},
824: {selfinsert, "self-insert-command"},
1.4 millert 825: #ifdef REGEX
1.3 millert 826: {setcasefold, "set-case-fold-search"},
1.4 millert 827: #endif /* REGEX */
1.1 deraadt 828: {set_default_mode, "set-default-mode"},
1.3 millert 829: {setfillcol, "set-fill-column"},
830: {setmark, "set-mark-command"},
1.4 millert 831: #ifdef PREFIXREGION
1.3 millert 832: {setprefix, "set-prefix-string"},
1.4 millert 833: #endif /* PREFIXREGION */
1.3 millert 834: {shrinkwind, "shrink-window"},
1.4 millert 835: #ifdef NOTAB
1.1 deraadt 836: {space_to_tabstop, "space-to-tabstop"},
1.4 millert 837: #endif /* NOTAB */
1.3 millert 838: {splitwind, "split-window-vertically"},
1.1 deraadt 839: #ifndef NO_MACRO
1.3 millert 840: {definemacro, "start-kbd-macro"},
1.4 millert 841: #endif /* !NO_MACRO */
1.3 millert 842: {spawncli, "suspend-emacs"},
843: {usebuffer, "switch-to-buffer"},
844: {poptobuffer, "switch-to-buffer-other-window"},
845: {twiddle, "transpose-chars"},
1.1 deraadt 846: {universal_argument, "universal-argument"},
1.3 millert 847: {upperregion, "upcase-region"},
848: {upperword, "upcase-word"},
849: {showcpos, "what-cursor-position"},
850: {filewrite, "write-file"},
851: {yank, "yank"},
1.1 deraadt 852: };
853:
854: #define NFUNCT (sizeof(functnames)/sizeof(FUNCTNAMES))
855:
856: /*
857: * The general-purpose version of ROUND2 blows osk C (2.0) out of the water.
858: * (reboot required) If you need to build a version of mg with less than 32
859: * or more than 511 functions, something better must be done.
860: * The version that should work, but doesn't is:
861: * #define ROUND2(x) (1+((x>>1)|(x>>2)|(x>>3)|(x>>4)|(x>>5)|(x>>6)|(x>>7)|\
862: * (x>>8)|(x>>9)|(x>>10)|(x>>11)|(x>>12)|(x>>13)|(x>>14)|(x>>15)))
863: */
864: #define ROUND2(x) (x<128?(x<64?32:64):(x<256?128:256))
865:
1.4 millert 866: static int
1.3 millert 867: name_fent(fname, flag)
1.4 millert 868: char *fname;
869: int flag;
1.1 deraadt 870: {
1.4 millert 871: int try, notit;
872: int x = ROUND2(NFUNCT);
873: int base = 0;
1.1 deraadt 874:
875: do {
1.3 millert 876: /* + can be used instead of | here if more efficent. */
877: if ((try = base | x) < NFUNCT) {
1.11 ! mickey 878: if ((notit = strcmp(fname, functnames[try].n_name))
1.4 millert 879: >= 0) {
1.3 millert 880: if (!notit)
881: return try;
882: base = try;
883: }
1.1 deraadt 884: }
1.4 millert 885: /* try 0 once if needed */
886: } while ((x >>= 1) || (try == 1 && base == 0));
1.1 deraadt 887: return flag ? base : -1;
888: }
889:
890: /*
891: * Translate from function name to function pointer, using binary search.
892: */
893:
1.3 millert 894: PF
895: name_function(fname)
1.4 millert 896: char *fname;
1.1 deraadt 897: {
1.4 millert 898: int i;
1.3 millert 899: if ((i = name_fent(fname, FALSE)) >= 0)
900: return functnames[i].n_funct;
1.4 millert 901: return (PF)NULL;
1.1 deraadt 902: }
903:
1.4 millert 904: /*
905: * list possible function name completions.
906: */
907: LIST *
1.3 millert 908: complete_function_list(fname, c)
1.4 millert 909: char *fname;
910: int c;
1.1 deraadt 911: {
1.4 millert 912: int i, j, k, l;
913: LIST *current, *last;
1.1 deraadt 914:
915: i = name_fent(fname, TRUE);
1.4 millert 916: for (j = 0; (l = fname[j]) && functnames[i].n_name[j] == l; j++);
1.3 millert 917: if (fname[j] != '\0') {
918: if (++i >= NFUNCT)
1.4 millert 919: /* no match */
920: return NULL;
1.11 ! mickey 921: for (j = 0; (l = fname[j]) && functnames[i].n_name[j] == l;
1.4 millert 922: j++);
1.3 millert 923: if (fname[j] != '\0')
1.4 millert 924: /* no match */
925: return NULL;
1.1 deraadt 926: }
1.3 millert 927: /*
1.4 millert 928: * if(c==CCHR('M') && functnames[i].n_name[j]=='\0') return -1;
1.3 millert 929: */
1.4 millert 930: /* find last match */
931: for (k = i + 1; k < NFUNCT; k++) {
932: for (l = 0; functnames[k].n_name[l] == fname[l]; l++);
1.3 millert 933: if (l < j)
934: break;
1.1 deraadt 935: }
936: k--;
937: last = NULL;
938: for (; k >= i; k--) {
1.4 millert 939: current = (LIST *)malloc(sizeof(LIST));
1.3 millert 940: current->l_next = last;
941: current->l_name = functnames[k].n_name;
942: last = current;
1.1 deraadt 943: }
1.3 millert 944: return (last);
1.1 deraadt 945: }
946:
1.4 millert 947: /*
948: * translate from function pointer to function name.
949: */
950: char *
1.3 millert 951: function_name(fpoint)
1.4 millert 952: PF fpoint;
1.1 deraadt 953: {
1.11 ! mickey 954: const FUNCTNAMES *fnp = &functnames[0];
1.1 deraadt 955:
1.6 art 956: if (fpoint == NULL)
1.4 millert 957: /* ambiguous */
1.10 art 958: return NULL;
1.1 deraadt 959: do {
1.3 millert 960: if (fnp->n_funct == fpoint)
961: return fnp->n_name;
962: } while (++fnp < &functnames[NFUNCT]);
1.10 art 963: return NULL;
1.1 deraadt 964: }