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