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