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