1 /* $OpenBSD: keymap.c,v 1.14 2001/05/24 10:47:54 art Exp $ */ 2 3 /* 4 * Keyboard maps. This is character set dependent. The terminal specific 5 * parts of building the keymap has been moved to a better place. 6 */ 7 8 #include "def.h" 9 #include "kbd.h" 10 11 /* 12 * initial keymap declarations, deepest first 13 */ 14 15 #ifndef NO_HELP 16 static PF cHcG[] = { 17 ctrlg, /* ^G */ 18 help_help, /* ^H */ 19 }; 20 21 static PF cHa[] = { 22 apropos_command, /* a */ 23 wallchart, /* b */ 24 desckey, /* c */ 25 }; 26 27 static struct KEYMAPE (2 + IMAPEXT) helpmap = { 28 2, 29 2 + IMAPEXT, 30 rescan, 31 { 32 { 33 CCHR('G'), CCHR('H'), cHcG, NULL 34 }, 35 { 36 'a', 'c', cHa, NULL 37 }, 38 } 39 }; 40 #endif /* !NO_HELP */ 41 42 static PF cX4cF[] = { 43 poptofile, /* ^f */ 44 ctrlg, /* ^g */ 45 }; 46 static PF cX4b[] = { 47 poptobuffer, /* b */ 48 rescan, /* c */ 49 rescan, /* d */ 50 rescan, /* e */ 51 poptofile, /* f */ 52 }; 53 static struct KEYMAPE (2 + IMAPEXT) cX4map = { 54 2, 55 2 + IMAPEXT, 56 rescan, 57 { 58 { 59 CCHR('F'), CCHR('G'), cX4cF, NULL 60 }, 61 { 62 'b', 'f', cX4b, NULL 63 }, 64 } 65 }; 66 67 static PF cXcB[] = { 68 listbuffers, /* ^B */ 69 quit, /* ^C */ 70 rescan, /* ^D */ 71 rescan, /* ^E */ 72 filevisit, /* ^F */ 73 ctrlg, /* ^G */ 74 }; 75 76 static PF cXcL[] = { 77 lowerregion, /* ^L */ 78 rescan, /* ^M */ 79 rescan, /* ^N */ 80 deblank, /* ^O */ 81 rescan, /* ^P */ 82 rescan, /* ^Q */ 83 rescan, /* ^R */ 84 filesave, /* ^S */ 85 rescan, /* ^T */ 86 upperregion, /* ^U */ 87 rescan, /* ^V */ 88 filewrite, /* ^W */ 89 swapmark, /* ^X */ 90 }; 91 92 #ifndef NO_MACRO 93 static PF cXlp[] = { 94 definemacro, /* ( */ 95 finishmacro, /* ) */ 96 }; 97 #endif /* !NO_MACRO */ 98 99 static PF cX0[] = { 100 delwind, /* 0 */ 101 onlywind, /* 1 */ 102 splitwind, /* 2 */ 103 rescan, /* 3 */ 104 NULL, /* 4 */ 105 }; 106 107 static PF cXeq[] = { 108 showcpos, /* = */ 109 }; 110 111 static PF cXcar[] = { 112 enlargewind, /* ^ */ 113 rescan, /* _ */ 114 rescan, /* ` */ 115 rescan, /* a */ 116 usebuffer, /* b */ 117 rescan, /* c */ 118 #ifndef NO_DIRED 119 dired, /* d */ 120 #else /* !NO_DIRED */ 121 rescan, /* d */ 122 #endif /* !NO_DIRED */ 123 #ifndef NO_MACRO 124 executemacro, /* e */ 125 #else /* !NO_MACRO */ 126 rescan, /* e */ 127 #endif /* !NO_MACRO */ 128 setfillcol, /* f */ 129 rescan, /* g */ 130 rescan, /* h */ 131 fileinsert, /* i */ 132 rescan, /* j */ 133 killbuffer, /* k */ 134 rescan, /* l */ 135 rescan, /* m */ 136 rescan, /* n */ 137 nextwind, /* o */ 138 rescan, /* p */ 139 rescan, /* q */ 140 rescan, /* r */ 141 savebuffers, /* s */ 142 }; 143 144 #ifndef NO_MACRO 145 static struct KEYMAPE (6 + IMAPEXT) cXmap = { 146 6, 147 6 + IMAPEXT, 148 #else /* !NO_MACRO */ 149 static struct KEYMAPE (5 + IMAPEXT) cXmap = { 150 5, 151 5 + IMAPEXT, 152 #endif /* !NO_MACRO */ 153 rescan, 154 { 155 { 156 CCHR('B'), CCHR('G'), cXcB, NULL 157 }, 158 { 159 CCHR('L'), CCHR('X'), cXcL, NULL 160 }, 161 #ifndef NO_MACRO 162 { 163 '(', ')', cXlp, NULL 164 }, 165 #endif /* !NO_MACRO */ 166 { 167 '0', '4', cX0, (KEYMAP *) & cX4map 168 }, 169 { 170 '=', '=', cXeq, NULL 171 }, 172 { 173 '^', 's', cXcar, NULL 174 }, 175 } 176 }; 177 178 static PF metacG[] = { 179 ctrlg, /* ^G */ 180 }; 181 182 static PF metacV[] = { 183 pagenext, /* ^V */ 184 }; 185 186 static PF metasp[] = { 187 justone, /* space */ 188 }; 189 190 static PF metapct[] = { 191 queryrepl, /* % */ 192 }; 193 194 static PF metami[] = { 195 negative_argument, /* - */ 196 rescan, /* . */ 197 rescan, /* / */ 198 digit_argument, /* 0 */ 199 digit_argument, /* 1 */ 200 digit_argument, /* 2 */ 201 digit_argument, /* 3 */ 202 digit_argument, /* 4 */ 203 digit_argument, /* 5 */ 204 digit_argument, /* 6 */ 205 digit_argument, /* 7 */ 206 digit_argument, /* 8 */ 207 digit_argument, /* 9 */ 208 rescan, /* : */ 209 rescan, /* ; */ 210 gotobob, /* < */ 211 rescan, /* = */ 212 gotoeob, /* > */ 213 }; 214 215 static PF metalb[] = { 216 gotobop, /* [ */ 217 delwhite, /* \ */ 218 gotoeop, /* ] */ 219 rescan, /* ^ */ 220 rescan, /* _ */ 221 rescan, /* ` */ 222 rescan, /* a */ 223 backword, /* b */ 224 capword, /* c */ 225 delfword, /* d */ 226 rescan, /* e */ 227 forwword, /* f */ 228 }; 229 230 static PF metal[] = { 231 lowerword, /* l */ 232 rescan, /* m */ 233 rescan, /* n */ 234 rescan, /* o */ 235 rescan, /* p */ 236 fillpara, /* q */ 237 backsearch, /* r */ 238 forwsearch, /* s */ 239 rescan, /* t */ 240 upperword, /* u */ 241 backpage, /* v */ 242 copyregion, /* w */ 243 extend, /* x */ 244 }; 245 246 static PF metatilde[] = { 247 notmodified, /* ~ */ 248 delbword, /* DEL */ 249 }; 250 251 static struct KEYMAPE (8 + IMAPEXT) metamap = { 252 8, 253 8 + IMAPEXT, 254 rescan, 255 { 256 { 257 CCHR('G'), CCHR('G'), metacG, NULL 258 }, 259 { 260 CCHR('V'), CCHR('V'), metacV, NULL 261 }, 262 { 263 ' ', ' ', metasp, NULL 264 }, 265 { 266 '%', '%', metapct, NULL 267 }, 268 { 269 '-', '>', metami, NULL 270 }, 271 { 272 '[', 'f', metalb, NULL 273 }, 274 { 275 'l', 'x', metal, NULL 276 }, 277 { 278 '~', CCHR('?'), metatilde, NULL 279 }, 280 } 281 }; 282 283 static PF fund_at[] = { 284 setmark, /* ^@ */ 285 gotobol, /* ^A */ 286 backchar, /* ^B */ 287 rescan, /* ^C */ 288 forwdel, /* ^D */ 289 gotoeol, /* ^E */ 290 forwchar, /* ^F */ 291 ctrlg, /* ^G */ 292 #ifndef NO_HELP 293 NULL, /* ^H */ 294 #else /* !NO_HELP */ 295 rescan, /* ^H */ 296 #endif /* !NO_HELP */ 297 }; 298 299 /* ^I is selfinsert */ 300 static PF fund_CJ[] = { 301 indent, /* ^J */ 302 killline, /* ^K */ 303 reposition, /* ^L */ 304 newline, /* ^M */ 305 forwline, /* ^N */ 306 openline, /* ^O */ 307 backline, /* ^P */ 308 quote, /* ^Q */ 309 backisearch, /* ^R */ 310 forwisearch, /* ^S */ 311 twiddle, /* ^T */ 312 universal_argument, /* ^U */ 313 forwpage, /* ^V */ 314 killregion, /* ^W */ 315 NULL, /* ^X */ 316 yank, /* ^Y */ 317 spawncli, /* ^Z */ 318 }; 319 320 static PF fund_esc[] = { 321 NULL, /* esc */ 322 rescan, /* ^\ selfinsert is default on fundamental */ 323 rescan, /* ^] */ 324 rescan, /* ^^ */ 325 rescan, /* ^_ */ 326 }; 327 328 static PF fund_del[] = { 329 backdel, /* DEL */ 330 }; 331 332 #ifndef FUND_XMAPS 333 #define NFUND_XMAPS 0 /* extra map sections after normal ones */ 334 #endif 335 336 static struct KEYMAPE (4 + NFUND_XMAPS + IMAPEXT) fundmap = { 337 4 + NFUND_XMAPS, 338 4 + NFUND_XMAPS + IMAPEXT, 339 selfinsert, 340 { 341 #ifndef NO_HELP 342 { 343 CCHR('@'), CCHR('H'), fund_at, (KEYMAP *) & helpmap 344 }, 345 #else /* !NO_HELP */ 346 { 347 CCHR('@'), CCHR('H'), fund_at, NULL 348 }, 349 #endif /* !NO_HELP */ 350 { 351 CCHR('J'), CCHR('Z'), fund_CJ, (KEYMAP *) & cXmap 352 }, 353 { 354 CCHR('['), CCHR('_'), fund_esc, (KEYMAP *) & metamap 355 }, 356 { 357 CCHR('?'), CCHR('?'), fund_del, NULL 358 }, 359 #ifdef FUND_XMAPS 360 FUND_XMAPS, 361 #endif /* FUND_XMAPS */ 362 } 363 }; 364 365 static PF fill_sp[] = { 366 fillword, /* ' ' */ 367 }; 368 369 static struct KEYMAPE (1 + IMAPEXT) fillmap = { 370 1, 371 1 + IMAPEXT, 372 rescan, 373 { 374 { 375 ' ', ' ', fill_sp, NULL 376 }, 377 } 378 }; 379 380 static PF indent_lf[] = { 381 newline, /* ^J */ 382 rescan, /* ^K */ 383 rescan, /* ^L */ 384 indent, /* ^M */ 385 }; 386 387 static struct KEYMAPE (1 + IMAPEXT) indntmap = { 388 1, 389 1 + IMAPEXT, 390 rescan, 391 { 392 { 393 CCHR('J'), CCHR('M'), indent_lf, NULL 394 }, 395 } 396 }; 397 398 static PF blink_rp[] = { 399 showmatch, /* ) */ 400 }; 401 402 static struct KEYMAPE (1 + IMAPEXT) blinkmap = { 403 1, 404 1 + IMAPEXT, 405 rescan, 406 { 407 { 408 ')', ')', blink_rp, NULL 409 }, 410 } 411 }; 412 413 #ifdef NOTAB 414 static PF notab_tab[] = { 415 space_to_tabstop, /* ^I */ 416 }; 417 418 static struct KEYMAPE (1 + IMAPEXT) notabmap = { 419 1, 420 1 + IMAPEXT, 421 rescan, 422 { 423 { 424 CCHR('I'), CCHR('I'), notab_tab, NULL 425 }, 426 } 427 }; 428 #endif /* NOTAB */ 429 430 static struct KEYMAPE (1 + IMAPEXT) overwmap = { 431 0, 432 1 + IMAPEXT, /* 1 to avoid 0 sized array */ 433 rescan, 434 { 435 /* unused dummy entry for VMS C */ 436 { 437 (KCHAR)0, (KCHAR)0, NULL, NULL 438 }, 439 } 440 }; 441 442 #ifndef NO_DIRED 443 static PF dirednul[] = { 444 setmark, /* ^@ */ 445 gotobol, /* ^A */ 446 backchar, /* ^B */ 447 rescan, /* ^C */ 448 d_del, /* ^D */ 449 gotoeol, /* ^E */ 450 forwchar, /* ^F */ 451 ctrlg, /* ^G */ 452 #ifndef NO_HELP 453 NULL, /* ^H */ 454 #endif /* !NO_HELP */ 455 }; 456 457 static PF diredcl[] = { 458 reposition, /* ^L */ 459 forwline, /* ^M */ 460 forwline, /* ^N */ 461 rescan, /* ^O */ 462 backline, /* ^P */ 463 rescan, /* ^Q */ 464 backisearch, /* ^R */ 465 forwisearch, /* ^S */ 466 rescan, /* ^T */ 467 universal_argument, /* ^U */ 468 forwpage, /* ^V */ 469 rescan, /* ^W */ 470 NULL, /* ^X */ 471 }; 472 473 static PF diredcz[] = { 474 spawncli, /* ^Z */ 475 NULL, /* esc */ 476 rescan, /* ^\ */ 477 rescan, /* ^] */ 478 rescan, /* ^^ */ 479 rescan, /* ^_ */ 480 forwline, /* SP */ 481 }; 482 483 static PF diredc[] = { 484 d_copy, /* c */ 485 d_del, /* d */ 486 d_findfile, /* e */ 487 d_findfile, /* f */ 488 }; 489 490 static PF diredn[] = { 491 forwline, /* n */ 492 d_ffotherwindow, /* o */ 493 backline, /* p */ 494 rescan, /* q */ 495 d_rename, /* r */ 496 rescan, /* s */ 497 rescan, /* t */ 498 d_undel, /* u */ 499 rescan, /* v */ 500 rescan, /* w */ 501 d_expunge, /* x */ 502 }; 503 504 static PF direddl[] = { 505 d_undelbak, /* del */ 506 }; 507 508 #ifndef DIRED_XMAPS 509 #define NDIRED_XMAPS 0 /* number of extra map sections */ 510 #endif /* DIRED_XMAPS */ 511 512 static struct KEYMAPE (6 + NDIRED_XMAPS + IMAPEXT) diredmap = { 513 6 + NDIRED_XMAPS, 514 6 + NDIRED_XMAPS + IMAPEXT, 515 rescan, 516 { 517 #ifndef NO_HELP 518 { 519 CCHR('@'), CCHR('H'), dirednul, (KEYMAP *) & helpmap 520 }, 521 #else /* !NO_HELP */ 522 { 523 CCHR('@'), CCHR('G'), dirednul, NULL 524 }, 525 #endif /* !NO_HELP */ 526 { 527 CCHR('L'), CCHR('X'), diredcl, (KEYMAP *) & cXmap 528 }, 529 { 530 CCHR('Z'), ' ', diredcz, (KEYMAP *) & metamap 531 }, 532 { 533 'c', 'f', diredc, NULL 534 }, 535 { 536 'n', 'x', diredn, NULL 537 }, 538 { 539 CCHR('?'), CCHR('?'), direddl, NULL 540 }, 541 #ifdef DIRED_XMAPS 542 DIRED_XMAPS, /* map sections for dired mode keys */ 543 #endif /* DIRED_XMAPS */ 544 } 545 }; 546 #endif /* !NO_DIRED */ 547 548 MAPS fundamental_mode = { (KEYMAP *)&fundmap, "fundamental", }; 549 550 /* 551 * give names to the maps, for use by help etc. If the map is to be bindable, 552 * it must also be listed in the function name table below with the same 553 * name. Maps created dynamicly currently don't get added here, thus are 554 * unnamed. Modes are just named keymaps with functions to add/subtract them 555 * from a buffer's list of modes. If you change a mode name, change it in 556 * modes.c also. 557 */ 558 559 static MAPS map_table[] = { 560 {(KEYMAP *) &fillmap, "fill",}, 561 {(KEYMAP *) &indntmap, "indent",}, 562 {(KEYMAP *) &blinkmap, "blink",}, 563 #ifdef NOTAB 564 {(KEYMAP *) ¬abmap, "notab",}, 565 #endif /* NOTAB */ 566 {(KEYMAP *) &overwmap, "overwrite",}, 567 {(KEYMAP *) &metamap, "esc prefix",}, 568 {(KEYMAP *) &cXmap, "c-x prefix",}, 569 {(KEYMAP *) &cX4map, "c-x 4 prefix",}, 570 #ifndef NO_HELP 571 {(KEYMAP *) &helpmap, "help",}, 572 #endif 573 #ifndef NO_DIRED 574 {(KEYMAP *) &diredmap, "dired",}, 575 #endif 576 {NULL, NULL}, 577 }; 578 579 MAPS *maps; 580 581 void 582 maps_init(void) 583 { 584 int i; 585 MAPS *mp; 586 587 maps = &fundamental_mode; 588 for (i = 0; map_table[i].p_name != NULL; i++) { 589 mp = &map_table[i]; 590 mp->p_next = maps; 591 maps = mp; 592 } 593 } 594 595 int 596 maps_add(KEYMAP *map, char *name) 597 { 598 MAPS *mp; 599 600 if ((mp = malloc(sizeof(*mp))) == NULL) 601 return FALSE; 602 603 mp->p_name = name; 604 mp->p_map = map; 605 mp->p_next = maps; 606 maps = mp; 607 608 return TRUE; 609 } 610 611 char * 612 map_name(KEYMAP *map) 613 { 614 MAPS *mp; 615 616 for (mp = maps; mp != NULL; mp = mp->p_next) 617 if (mp->p_map == map) 618 return mp->p_name; 619 return NULL; 620 } 621 622 MAPS * 623 name_mode(char *name) 624 { 625 MAPS *mp; 626 627 for (mp = maps; mp != NULL; mp = mp->p_next) 628 if (strcmp(mp->p_name, name) == 0) 629 return mp; 630 return NULL; 631 } 632 633 KEYMAP * 634 name_map(char *name) 635 { 636 MAPS *mp; 637 return (mp = name_mode(name)) == NULL ? NULL : mp->p_map; 638 } 639 640