Annotation of src/usr.bin/mg/keymap.c, Revision 1.50
1.50 ! lum 1: /* $OpenBSD: keymap.c,v 1.49 2012/04/12 04:47:59 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:
220: static PF metasp[] = {
1.28 db 221: justone /* space */
1.1 deraadt 222: };
1.4 millert 223:
224: static PF metapct[] = {
1.28 db 225: queryrepl /* % */
1.1 deraadt 226: };
1.4 millert 227:
228: static PF metami[] = {
1.46 lum 229: poptag, /* * */
230: rescan, /* + */
231: rescan, /* , */
1.1 deraadt 232: negative_argument, /* - */
1.46 lum 233: findtag, /* . */
1.3 millert 234: rescan, /* / */
235: digit_argument, /* 0 */
236: digit_argument, /* 1 */
237: digit_argument, /* 2 */
238: digit_argument, /* 3 */
239: digit_argument, /* 4 */
240: digit_argument, /* 5 */
241: digit_argument, /* 6 */
242: digit_argument, /* 7 */
243: digit_argument, /* 8 */
244: digit_argument, /* 9 */
245: rescan, /* : */
246: rescan, /* ; */
247: gotobob, /* < */
248: rescan, /* = */
1.28 db 249: gotoeob /* > */
1.3 millert 250: };
1.4 millert 251:
1.42 kjell 252: static PF metasqf[] = {
253: NULL, /* [ */
1.3 millert 254: delwhite, /* \ */
1.39 kjell 255: rescan, /* ] */
1.45 kjell 256: joinline, /* ^ */
1.3 millert 257: rescan, /* _ */
258: rescan, /* ` */
259: rescan, /* a */
260: backword, /* b */
261: capword, /* c */
262: delfword, /* d */
263: rescan, /* e */
1.28 db 264: forwword /* f */
1.3 millert 265: };
1.4 millert 266:
267: static PF metal[] = {
1.3 millert 268: lowerword, /* l */
1.44 kjell 269: backtoindent, /* m */
1.3 millert 270: rescan, /* n */
271: rescan, /* o */
272: rescan, /* p */
273: fillpara, /* q */
274: backsearch, /* r */
275: forwsearch, /* s */
276: rescan, /* t */
277: upperword, /* u */
278: backpage, /* v */
279: copyregion, /* w */
1.39 kjell 280: extend, /* x */
281: rescan, /* y */
282: rescan, /* z */
283: gotobop, /* { */
1.48 lum 284: piperegion, /* | */
1.39 kjell 285: gotoeop /* } */
1.3 millert 286: };
1.4 millert 287:
1.42 kjell 288: static PF metasqlZ[] = {
289: rescan /* Z */
290: };
291:
1.4 millert 292: static PF metatilde[] = {
1.3 millert 293: notmodified, /* ~ */
1.28 db 294: delbword /* DEL */
1.1 deraadt 295: };
1.4 millert 296:
1.42 kjell 297: struct KEYMAPE (1 + IMAPEXT) metasqlmap = {
298: 1,
299: 1 + IMAPEXT,
300: rescan,
301: {
302: {
303: 'Z', 'Z', metasqlZ, NULL
304: }
305: }
306: };
307:
1.33 kjell 308: struct KEYMAPE (8 + IMAPEXT) metamap = {
1.1 deraadt 309: 8,
1.3 millert 310: 8 + IMAPEXT,
1.1 deraadt 311: rescan,
312: {
1.3 millert 313: {
1.10 art 314: CCHR('G'), CCHR('G'), metacG, NULL
1.3 millert 315: },
316: {
1.10 art 317: CCHR('V'), CCHR('V'), metacV, NULL
1.3 millert 318: },
319: {
1.10 art 320: ' ', ' ', metasp, NULL
1.3 millert 321: },
322: {
1.10 art 323: '%', '%', metapct, NULL
1.3 millert 324: },
325: {
1.46 lum 326: '*', '>', metami, NULL
1.3 millert 327: },
328: {
1.42 kjell 329: '[', 'f', metasqf, (KEYMAP *) &metasqlmap
1.3 millert 330: },
331: {
1.39 kjell 332: 'l', '}', metal, NULL
1.3 millert 333: },
334: {
1.10 art 335: '~', CCHR('?'), metatilde, NULL
1.28 db 336: }
1.1 deraadt 337: }
338: };
339:
1.4 millert 340: static PF fund_at[] = {
1.3 millert 341: setmark, /* ^@ */
342: gotobol, /* ^A */
343: backchar, /* ^B */
1.43 kjell 344: NULL, /* ^C */
1.3 millert 345: forwdel, /* ^D */
346: gotoeol, /* ^E */
347: forwchar, /* ^F */
348: ctrlg, /* ^G */
1.43 kjell 349: };
350:
351: static PF fund_h[] = {
1.6 art 352: NULL, /* ^H */
1.1 deraadt 353: };
1.4 millert 354:
1.43 kjell 355:
1.1 deraadt 356: /* ^I is selfinsert */
1.4 millert 357: static PF fund_CJ[] = {
1.40 kjell 358: lfindent, /* ^J */
1.3 millert 359: killline, /* ^K */
360: reposition, /* ^L */
361: newline, /* ^M */
362: forwline, /* ^N */
363: openline, /* ^O */
364: backline, /* ^P */
365: quote, /* ^Q */
366: backisearch, /* ^R */
367: forwisearch, /* ^S */
368: twiddle, /* ^T */
1.1 deraadt 369: universal_argument, /* ^U */
1.3 millert 370: forwpage, /* ^V */
371: killregion, /* ^W */
1.6 art 372: NULL, /* ^X */
1.3 millert 373: yank, /* ^Y */
1.28 db 374: spawncli /* ^Z */
1.1 deraadt 375: };
1.4 millert 376:
377: static PF fund_esc[] = {
1.6 art 378: NULL, /* esc */
1.4 millert 379: rescan, /* ^\ selfinsert is default on fundamental */
1.3 millert 380: rescan, /* ^] */
381: rescan, /* ^^ */
1.28 db 382: undo /* ^_ */
1.1 deraadt 383: };
1.4 millert 384:
385: static PF fund_del[] = {
1.28 db 386: backdel /* DEL */
1.1 deraadt 387: };
388:
1.42 kjell 389: static PF fund_cb[] = {
390: showmatch /* ) */
391: };
392:
1.1 deraadt 393: #ifndef FUND_XMAPS
394: #define NFUND_XMAPS 0 /* extra map sections after normal ones */
395: #endif
396:
1.43 kjell 397: static struct KEYMAPE (6 + NFUND_XMAPS + IMAPEXT) fundmap = {
398: 6 + NFUND_XMAPS,
399: 6 + NFUND_XMAPS + IMAPEXT,
1.1 deraadt 400: selfinsert,
401: {
1.43 kjell 402: {
403: CCHR('@'), CCHR('G'), fund_at, (KEYMAP *) & ccmap
404: },
1.3 millert 405: {
1.43 kjell 406: CCHR('H'), CCHR('H'), fund_h, (KEYMAP *) & helpmap
1.3 millert 407: },
408: {
409: CCHR('J'), CCHR('Z'), fund_CJ, (KEYMAP *) & cXmap
410: },
411: {
412: CCHR('['), CCHR('_'), fund_esc, (KEYMAP *) & metamap
413: },
414: {
1.42 kjell 415: ')', ')', fund_cb, NULL
416: },
417: {
1.10 art 418: CCHR('?'), CCHR('?'), fund_del, NULL
1.3 millert 419: },
1.4 millert 420: #ifdef FUND_XMAPS
1.1 deraadt 421: FUND_XMAPS,
1.4 millert 422: #endif /* FUND_XMAPS */
1.1 deraadt 423: }
424: };
425:
1.4 millert 426: static PF fill_sp[] = {
1.28 db 427: fillword /* ' ' */
1.1 deraadt 428: };
1.4 millert 429:
1.3 millert 430: static struct KEYMAPE (1 + IMAPEXT) fillmap = {
1.1 deraadt 431: 1,
1.3 millert 432: 1 + IMAPEXT,
1.1 deraadt 433: rescan,
434: {
1.41 kjell 435: { ' ', ' ', fill_sp, NULL }
1.1 deraadt 436: }
437: };
438:
1.4 millert 439: static PF indent_lf[] = {
1.3 millert 440: newline, /* ^J */
441: rescan, /* ^K */
442: rescan, /* ^L */
1.40 kjell 443: lfindent /* ^M */
1.1 deraadt 444: };
1.4 millert 445:
1.3 millert 446: static struct KEYMAPE (1 + IMAPEXT) indntmap = {
1.1 deraadt 447: 1,
1.3 millert 448: 1 + IMAPEXT,
1.1 deraadt 449: rescan,
450: {
1.3 millert 451: {
1.10 art 452: CCHR('J'), CCHR('M'), indent_lf, NULL
1.28 db 453: }
1.1 deraadt 454: }
455: };
1.4 millert 456:
457: #ifdef NOTAB
458: static PF notab_tab[] = {
1.28 db 459: space_to_tabstop /* ^I */
1.1 deraadt 460: };
1.4 millert 461:
1.3 millert 462: static struct KEYMAPE (1 + IMAPEXT) notabmap = {
1.1 deraadt 463: 1,
1.3 millert 464: 1 + IMAPEXT,
1.1 deraadt 465: rescan,
466: {
1.3 millert 467: {
1.10 art 468: CCHR('I'), CCHR('I'), notab_tab, NULL
1.28 db 469: }
1.1 deraadt 470: }
471: };
1.4 millert 472: #endif /* NOTAB */
1.1 deraadt 473:
1.3 millert 474: static struct KEYMAPE (1 + IMAPEXT) overwmap = {
1.1 deraadt 475: 0,
1.3 millert 476: 1 + IMAPEXT, /* 1 to avoid 0 sized array */
1.1 deraadt 477: rescan,
478: {
479: /* unused dummy entry for VMS C */
1.3 millert 480: {
1.10 art 481: (KCHAR)0, (KCHAR)0, NULL, NULL
1.28 db 482: }
1.1 deraadt 483: }
484: };
485:
486:
1.33 kjell 487: /*
488: * The basic (root) keyboard map
1.35 deraadt 489: */
1.37 deraadt 490: struct maps_s fundamental_mode = { (KEYMAP *)&fundmap, "fundamental" };
1.13 art 491:
1.3 millert 492: /*
493: * give names to the maps, for use by help etc. If the map is to be bindable,
494: * it must also be listed in the function name table below with the same
1.28 db 495: * name. Maps created dynamically currently don't get added here, thus are
1.3 millert 496: * unnamed. Modes are just named keymaps with functions to add/subtract them
497: * from a buffer's list of modes. If you change a mode name, change it in
1.1 deraadt 498: * modes.c also.
499: */
500:
1.37 deraadt 501: static struct maps_s map_table[] = {
1.13 art 502: {(KEYMAP *) &fillmap, "fill",},
503: {(KEYMAP *) &indntmap, "indent",},
1.4 millert 504: #ifdef NOTAB
1.13 art 505: {(KEYMAP *) ¬abmap, "notab",},
1.4 millert 506: #endif /* NOTAB */
1.13 art 507: {(KEYMAP *) &overwmap, "overwrite",},
508: {(KEYMAP *) &metamap, "esc prefix",},
509: {(KEYMAP *) &cXmap, "c-x prefix",},
510: {(KEYMAP *) &cX4map, "c-x 4 prefix",},
511: {(KEYMAP *) &helpmap, "help",},
1.28 db 512: {NULL, NULL}
1.1 deraadt 513: };
514:
1.37 deraadt 515: struct maps_s *maps;
1.13 art 516:
517: void
518: maps_init(void)
519: {
1.28 db 520: int i;
1.37 deraadt 521: struct maps_s *mp;
1.13 art 522:
523: maps = &fundamental_mode;
524: for (i = 0; map_table[i].p_name != NULL; i++) {
525: mp = &map_table[i];
526: mp->p_next = maps;
527: maps = mp;
528: }
529: }
1.9 art 530:
1.33 kjell 531: /*
532: * Insert a new (named) keymap at the head of the keymap list.
533: */
1.13 art 534: int
1.19 vincent 535: maps_add(KEYMAP *map, const char *name)
1.13 art 536: {
1.37 deraadt 537: struct maps_s *mp;
1.13 art 538:
539: if ((mp = malloc(sizeof(*mp))) == NULL)
1.28 db 540: return (FALSE);
1.13 art 541:
542: mp->p_name = name;
543: mp->p_map = map;
544: mp->p_next = maps;
545: maps = mp;
546:
1.28 db 547: return (TRUE);
1.1 deraadt 548: }
549:
1.37 deraadt 550: struct maps_s *
1.19 vincent 551: name_mode(const char *name)
1.1 deraadt 552: {
1.37 deraadt 553: struct maps_s *mp;
1.1 deraadt 554:
1.13 art 555: for (mp = maps; mp != NULL; mp = mp->p_next)
1.3 millert 556: if (strcmp(mp->p_name, name) == 0)
1.28 db 557: return (mp);
558: return (NULL);
1.1 deraadt 559: }
560:
1.4 millert 561: KEYMAP *
1.19 vincent 562: name_map(const char *name)
1.1 deraadt 563: {
1.37 deraadt 564: struct maps_s *mp;
565:
1.28 db 566: return ((mp = name_mode(name)) == NULL ? NULL : mp->p_map);
1.1 deraadt 567: }