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