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