Annotation of src/usr.bin/mg/keymap.c, Revision 1.42
1.42 ! kjell 1: /* $OpenBSD: keymap.c,v 1.41 2008/06/12 21:13:20 kjell Exp $ */
1.30 kjell 2:
3: /* This file is in the public domain. */
1.5 niklas 4:
1.1 deraadt 5: /*
1.11 mickey 6: * Keyboard maps. This is character set dependent. The terminal specific
1.4 millert 7: * parts of building the keymap has been moved to a better place.
1.1 deraadt 8: */
1.4 millert 9:
1.28 db 10: #include "def.h"
11: #include "kbd.h"
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 */
1.28 db 20: help_help /* ^H */
1.3 millert 21: };
1.4 millert 22:
23: static PF cHa[] = {
1.3 millert 24: apropos_command, /* a */
25: wallchart, /* b */
1.28 db 26: desckey /* c */
1.1 deraadt 27: };
1.4 millert 28:
1.33 kjell 29: 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.28 db 39: }
1.1 deraadt 40: }
41: };
1.4 millert 42: #endif /* !NO_HELP */
1.1 deraadt 43:
1.4 millert 44: static PF cX4cF[] = {
1.3 millert 45: poptofile, /* ^f */
1.28 db 46: ctrlg /* ^g */
1.3 millert 47: };
1.4 millert 48: static PF cX4b[] = {
1.3 millert 49: poptobuffer, /* b */
50: rescan, /* c */
51: rescan, /* d */
52: rescan, /* e */
1.28 db 53: poptofile /* f */
1.1 deraadt 54: };
1.3 millert 55: static struct KEYMAPE (2 + IMAPEXT) cX4map = {
1.1 deraadt 56: 2,
1.3 millert 57: 2 + IMAPEXT,
1.1 deraadt 58: rescan,
59: {
1.3 millert 60: {
1.10 art 61: CCHR('F'), CCHR('G'), cX4cF, NULL
1.3 millert 62: },
63: {
1.10 art 64: 'b', 'f', cX4b, NULL
1.28 db 65: }
1.1 deraadt 66: }
67: };
68:
1.4 millert 69: static PF cXcB[] = {
1.3 millert 70: listbuffers, /* ^B */
71: quit, /* ^C */
72: rescan, /* ^D */
73: rescan, /* ^E */
74: filevisit, /* ^F */
1.28 db 75: ctrlg /* ^G */
1.3 millert 76: };
1.4 millert 77:
78: static PF cXcL[] = {
1.3 millert 79: lowerregion, /* ^L */
80: rescan, /* ^M */
81: rescan, /* ^N */
82: deblank, /* ^O */
83: rescan, /* ^P */
1.34 kjell 84: togglereadonly, /* ^Q */
1.31 kjell 85: filevisitro, /* ^R */
1.3 millert 86: filesave, /* ^S */
87: rescan, /* ^T */
88: upperregion, /* ^U */
1.29 jason 89: filevisitalt, /* ^V */
1.3 millert 90: filewrite, /* ^W */
1.28 db 91: swapmark /* ^X */
1.1 deraadt 92: };
1.4 millert 93:
1.1 deraadt 94: #ifndef NO_MACRO
1.4 millert 95: static PF cXlp[] = {
1.3 millert 96: definemacro, /* ( */
1.28 db 97: finishmacro /* ) */
1.3 millert 98: };
1.4 millert 99: #endif /* !NO_MACRO */
100:
101: static PF cX0[] = {
1.3 millert 102: delwind, /* 0 */
103: onlywind, /* 1 */
104: splitwind, /* 2 */
105: rescan, /* 3 */
1.28 db 106: NULL /* 4 */
1.3 millert 107: };
1.4 millert 108:
109: static PF cXeq[] = {
1.28 db 110: showcpos /* = */
1.3 millert 111: };
1.4 millert 112:
113: static PF cXcar[] = {
1.3 millert 114: enlargewind, /* ^ */
115: rescan, /* _ */
1.32 kjell 116: next_error, /* ` */
1.3 millert 117: rescan, /* a */
118: usebuffer, /* b */
119: rescan, /* c */
120: rescan, /* d */
1.1 deraadt 121: #ifndef NO_MACRO
1.3 millert 122: executemacro, /* e */
1.4 millert 123: #else /* !NO_MACRO */
1.3 millert 124: rescan, /* e */
1.4 millert 125: #endif /* !NO_MACRO */
1.3 millert 126: setfillcol, /* f */
1.26 deraadt 127: gotoline, /* g */
1.3 millert 128: rescan, /* h */
129: fileinsert, /* i */
130: rescan, /* j */
1.27 jfb 131: killbuffer_cmd, /* k */
1.3 millert 132: rescan, /* l */
133: rescan, /* m */
1.15 deraadt 134: nextwind, /* n */
1.3 millert 135: nextwind, /* o */
1.15 deraadt 136: prevwind, /* p */
1.3 millert 137: rescan, /* q */
138: rescan, /* r */
139: savebuffers, /* s */
1.25 deraadt 140: rescan, /* t */
1.24 deraadt 141: undo /* u */
1.1 deraadt 142: };
1.4 millert 143:
1.1 deraadt 144: #ifndef NO_MACRO
1.33 kjell 145: struct KEYMAPE (6 + IMAPEXT) cXmap = {
1.1 deraadt 146: 6,
1.3 millert 147: 6 + IMAPEXT,
1.4 millert 148: #else /* !NO_MACRO */
1.3 millert 149: static struct KEYMAPE (5 + IMAPEXT) cXmap = {
1.1 deraadt 150: 5,
1.3 millert 151: 5 + IMAPEXT,
1.4 millert 152: #endif /* !NO_MACRO */
1.1 deraadt 153: rescan,
154: {
1.3 millert 155: {
1.10 art 156: CCHR('B'), CCHR('G'), cXcB, NULL
1.3 millert 157: },
158: {
1.10 art 159: CCHR('L'), CCHR('X'), cXcL, NULL
1.3 millert 160: },
1.1 deraadt 161: #ifndef NO_MACRO
1.3 millert 162: {
1.10 art 163: '(', ')', cXlp, NULL
1.3 millert 164: },
1.4 millert 165: #endif /* !NO_MACRO */
1.3 millert 166: {
167: '0', '4', cX0, (KEYMAP *) & cX4map
168: },
169: {
1.10 art 170: '=', '=', cXeq, NULL
1.3 millert 171: },
172: {
1.24 deraadt 173: '^', 'u', cXcar, NULL
1.28 db 174: }
1.1 deraadt 175: }
176: };
177:
1.4 millert 178: static PF metacG[] = {
1.28 db 179: ctrlg /* ^G */
1.1 deraadt 180: };
1.4 millert 181:
182: static PF metacV[] = {
1.28 db 183: pagenext /* ^V */
1.1 deraadt 184: };
1.4 millert 185:
186: static PF metasp[] = {
1.28 db 187: justone /* space */
1.1 deraadt 188: };
1.4 millert 189:
190: static PF metapct[] = {
1.28 db 191: queryrepl /* % */
1.1 deraadt 192: };
1.4 millert 193:
194: static PF metami[] = {
1.1 deraadt 195: negative_argument, /* - */
1.3 millert 196: rescan, /* . */
197: rescan, /* / */
198: digit_argument, /* 0 */
199: digit_argument, /* 1 */
200: digit_argument, /* 2 */
201: digit_argument, /* 3 */
202: digit_argument, /* 4 */
203: digit_argument, /* 5 */
204: digit_argument, /* 6 */
205: digit_argument, /* 7 */
206: digit_argument, /* 8 */
207: digit_argument, /* 9 */
208: rescan, /* : */
209: rescan, /* ; */
210: gotobob, /* < */
211: rescan, /* = */
1.28 db 212: gotoeob /* > */
1.3 millert 213: };
1.4 millert 214:
1.42 ! kjell 215: static PF metasqf[] = {
! 216: NULL, /* [ */
1.3 millert 217: delwhite, /* \ */
1.39 kjell 218: rescan, /* ] */
1.3 millert 219: rescan, /* ^ */
220: rescan, /* _ */
221: rescan, /* ` */
222: rescan, /* a */
223: backword, /* b */
224: capword, /* c */
225: delfword, /* d */
226: rescan, /* e */
1.28 db 227: forwword /* f */
1.3 millert 228: };
1.4 millert 229:
230: static PF metal[] = {
1.3 millert 231: lowerword, /* l */
232: rescan, /* m */
233: rescan, /* n */
234: rescan, /* o */
235: rescan, /* p */
236: fillpara, /* q */
237: backsearch, /* r */
238: forwsearch, /* s */
239: rescan, /* t */
240: upperword, /* u */
241: backpage, /* v */
242: copyregion, /* w */
1.39 kjell 243: extend, /* x */
244: rescan, /* y */
245: rescan, /* z */
246: gotobop, /* { */
247: rescan, /* | */
248: gotoeop /* } */
1.3 millert 249: };
1.4 millert 250:
1.42 ! kjell 251: static PF metasqlZ[] = {
! 252: rescan /* Z */
! 253: };
! 254:
1.4 millert 255: static PF metatilde[] = {
1.3 millert 256: notmodified, /* ~ */
1.28 db 257: delbword /* DEL */
1.1 deraadt 258: };
1.4 millert 259:
1.42 ! kjell 260: struct KEYMAPE (1 + IMAPEXT) metasqlmap = {
! 261: 1,
! 262: 1 + IMAPEXT,
! 263: rescan,
! 264: {
! 265: {
! 266: 'Z', 'Z', metasqlZ, NULL
! 267: }
! 268: }
! 269: };
! 270:
1.33 kjell 271: struct KEYMAPE (8 + IMAPEXT) metamap = {
1.1 deraadt 272: 8,
1.3 millert 273: 8 + IMAPEXT,
1.1 deraadt 274: rescan,
275: {
1.3 millert 276: {
1.10 art 277: CCHR('G'), CCHR('G'), metacG, NULL
1.3 millert 278: },
279: {
1.10 art 280: CCHR('V'), CCHR('V'), metacV, NULL
1.3 millert 281: },
282: {
1.10 art 283: ' ', ' ', metasp, NULL
1.3 millert 284: },
285: {
1.10 art 286: '%', '%', metapct, NULL
1.3 millert 287: },
288: {
1.10 art 289: '-', '>', metami, NULL
1.3 millert 290: },
291: {
1.42 ! kjell 292: '[', 'f', metasqf, (KEYMAP *) &metasqlmap
1.3 millert 293: },
294: {
1.39 kjell 295: 'l', '}', metal, NULL
1.3 millert 296: },
297: {
1.10 art 298: '~', CCHR('?'), metatilde, NULL
1.28 db 299: }
1.1 deraadt 300: }
301: };
302:
1.4 millert 303: static PF fund_at[] = {
1.3 millert 304: setmark, /* ^@ */
305: gotobol, /* ^A */
306: backchar, /* ^B */
307: rescan, /* ^C */
308: forwdel, /* ^D */
309: gotoeol, /* ^E */
310: forwchar, /* ^F */
311: ctrlg, /* ^G */
1.1 deraadt 312: #ifndef NO_HELP
1.6 art 313: NULL, /* ^H */
1.4 millert 314: #else /* !NO_HELP */
1.3 millert 315: rescan, /* ^H */
1.4 millert 316: #endif /* !NO_HELP */
1.1 deraadt 317: };
1.4 millert 318:
1.1 deraadt 319: /* ^I is selfinsert */
1.4 millert 320: static PF fund_CJ[] = {
1.40 kjell 321: lfindent, /* ^J */
1.3 millert 322: killline, /* ^K */
323: reposition, /* ^L */
324: newline, /* ^M */
325: forwline, /* ^N */
326: openline, /* ^O */
327: backline, /* ^P */
328: quote, /* ^Q */
329: backisearch, /* ^R */
330: forwisearch, /* ^S */
331: twiddle, /* ^T */
1.1 deraadt 332: universal_argument, /* ^U */
1.3 millert 333: forwpage, /* ^V */
334: killregion, /* ^W */
1.6 art 335: NULL, /* ^X */
1.3 millert 336: yank, /* ^Y */
1.28 db 337: spawncli /* ^Z */
1.1 deraadt 338: };
1.4 millert 339:
340: static PF fund_esc[] = {
1.6 art 341: NULL, /* esc */
1.4 millert 342: rescan, /* ^\ selfinsert is default on fundamental */
1.3 millert 343: rescan, /* ^] */
344: rescan, /* ^^ */
1.28 db 345: undo /* ^_ */
1.1 deraadt 346: };
1.4 millert 347:
348: static PF fund_del[] = {
1.28 db 349: backdel /* DEL */
1.1 deraadt 350: };
351:
1.42 ! kjell 352: static PF fund_cb[] = {
! 353: showmatch /* ) */
! 354: };
! 355:
1.1 deraadt 356: #ifndef FUND_XMAPS
357: #define NFUND_XMAPS 0 /* extra map sections after normal ones */
358: #endif
359:
1.42 ! kjell 360: static struct KEYMAPE (5 + NFUND_XMAPS + IMAPEXT) fundmap = {
! 361: 5 + NFUND_XMAPS,
! 362: 5 + NFUND_XMAPS + IMAPEXT,
1.1 deraadt 363: selfinsert,
364: {
365: #ifndef NO_HELP
1.3 millert 366: {
367: CCHR('@'), CCHR('H'), fund_at, (KEYMAP *) & helpmap
368: },
1.4 millert 369: #else /* !NO_HELP */
1.3 millert 370: {
1.10 art 371: CCHR('@'), CCHR('H'), fund_at, NULL
1.3 millert 372: },
1.4 millert 373: #endif /* !NO_HELP */
1.3 millert 374: {
375: CCHR('J'), CCHR('Z'), fund_CJ, (KEYMAP *) & cXmap
376: },
377: {
378: CCHR('['), CCHR('_'), fund_esc, (KEYMAP *) & metamap
379: },
380: {
1.42 ! kjell 381: ')', ')', fund_cb, NULL
! 382: },
! 383: {
1.10 art 384: CCHR('?'), CCHR('?'), fund_del, NULL
1.3 millert 385: },
1.4 millert 386: #ifdef FUND_XMAPS
1.1 deraadt 387: FUND_XMAPS,
1.4 millert 388: #endif /* FUND_XMAPS */
1.1 deraadt 389: }
390: };
391:
1.4 millert 392: static PF fill_sp[] = {
1.28 db 393: fillword /* ' ' */
1.1 deraadt 394: };
1.4 millert 395:
1.3 millert 396: static struct KEYMAPE (1 + IMAPEXT) fillmap = {
1.1 deraadt 397: 1,
1.3 millert 398: 1 + IMAPEXT,
1.1 deraadt 399: rescan,
400: {
1.41 kjell 401: { ' ', ' ', fill_sp, NULL }
1.1 deraadt 402: }
403: };
404:
1.4 millert 405: static PF indent_lf[] = {
1.3 millert 406: newline, /* ^J */
407: rescan, /* ^K */
408: rescan, /* ^L */
1.40 kjell 409: lfindent /* ^M */
1.1 deraadt 410: };
1.4 millert 411:
1.3 millert 412: static struct KEYMAPE (1 + IMAPEXT) indntmap = {
1.1 deraadt 413: 1,
1.3 millert 414: 1 + IMAPEXT,
1.1 deraadt 415: rescan,
416: {
1.3 millert 417: {
1.10 art 418: CCHR('J'), CCHR('M'), indent_lf, NULL
1.28 db 419: }
1.1 deraadt 420: }
421: };
1.4 millert 422:
423: #ifdef NOTAB
424: static PF notab_tab[] = {
1.28 db 425: space_to_tabstop /* ^I */
1.1 deraadt 426: };
1.4 millert 427:
1.3 millert 428: static struct KEYMAPE (1 + IMAPEXT) notabmap = {
1.1 deraadt 429: 1,
1.3 millert 430: 1 + IMAPEXT,
1.1 deraadt 431: rescan,
432: {
1.3 millert 433: {
1.10 art 434: CCHR('I'), CCHR('I'), notab_tab, NULL
1.28 db 435: }
1.1 deraadt 436: }
437: };
1.4 millert 438: #endif /* NOTAB */
1.1 deraadt 439:
1.3 millert 440: static struct KEYMAPE (1 + IMAPEXT) overwmap = {
1.1 deraadt 441: 0,
1.3 millert 442: 1 + IMAPEXT, /* 1 to avoid 0 sized array */
1.1 deraadt 443: rescan,
444: {
445: /* unused dummy entry for VMS C */
1.3 millert 446: {
1.10 art 447: (KCHAR)0, (KCHAR)0, NULL, NULL
1.28 db 448: }
1.1 deraadt 449: }
450: };
451:
452:
1.33 kjell 453: /*
454: * The basic (root) keyboard map
1.35 deraadt 455: */
1.37 deraadt 456: struct maps_s fundamental_mode = { (KEYMAP *)&fundmap, "fundamental" };
1.13 art 457:
1.3 millert 458: /*
459: * give names to the maps, for use by help etc. If the map is to be bindable,
460: * it must also be listed in the function name table below with the same
1.28 db 461: * name. Maps created dynamically currently don't get added here, thus are
1.3 millert 462: * unnamed. Modes are just named keymaps with functions to add/subtract them
463: * from a buffer's list of modes. If you change a mode name, change it in
1.1 deraadt 464: * modes.c also.
465: */
466:
1.37 deraadt 467: static struct maps_s map_table[] = {
1.13 art 468: {(KEYMAP *) &fillmap, "fill",},
469: {(KEYMAP *) &indntmap, "indent",},
1.4 millert 470: #ifdef NOTAB
1.13 art 471: {(KEYMAP *) ¬abmap, "notab",},
1.4 millert 472: #endif /* NOTAB */
1.13 art 473: {(KEYMAP *) &overwmap, "overwrite",},
474: {(KEYMAP *) &metamap, "esc prefix",},
475: {(KEYMAP *) &cXmap, "c-x prefix",},
476: {(KEYMAP *) &cX4map, "c-x 4 prefix",},
1.1 deraadt 477: #ifndef NO_HELP
1.13 art 478: {(KEYMAP *) &helpmap, "help",},
1.1 deraadt 479: #endif
1.28 db 480: {NULL, NULL}
1.1 deraadt 481: };
482:
1.37 deraadt 483: struct maps_s *maps;
1.13 art 484:
485: void
486: maps_init(void)
487: {
1.28 db 488: int i;
1.37 deraadt 489: struct maps_s *mp;
1.13 art 490:
491: maps = &fundamental_mode;
492: for (i = 0; map_table[i].p_name != NULL; i++) {
493: mp = &map_table[i];
494: mp->p_next = maps;
495: maps = mp;
496: }
497: }
1.9 art 498:
1.33 kjell 499: /*
500: * Insert a new (named) keymap at the head of the keymap list.
501: */
1.13 art 502: int
1.19 vincent 503: maps_add(KEYMAP *map, const char *name)
1.13 art 504: {
1.37 deraadt 505: struct maps_s *mp;
1.13 art 506:
507: if ((mp = malloc(sizeof(*mp))) == NULL)
1.28 db 508: return (FALSE);
1.13 art 509:
510: mp->p_name = name;
511: mp->p_map = map;
512: mp->p_next = maps;
513: maps = mp;
514:
1.28 db 515: return (TRUE);
1.1 deraadt 516: }
517:
1.37 deraadt 518: struct maps_s *
1.19 vincent 519: name_mode(const char *name)
1.1 deraadt 520: {
1.37 deraadt 521: struct maps_s *mp;
1.1 deraadt 522:
1.13 art 523: for (mp = maps; mp != NULL; mp = mp->p_next)
1.3 millert 524: if (strcmp(mp->p_name, name) == 0)
1.28 db 525: return (mp);
526: return (NULL);
1.1 deraadt 527: }
528:
1.4 millert 529: KEYMAP *
1.19 vincent 530: name_map(const char *name)
1.1 deraadt 531: {
1.37 deraadt 532: struct maps_s *mp;
533:
1.28 db 534: return ((mp = name_mode(name)) == NULL ? NULL : mp->p_map);
1.1 deraadt 535: }