1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Do ":help uganda" in Vim to read copying and usage conditions. 6 * Do ":help credits" in Vim to see a list of people who contributed. 7 * See README.txt for an overview of the Vim source code. 8 */ 9 10 /* 11 * map.c: functions for maps and abbreviations 12 */ 13 14 #include "vim.h" 15 16 /* 17 * List used for abbreviations. 18 */ 19 static mapblock_T *first_abbr = NULL; // first entry in abbrlist 20 21 /* 22 * Each mapping is put in one of the 256 hash lists, to speed up finding it. 23 */ 24 static mapblock_T *(maphash[256]); 25 static int maphash_valid = FALSE; 26 27 /* 28 * Make a hash value for a mapping. 29 * "mode" is the lower 4 bits of the State for the mapping. 30 * "c1" is the first character of the "lhs". 31 * Returns a value between 0 and 255, index in maphash. 32 * Put Normal/Visual mode mappings mostly separately from Insert/Cmdline mode. 33 */ 34 #define MAP_HASH(mode, c1) (((mode) & (NORMAL + VISUAL + SELECTMODE + OP_PENDING + TERMINAL)) ? (c1) : ((c1) ^ 0x80)) 35 36 /* 37 * Get the start of the hashed map list for "state" and first character "c". 38 */ 39 mapblock_T * 40 get_maphash_list(int state, int c) 41 { 42 return maphash[MAP_HASH(state, c)]; 43 } 44 45 /* 46 * Get the buffer-local hashed map list for "state" and first character "c". 47 */ 48 mapblock_T * 49 get_buf_maphash_list(int state, int c) 50 { 51 return curbuf->b_maphash[MAP_HASH(state, c)]; 52 } 53 54 int 55 is_maphash_valid(void) 56 { 57 return maphash_valid; 58 } 59 60 /* 61 * Initialize maphash[] for first use. 62 */ 63 static void 64 validate_maphash(void) 65 { 66 if (!maphash_valid) 67 { 68 vim_memset(maphash, 0, sizeof(maphash)); 69 maphash_valid = TRUE; 70 } 71 } 72 73 /* 74 * Delete one entry from the abbrlist or maphash[]. 75 * "mpp" is a pointer to the m_next field of the PREVIOUS entry! 76 */ 77 static void 78 map_free(mapblock_T **mpp) 79 { 80 mapblock_T *mp; 81 82 mp = *mpp; 83 vim_free(mp->m_keys); 84 vim_free(mp->m_str); 85 vim_free(mp->m_orig_str); 86 *mpp = mp->m_next; 87 vim_free(mp); 88 } 89 90 /* 91 * Return characters to represent the map mode in an allocated string. 92 * Returns NULL when out of memory. 93 */ 94 static char_u * 95 map_mode_to_chars(int mode) 96 { 97 garray_T mapmode; 98 99 ga_init2(&mapmode, 1, 7); 100 101 if ((mode & (INSERT + CMDLINE)) == INSERT + CMDLINE) 102 ga_append(&mapmode, '!'); // :map! 103 else if (mode & INSERT) 104 ga_append(&mapmode, 'i'); // :imap 105 else if (mode & LANGMAP) 106 ga_append(&mapmode, 'l'); // :lmap 107 else if (mode & CMDLINE) 108 ga_append(&mapmode, 'c'); // :cmap 109 else if ((mode & (NORMAL + VISUAL + SELECTMODE + OP_PENDING)) 110 == NORMAL + VISUAL + SELECTMODE + OP_PENDING) 111 ga_append(&mapmode, ' '); // :map 112 else 113 { 114 if (mode & NORMAL) 115 ga_append(&mapmode, 'n'); // :nmap 116 if (mode & OP_PENDING) 117 ga_append(&mapmode, 'o'); // :omap 118 if (mode & TERMINAL) 119 ga_append(&mapmode, 't'); // :tmap 120 if ((mode & (VISUAL + SELECTMODE)) == VISUAL + SELECTMODE) 121 ga_append(&mapmode, 'v'); // :vmap 122 else 123 { 124 if (mode & VISUAL) 125 ga_append(&mapmode, 'x'); // :xmap 126 if (mode & SELECTMODE) 127 ga_append(&mapmode, 's'); // :smap 128 } 129 } 130 131 ga_append(&mapmode, NUL); 132 return (char_u *)mapmode.ga_data; 133 } 134 135 static void 136 showmap( 137 mapblock_T *mp, 138 int local) // TRUE for buffer-local map 139 { 140 int len = 1; 141 char_u *mapchars; 142 143 if (message_filtered(mp->m_keys) && message_filtered(mp->m_str)) 144 return; 145 146 if (msg_didout || msg_silent != 0) 147 { 148 msg_putchar('\n'); 149 if (got_int) // 'q' typed at MORE prompt 150 return; 151 } 152 153 mapchars = map_mode_to_chars(mp->m_mode); 154 if (mapchars != NULL) 155 { 156 msg_puts((char *)mapchars); 157 len = (int)STRLEN(mapchars); 158 vim_free(mapchars); 159 } 160 161 while (++len <= 3) 162 msg_putchar(' '); 163 164 // Display the LHS. Get length of what we write. 165 len = msg_outtrans_special(mp->m_keys, TRUE, 0); 166 do 167 { 168 msg_putchar(' '); // padd with blanks 169 ++len; 170 } while (len < 12); 171 172 if (mp->m_noremap == REMAP_NONE) 173 msg_puts_attr("*", HL_ATTR(HLF_8)); 174 else if (mp->m_noremap == REMAP_SCRIPT) 175 msg_puts_attr("&", HL_ATTR(HLF_8)); 176 else 177 msg_putchar(' '); 178 179 if (local) 180 msg_putchar('@'); 181 else 182 msg_putchar(' '); 183 184 // Use FALSE below if we only want things like <Up> to show up as such on 185 // the rhs, and not M-x etc, TRUE gets both -- webb 186 if (*mp->m_str == NUL) 187 msg_puts_attr("<Nop>", HL_ATTR(HLF_8)); 188 else 189 { 190 // Remove escaping of CSI, because "m_str" is in a format to be used 191 // as typeahead. 192 char_u *s = vim_strsave(mp->m_str); 193 if (s != NULL) 194 { 195 vim_unescape_csi(s); 196 msg_outtrans_special(s, FALSE, 0); 197 vim_free(s); 198 } 199 } 200 #ifdef FEAT_EVAL 201 if (p_verbose > 0) 202 last_set_msg(mp->m_script_ctx); 203 #endif 204 out_flush(); // show one line at a time 205 } 206 207 /* 208 * map[!] : show all key mappings 209 * map[!] {lhs} : show key mapping for {lhs} 210 * map[!] {lhs} {rhs} : set key mapping for {lhs} to {rhs} 211 * noremap[!] {lhs} {rhs} : same, but no remapping for {rhs} 212 * unmap[!] {lhs} : remove key mapping for {lhs} 213 * abbr : show all abbreviations 214 * abbr {lhs} : show abbreviations for {lhs} 215 * abbr {lhs} {rhs} : set abbreviation for {lhs} to {rhs} 216 * noreabbr {lhs} {rhs} : same, but no remapping for {rhs} 217 * unabbr {lhs} : remove abbreviation for {lhs} 218 * 219 * maptype: 0 for :map, 1 for :unmap, 2 for noremap. 220 * 221 * arg is pointer to any arguments. Note: arg cannot be a read-only string, 222 * it will be modified. 223 * 224 * for :map mode is NORMAL + VISUAL + SELECTMODE + OP_PENDING 225 * for :map! mode is INSERT + CMDLINE 226 * for :cmap mode is CMDLINE 227 * for :imap mode is INSERT 228 * for :lmap mode is LANGMAP 229 * for :nmap mode is NORMAL 230 * for :vmap mode is VISUAL + SELECTMODE 231 * for :xmap mode is VISUAL 232 * for :smap mode is SELECTMODE 233 * for :omap mode is OP_PENDING 234 * for :tmap mode is TERMINAL 235 * 236 * for :abbr mode is INSERT + CMDLINE 237 * for :iabbr mode is INSERT 238 * for :cabbr mode is CMDLINE 239 * 240 * Return 0 for success 241 * 1 for invalid arguments 242 * 2 for no match 243 * 4 for out of mem 244 * 5 for entry not unique 245 */ 246 int 247 do_map( 248 int maptype, 249 char_u *arg, 250 int mode, 251 int abbrev) // not a mapping but an abbreviation 252 { 253 char_u *keys; 254 mapblock_T *mp, **mpp; 255 char_u *rhs; 256 char_u *p; 257 int n; 258 int len = 0; // init for GCC 259 int hasarg; 260 int haskey; 261 int do_print; 262 int keyround; 263 char_u *keys_buf = NULL; 264 char_u *alt_keys_buf = NULL; 265 char_u *arg_buf = NULL; 266 int retval = 0; 267 int do_backslash; 268 mapblock_T **abbr_table; 269 mapblock_T **map_table; 270 int unique = FALSE; 271 int nowait = FALSE; 272 int silent = FALSE; 273 int special = FALSE; 274 #ifdef FEAT_EVAL 275 int expr = FALSE; 276 #endif 277 int did_simplify = FALSE; 278 int noremap; 279 char_u *orig_rhs; 280 281 keys = arg; 282 map_table = maphash; 283 abbr_table = &first_abbr; 284 285 // For ":noremap" don't remap, otherwise do remap. 286 if (maptype == 2) 287 noremap = REMAP_NONE; 288 else 289 noremap = REMAP_YES; 290 291 // Accept <buffer>, <nowait>, <silent>, <expr> <script> and <unique> in 292 // any order. 293 for (;;) 294 { 295 // Check for "<buffer>": mapping local to buffer. 296 if (STRNCMP(keys, "<buffer>", 8) == 0) 297 { 298 keys = skipwhite(keys + 8); 299 map_table = curbuf->b_maphash; 300 abbr_table = &curbuf->b_first_abbr; 301 continue; 302 } 303 304 // Check for "<nowait>": don't wait for more characters. 305 if (STRNCMP(keys, "<nowait>", 8) == 0) 306 { 307 keys = skipwhite(keys + 8); 308 nowait = TRUE; 309 continue; 310 } 311 312 // Check for "<silent>": don't echo commands. 313 if (STRNCMP(keys, "<silent>", 8) == 0) 314 { 315 keys = skipwhite(keys + 8); 316 silent = TRUE; 317 continue; 318 } 319 320 // Check for "<special>": accept special keys in <> 321 if (STRNCMP(keys, "<special>", 9) == 0) 322 { 323 keys = skipwhite(keys + 9); 324 special = TRUE; 325 continue; 326 } 327 328 #ifdef FEAT_EVAL 329 // Check for "<script>": remap script-local mappings only 330 if (STRNCMP(keys, "<script>", 8) == 0) 331 { 332 keys = skipwhite(keys + 8); 333 noremap = REMAP_SCRIPT; 334 continue; 335 } 336 337 // Check for "<expr>": {rhs} is an expression. 338 if (STRNCMP(keys, "<expr>", 6) == 0) 339 { 340 keys = skipwhite(keys + 6); 341 expr = TRUE; 342 continue; 343 } 344 #endif 345 // Check for "<unique>": don't overwrite an existing mapping. 346 if (STRNCMP(keys, "<unique>", 8) == 0) 347 { 348 keys = skipwhite(keys + 8); 349 unique = TRUE; 350 continue; 351 } 352 break; 353 } 354 355 validate_maphash(); 356 357 // Find end of keys and skip CTRL-Vs (and backslashes) in it. 358 // Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'. 359 // with :unmap white space is included in the keys, no argument possible. 360 p = keys; 361 do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL); 362 while (*p && (maptype == 1 || !VIM_ISWHITE(*p))) 363 { 364 if ((p[0] == Ctrl_V || (do_backslash && p[0] == '\\')) && 365 p[1] != NUL) 366 ++p; // skip CTRL-V or backslash 367 ++p; 368 } 369 if (*p != NUL) 370 *p++ = NUL; 371 372 p = skipwhite(p); 373 rhs = p; 374 hasarg = (*rhs != NUL); 375 haskey = (*keys != NUL); 376 do_print = !haskey || (maptype != 1 && !hasarg); 377 378 // check for :unmap without argument 379 if (maptype == 1 && !haskey) 380 { 381 retval = 1; 382 goto theend; 383 } 384 385 // If mapping has been given as ^V<C_UP> say, then replace the term codes 386 // with the appropriate two bytes. If it is a shifted special key, unshift 387 // it too, giving another two bytes. 388 // replace_termcodes() may move the result to allocated memory, which 389 // needs to be freed later (*keys_buf and *arg_buf). 390 // replace_termcodes() also removes CTRL-Vs and sometimes backslashes. 391 // If something like <C-H> is simplified to 0x08 then mark it as simplified 392 // and also add a n entry with a modifier, which will work when 393 // modifyOtherKeys is working. 394 if (haskey) 395 { 396 char_u *new_keys; 397 int flags = REPTERM_FROM_PART | REPTERM_DO_LT; 398 399 if (special) 400 flags |= REPTERM_SPECIAL; 401 new_keys = replace_termcodes(keys, &keys_buf, flags, &did_simplify); 402 if (did_simplify) 403 (void)replace_termcodes(keys, &alt_keys_buf, 404 flags | REPTERM_NO_SIMPLIFY, NULL); 405 keys = new_keys; 406 } 407 orig_rhs = rhs; 408 if (hasarg) 409 { 410 if (STRICMP(rhs, "<nop>") == 0) // "<Nop>" means nothing 411 rhs = (char_u *)""; 412 else 413 rhs = replace_termcodes(rhs, &arg_buf, 414 REPTERM_DO_LT | (special ? REPTERM_SPECIAL : 0), NULL); 415 } 416 417 /* 418 * The following is done twice if we have two versions of keys: 419 * "alt_keys_buf" is not NULL. 420 */ 421 for (keyround = 1; keyround <= 2; ++keyround) 422 { 423 int did_it = FALSE; 424 int did_local = FALSE; 425 int round; 426 int hash; 427 int new_hash; 428 429 if (keyround == 2) 430 { 431 if (alt_keys_buf == NULL) 432 break; 433 keys = alt_keys_buf; 434 } 435 else if (alt_keys_buf != NULL && do_print) 436 // when printing always use the not-simplified map 437 keys = alt_keys_buf; 438 439 // check arguments and translate function keys 440 if (haskey) 441 { 442 len = (int)STRLEN(keys); 443 if (len > MAXMAPLEN) // maximum length of MAXMAPLEN chars 444 { 445 retval = 1; 446 goto theend; 447 } 448 449 if (abbrev && maptype != 1) 450 { 451 // If an abbreviation ends in a keyword character, the 452 // rest must be all keyword-char or all non-keyword-char. 453 // Otherwise we won't be able to find the start of it in a 454 // vi-compatible way. 455 if (has_mbyte) 456 { 457 int first, last; 458 int same = -1; 459 460 first = vim_iswordp(keys); 461 last = first; 462 p = keys + (*mb_ptr2len)(keys); 463 n = 1; 464 while (p < keys + len) 465 { 466 ++n; // nr of (multi-byte) chars 467 last = vim_iswordp(p); // type of last char 468 if (same == -1 && last != first) 469 same = n - 1; // count of same char type 470 p += (*mb_ptr2len)(p); 471 } 472 if (last && n > 2 && same >= 0 && same < n - 1) 473 { 474 retval = 1; 475 goto theend; 476 } 477 } 478 else if (vim_iswordc(keys[len - 1])) 479 // ends in keyword char 480 for (n = 0; n < len - 2; ++n) 481 if (vim_iswordc(keys[n]) != vim_iswordc(keys[len - 2])) 482 { 483 retval = 1; 484 goto theend; 485 } 486 // An abbreviation cannot contain white space. 487 for (n = 0; n < len; ++n) 488 if (VIM_ISWHITE(keys[n])) 489 { 490 retval = 1; 491 goto theend; 492 } 493 } 494 } 495 496 if (haskey && hasarg && abbrev) // if we will add an abbreviation 497 no_abbr = FALSE; // reset flag that indicates there are 498 // no abbreviations 499 500 if (do_print) 501 msg_start(); 502 503 // Check if a new local mapping wasn't already defined globally. 504 if (map_table == curbuf->b_maphash && haskey && hasarg && maptype != 1) 505 { 506 // need to loop over all global hash lists 507 for (hash = 0; hash < 256 && !got_int; ++hash) 508 { 509 if (abbrev) 510 { 511 if (hash != 0) // there is only one abbreviation list 512 break; 513 mp = first_abbr; 514 } 515 else 516 mp = maphash[hash]; 517 for ( ; mp != NULL && !got_int; mp = mp->m_next) 518 { 519 // check entries with the same mode 520 if ((mp->m_mode & mode) != 0 521 && mp->m_keylen == len 522 && unique 523 && STRNCMP(mp->m_keys, keys, (size_t)len) == 0) 524 { 525 if (abbrev) 526 semsg(_( 527 "E224: global abbreviation already exists for %s"), 528 mp->m_keys); 529 else 530 semsg(_( 531 "E225: global mapping already exists for %s"), 532 mp->m_keys); 533 retval = 5; 534 goto theend; 535 } 536 } 537 } 538 } 539 540 // When listing global mappings, also list buffer-local ones here. 541 if (map_table != curbuf->b_maphash && !hasarg && maptype != 1) 542 { 543 // need to loop over all global hash lists 544 for (hash = 0; hash < 256 && !got_int; ++hash) 545 { 546 if (abbrev) 547 { 548 if (hash != 0) // there is only one abbreviation list 549 break; 550 mp = curbuf->b_first_abbr; 551 } 552 else 553 mp = curbuf->b_maphash[hash]; 554 for ( ; mp != NULL && !got_int; mp = mp->m_next) 555 { 556 // check entries with the same mode 557 if (!mp->m_simplified && (mp->m_mode & mode) != 0) 558 { 559 if (!haskey) // show all entries 560 { 561 showmap(mp, TRUE); 562 did_local = TRUE; 563 } 564 else 565 { 566 n = mp->m_keylen; 567 if (STRNCMP(mp->m_keys, keys, 568 (size_t)(n < len ? n : len)) == 0) 569 { 570 showmap(mp, TRUE); 571 did_local = TRUE; 572 } 573 } 574 } 575 } 576 } 577 } 578 579 // Find an entry in the maphash[] list that matches. 580 // For :unmap we may loop two times: once to try to unmap an entry with 581 // a matching 'from' part, a second time, if the first fails, to unmap 582 // an entry with a matching 'to' part. This was done to allow ":ab foo 583 // bar" to be unmapped by typing ":unab foo", where "foo" will be 584 // replaced by "bar" because of the abbreviation. 585 for (round = 0; (round == 0 || maptype == 1) && round <= 1 586 && !did_it && !got_int; ++round) 587 { 588 // need to loop over all hash lists 589 for (hash = 0; hash < 256 && !got_int; ++hash) 590 { 591 if (abbrev) 592 { 593 if (hash > 0) // there is only one abbreviation list 594 break; 595 mpp = abbr_table; 596 } 597 else 598 mpp = &(map_table[hash]); 599 for (mp = *mpp; mp != NULL && !got_int; mp = *mpp) 600 { 601 602 if ((mp->m_mode & mode) == 0) 603 { 604 // skip entries with wrong mode 605 mpp = &(mp->m_next); 606 continue; 607 } 608 if (!haskey) // show all entries 609 { 610 if (!mp->m_simplified) 611 { 612 showmap(mp, map_table != maphash); 613 did_it = TRUE; 614 } 615 } 616 else // do we have a match? 617 { 618 if (round) // second round: Try unmap "rhs" string 619 { 620 n = (int)STRLEN(mp->m_str); 621 p = mp->m_str; 622 } 623 else 624 { 625 n = mp->m_keylen; 626 p = mp->m_keys; 627 } 628 if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0) 629 { 630 if (maptype == 1) 631 { 632 // Delete entry. 633 // Only accept a full match. For abbreviations 634 // we ignore trailing space when matching with 635 // the "lhs", since an abbreviation can't have 636 // trailing space. 637 if (n != len && (!abbrev || round || n > len 638 || *skipwhite(keys + n) != NUL)) 639 { 640 mpp = &(mp->m_next); 641 continue; 642 } 643 // We reset the indicated mode bits. If nothing 644 // is left the entry is deleted below. 645 mp->m_mode &= ~mode; 646 did_it = TRUE; // remember we did something 647 } 648 else if (!hasarg) // show matching entry 649 { 650 if (!mp->m_simplified) 651 { 652 showmap(mp, map_table != maphash); 653 did_it = TRUE; 654 } 655 } 656 else if (n != len) // new entry is ambiguous 657 { 658 mpp = &(mp->m_next); 659 continue; 660 } 661 else if (unique) 662 { 663 if (abbrev) 664 semsg(_( 665 "E226: abbreviation already exists for %s"), 666 p); 667 else 668 semsg(_( 669 "E227: mapping already exists for %s"), 670 p); 671 retval = 5; 672 goto theend; 673 } 674 else 675 { 676 // new rhs for existing entry 677 mp->m_mode &= ~mode; // remove mode bits 678 if (mp->m_mode == 0 && !did_it) // reuse entry 679 { 680 char_u *newstr = vim_strsave(rhs); 681 682 if (newstr == NULL) 683 { 684 retval = 4; // no mem 685 goto theend; 686 } 687 vim_free(mp->m_str); 688 mp->m_str = newstr; 689 vim_free(mp->m_orig_str); 690 mp->m_orig_str = vim_strsave(orig_rhs); 691 mp->m_noremap = noremap; 692 mp->m_nowait = nowait; 693 mp->m_silent = silent; 694 mp->m_mode = mode; 695 mp->m_simplified = 696 did_simplify && keyround == 1; 697 #ifdef FEAT_EVAL 698 mp->m_expr = expr; 699 mp->m_script_ctx = current_sctx; 700 mp->m_script_ctx.sc_lnum += SOURCING_LNUM; 701 #endif 702 did_it = TRUE; 703 } 704 } 705 if (mp->m_mode == 0) // entry can be deleted 706 { 707 map_free(mpp); 708 continue; // continue with *mpp 709 } 710 711 // May need to put this entry into another hash 712 // list. 713 new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]); 714 if (!abbrev && new_hash != hash) 715 { 716 *mpp = mp->m_next; 717 mp->m_next = map_table[new_hash]; 718 map_table[new_hash] = mp; 719 720 continue; // continue with *mpp 721 } 722 } 723 } 724 mpp = &(mp->m_next); 725 } 726 } 727 } 728 729 if (maptype == 1) 730 { 731 // delete entry 732 if (!did_it) 733 retval = 2; // no match 734 else if (*keys == Ctrl_C) 735 { 736 // If CTRL-C has been unmapped, reuse it for Interrupting. 737 if (map_table == curbuf->b_maphash) 738 curbuf->b_mapped_ctrl_c &= ~mode; 739 else 740 mapped_ctrl_c &= ~mode; 741 } 742 continue; 743 } 744 745 if (!haskey || !hasarg) 746 { 747 // print entries 748 if (!did_it && !did_local) 749 { 750 if (abbrev) 751 msg(_("No abbreviation found")); 752 else 753 msg(_("No mapping found")); 754 } 755 goto theend; // listing finished 756 } 757 758 if (did_it) 759 continue; // have added the new entry already 760 761 // Get here when adding a new entry to the maphash[] list or abbrlist. 762 mp = ALLOC_ONE(mapblock_T); 763 if (mp == NULL) 764 { 765 retval = 4; // no mem 766 goto theend; 767 } 768 769 // If CTRL-C has been mapped, don't always use it for Interrupting. 770 if (*keys == Ctrl_C) 771 { 772 if (map_table == curbuf->b_maphash) 773 curbuf->b_mapped_ctrl_c |= mode; 774 else 775 mapped_ctrl_c |= mode; 776 } 777 778 mp->m_keys = vim_strsave(keys); 779 mp->m_str = vim_strsave(rhs); 780 mp->m_orig_str = vim_strsave(orig_rhs); 781 if (mp->m_keys == NULL || mp->m_str == NULL) 782 { 783 vim_free(mp->m_keys); 784 vim_free(mp->m_str); 785 vim_free(mp->m_orig_str); 786 vim_free(mp); 787 retval = 4; // no mem 788 goto theend; 789 } 790 mp->m_keylen = (int)STRLEN(mp->m_keys); 791 mp->m_noremap = noremap; 792 mp->m_nowait = nowait; 793 mp->m_silent = silent; 794 mp->m_mode = mode; 795 mp->m_simplified = did_simplify && keyround == 1; 796 #ifdef FEAT_EVAL 797 mp->m_expr = expr; 798 mp->m_script_ctx = current_sctx; 799 mp->m_script_ctx.sc_lnum += SOURCING_LNUM; 800 #endif 801 802 // add the new entry in front of the abbrlist or maphash[] list 803 if (abbrev) 804 { 805 mp->m_next = *abbr_table; 806 *abbr_table = mp; 807 } 808 else 809 { 810 n = MAP_HASH(mp->m_mode, mp->m_keys[0]); 811 mp->m_next = map_table[n]; 812 map_table[n] = mp; 813 } 814 } 815 816 theend: 817 vim_free(keys_buf); 818 vim_free(alt_keys_buf); 819 vim_free(arg_buf); 820 return retval; 821 } 822 823 /* 824 * Get the mapping mode from the command name. 825 */ 826 static int 827 get_map_mode(char_u **cmdp, int forceit) 828 { 829 char_u *p; 830 int modec; 831 int mode; 832 833 p = *cmdp; 834 modec = *p++; 835 if (modec == 'i') 836 mode = INSERT; // :imap 837 else if (modec == 'l') 838 mode = LANGMAP; // :lmap 839 else if (modec == 'c') 840 mode = CMDLINE; // :cmap 841 else if (modec == 'n' && *p != 'o') // avoid :noremap 842 mode = NORMAL; // :nmap 843 else if (modec == 'v') 844 mode = VISUAL + SELECTMODE; // :vmap 845 else if (modec == 'x') 846 mode = VISUAL; // :xmap 847 else if (modec == 's') 848 mode = SELECTMODE; // :smap 849 else if (modec == 'o') 850 mode = OP_PENDING; // :omap 851 else if (modec == 't') 852 mode = TERMINAL; // :tmap 853 else 854 { 855 --p; 856 if (forceit) 857 mode = INSERT + CMDLINE; // :map ! 858 else 859 mode = VISUAL + SELECTMODE + NORMAL + OP_PENDING;// :map 860 } 861 862 *cmdp = p; 863 return mode; 864 } 865 866 /* 867 * Clear all mappings or abbreviations. 868 * 'abbr' should be FALSE for mappings, TRUE for abbreviations. 869 */ 870 static void 871 map_clear( 872 char_u *cmdp, 873 char_u *arg UNUSED, 874 int forceit, 875 int abbr) 876 { 877 int mode; 878 int local; 879 880 local = (STRCMP(arg, "<buffer>") == 0); 881 if (!local && *arg != NUL) 882 { 883 emsg(_(e_invarg)); 884 return; 885 } 886 887 mode = get_map_mode(&cmdp, forceit); 888 map_clear_int(curbuf, mode, local, abbr); 889 } 890 891 /* 892 * Clear all mappings in "mode". 893 */ 894 void 895 map_clear_int( 896 buf_T *buf, // buffer for local mappings 897 int mode, // mode in which to delete 898 int local, // TRUE for buffer-local mappings 899 int abbr) // TRUE for abbreviations 900 { 901 mapblock_T *mp, **mpp; 902 int hash; 903 int new_hash; 904 905 validate_maphash(); 906 907 for (hash = 0; hash < 256; ++hash) 908 { 909 if (abbr) 910 { 911 if (hash > 0) // there is only one abbrlist 912 break; 913 if (local) 914 mpp = &buf->b_first_abbr; 915 else 916 mpp = &first_abbr; 917 } 918 else 919 { 920 if (local) 921 mpp = &buf->b_maphash[hash]; 922 else 923 mpp = &maphash[hash]; 924 } 925 while (*mpp != NULL) 926 { 927 mp = *mpp; 928 if (mp->m_mode & mode) 929 { 930 mp->m_mode &= ~mode; 931 if (mp->m_mode == 0) // entry can be deleted 932 { 933 map_free(mpp); 934 continue; 935 } 936 // May need to put this entry into another hash list. 937 new_hash = MAP_HASH(mp->m_mode, mp->m_keys[0]); 938 if (!abbr && new_hash != hash) 939 { 940 *mpp = mp->m_next; 941 if (local) 942 { 943 mp->m_next = buf->b_maphash[new_hash]; 944 buf->b_maphash[new_hash] = mp; 945 } 946 else 947 { 948 mp->m_next = maphash[new_hash]; 949 maphash[new_hash] = mp; 950 } 951 continue; // continue with *mpp 952 } 953 } 954 mpp = &(mp->m_next); 955 } 956 } 957 } 958 959 #if defined(FEAT_EVAL) || defined(PROTO) 960 int 961 mode_str2flags(char_u *modechars) 962 { 963 int mode = 0; 964 965 if (vim_strchr(modechars, 'n') != NULL) 966 mode |= NORMAL; 967 if (vim_strchr(modechars, 'v') != NULL) 968 mode |= VISUAL + SELECTMODE; 969 if (vim_strchr(modechars, 'x') != NULL) 970 mode |= VISUAL; 971 if (vim_strchr(modechars, 's') != NULL) 972 mode |= SELECTMODE; 973 if (vim_strchr(modechars, 'o') != NULL) 974 mode |= OP_PENDING; 975 if (vim_strchr(modechars, 'i') != NULL) 976 mode |= INSERT; 977 if (vim_strchr(modechars, 'l') != NULL) 978 mode |= LANGMAP; 979 if (vim_strchr(modechars, 'c') != NULL) 980 mode |= CMDLINE; 981 982 return mode; 983 } 984 985 /* 986 * Return TRUE if a map exists that has "str" in the rhs for mode "modechars". 987 * Recognize termcap codes in "str". 988 * Also checks mappings local to the current buffer. 989 */ 990 int 991 map_to_exists(char_u *str, char_u *modechars, int abbr) 992 { 993 char_u *rhs; 994 char_u *buf; 995 int retval; 996 997 rhs = replace_termcodes(str, &buf, REPTERM_DO_LT, NULL); 998 999 retval = map_to_exists_mode(rhs, mode_str2flags(modechars), abbr); 1000 vim_free(buf); 1001 1002 return retval; 1003 } 1004 #endif 1005 1006 /* 1007 * Return TRUE if a map exists that has "str" in the rhs for mode "mode". 1008 * Also checks mappings local to the current buffer. 1009 */ 1010 int 1011 map_to_exists_mode(char_u *rhs, int mode, int abbr) 1012 { 1013 mapblock_T *mp; 1014 int hash; 1015 int exp_buffer = FALSE; 1016 1017 validate_maphash(); 1018 1019 // Do it twice: once for global maps and once for local maps. 1020 for (;;) 1021 { 1022 for (hash = 0; hash < 256; ++hash) 1023 { 1024 if (abbr) 1025 { 1026 if (hash > 0) // there is only one abbr list 1027 break; 1028 if (exp_buffer) 1029 mp = curbuf->b_first_abbr; 1030 else 1031 mp = first_abbr; 1032 } 1033 else if (exp_buffer) 1034 mp = curbuf->b_maphash[hash]; 1035 else 1036 mp = maphash[hash]; 1037 for (; mp; mp = mp->m_next) 1038 { 1039 if ((mp->m_mode & mode) 1040 && strstr((char *)mp->m_str, (char *)rhs) != NULL) 1041 return TRUE; 1042 } 1043 } 1044 if (exp_buffer) 1045 break; 1046 exp_buffer = TRUE; 1047 } 1048 1049 return FALSE; 1050 } 1051 1052 /* 1053 * Used below when expanding mapping/abbreviation names. 1054 */ 1055 static int expand_mapmodes = 0; 1056 static int expand_isabbrev = 0; 1057 static int expand_buffer = FALSE; 1058 1059 /* 1060 * Translate an internal mapping/abbreviation representation into the 1061 * corresponding external one recognized by :map/:abbrev commands. 1062 * Respects the current B/k/< settings of 'cpoption'. 1063 * 1064 * This function is called when expanding mappings/abbreviations on the 1065 * command-line. 1066 * 1067 * It uses a growarray to build the translation string since the latter can be 1068 * wider than the original description. The caller has to free the string 1069 * afterwards. 1070 * 1071 * Returns NULL when there is a problem. 1072 */ 1073 static char_u * 1074 translate_mapping(char_u *str) 1075 { 1076 garray_T ga; 1077 int c; 1078 int modifiers; 1079 int cpo_bslash; 1080 int cpo_special; 1081 1082 ga_init(&ga); 1083 ga.ga_itemsize = 1; 1084 ga.ga_growsize = 40; 1085 1086 cpo_bslash = (vim_strchr(p_cpo, CPO_BSLASH) != NULL); 1087 cpo_special = (vim_strchr(p_cpo, CPO_SPECI) != NULL); 1088 1089 for (; *str; ++str) 1090 { 1091 c = *str; 1092 if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) 1093 { 1094 modifiers = 0; 1095 if (str[1] == KS_MODIFIER) 1096 { 1097 str++; 1098 modifiers = *++str; 1099 c = *++str; 1100 } 1101 if (c == K_SPECIAL && str[1] != NUL && str[2] != NUL) 1102 { 1103 if (cpo_special) 1104 { 1105 ga_clear(&ga); 1106 return NULL; 1107 } 1108 c = TO_SPECIAL(str[1], str[2]); 1109 if (c == K_ZERO) // display <Nul> as ^@ 1110 c = NUL; 1111 str += 2; 1112 } 1113 if (IS_SPECIAL(c) || modifiers) // special key 1114 { 1115 if (cpo_special) 1116 { 1117 ga_clear(&ga); 1118 return NULL; 1119 } 1120 ga_concat(&ga, get_special_key_name(c, modifiers)); 1121 continue; // for (str) 1122 } 1123 } 1124 if (c == ' ' || c == '\t' || c == Ctrl_J || c == Ctrl_V 1125 || (c == '<' && !cpo_special) || (c == '\\' && !cpo_bslash)) 1126 ga_append(&ga, cpo_bslash ? Ctrl_V : '\\'); 1127 if (c) 1128 ga_append(&ga, c); 1129 } 1130 ga_append(&ga, NUL); 1131 return (char_u *)(ga.ga_data); 1132 } 1133 1134 /* 1135 * Work out what to complete when doing command line completion of mapping 1136 * or abbreviation names. 1137 */ 1138 char_u * 1139 set_context_in_map_cmd( 1140 expand_T *xp, 1141 char_u *cmd, 1142 char_u *arg, 1143 int forceit, // TRUE if '!' given 1144 int isabbrev, // TRUE if abbreviation 1145 int isunmap, // TRUE if unmap/unabbrev command 1146 cmdidx_T cmdidx) 1147 { 1148 if (forceit && cmdidx != CMD_map && cmdidx != CMD_unmap) 1149 xp->xp_context = EXPAND_NOTHING; 1150 else 1151 { 1152 if (isunmap) 1153 expand_mapmodes = get_map_mode(&cmd, forceit || isabbrev); 1154 else 1155 { 1156 expand_mapmodes = INSERT + CMDLINE; 1157 if (!isabbrev) 1158 expand_mapmodes += VISUAL + SELECTMODE + NORMAL + OP_PENDING; 1159 } 1160 expand_isabbrev = isabbrev; 1161 xp->xp_context = EXPAND_MAPPINGS; 1162 expand_buffer = FALSE; 1163 for (;;) 1164 { 1165 if (STRNCMP(arg, "<buffer>", 8) == 0) 1166 { 1167 expand_buffer = TRUE; 1168 arg = skipwhite(arg + 8); 1169 continue; 1170 } 1171 if (STRNCMP(arg, "<unique>", 8) == 0) 1172 { 1173 arg = skipwhite(arg + 8); 1174 continue; 1175 } 1176 if (STRNCMP(arg, "<nowait>", 8) == 0) 1177 { 1178 arg = skipwhite(arg + 8); 1179 continue; 1180 } 1181 if (STRNCMP(arg, "<silent>", 8) == 0) 1182 { 1183 arg = skipwhite(arg + 8); 1184 continue; 1185 } 1186 if (STRNCMP(arg, "<special>", 9) == 0) 1187 { 1188 arg = skipwhite(arg + 9); 1189 continue; 1190 } 1191 #ifdef FEAT_EVAL 1192 if (STRNCMP(arg, "<script>", 8) == 0) 1193 { 1194 arg = skipwhite(arg + 8); 1195 continue; 1196 } 1197 if (STRNCMP(arg, "<expr>", 6) == 0) 1198 { 1199 arg = skipwhite(arg + 6); 1200 continue; 1201 } 1202 #endif 1203 break; 1204 } 1205 xp->xp_pattern = arg; 1206 } 1207 1208 return NULL; 1209 } 1210 1211 /* 1212 * Find all mapping/abbreviation names that match regexp "regmatch"'. 1213 * For command line expansion of ":[un]map" and ":[un]abbrev" in all modes. 1214 * Return OK if matches found, FAIL otherwise. 1215 */ 1216 int 1217 ExpandMappings( 1218 regmatch_T *regmatch, 1219 int *num_file, 1220 char_u ***file) 1221 { 1222 mapblock_T *mp; 1223 int hash; 1224 int count; 1225 int round; 1226 char_u *p; 1227 int i; 1228 1229 validate_maphash(); 1230 1231 *num_file = 0; // return values in case of FAIL 1232 *file = NULL; 1233 1234 // round == 1: Count the matches. 1235 // round == 2: Build the array to keep the matches. 1236 for (round = 1; round <= 2; ++round) 1237 { 1238 count = 0; 1239 1240 for (i = 0; i < 7; ++i) 1241 { 1242 if (i == 0) 1243 p = (char_u *)"<silent>"; 1244 else if (i == 1) 1245 p = (char_u *)"<unique>"; 1246 #ifdef FEAT_EVAL 1247 else if (i == 2) 1248 p = (char_u *)"<script>"; 1249 else if (i == 3) 1250 p = (char_u *)"<expr>"; 1251 #endif 1252 else if (i == 4 && !expand_buffer) 1253 p = (char_u *)"<buffer>"; 1254 else if (i == 5) 1255 p = (char_u *)"<nowait>"; 1256 else if (i == 6) 1257 p = (char_u *)"<special>"; 1258 else 1259 continue; 1260 1261 if (vim_regexec(regmatch, p, (colnr_T)0)) 1262 { 1263 if (round == 1) 1264 ++count; 1265 else 1266 (*file)[count++] = vim_strsave(p); 1267 } 1268 } 1269 1270 for (hash = 0; hash < 256; ++hash) 1271 { 1272 if (expand_isabbrev) 1273 { 1274 if (hash > 0) // only one abbrev list 1275 break; // for (hash) 1276 mp = first_abbr; 1277 } 1278 else if (expand_buffer) 1279 mp = curbuf->b_maphash[hash]; 1280 else 1281 mp = maphash[hash]; 1282 for (; mp; mp = mp->m_next) 1283 { 1284 if (mp->m_mode & expand_mapmodes) 1285 { 1286 p = translate_mapping(mp->m_keys); 1287 if (p != NULL && vim_regexec(regmatch, p, (colnr_T)0)) 1288 { 1289 if (round == 1) 1290 ++count; 1291 else 1292 { 1293 (*file)[count++] = p; 1294 p = NULL; 1295 } 1296 } 1297 vim_free(p); 1298 } 1299 } // for (mp) 1300 } // for (hash) 1301 1302 if (count == 0) // no match found 1303 break; // for (round) 1304 1305 if (round == 1) 1306 { 1307 *file = ALLOC_MULT(char_u *, count); 1308 if (*file == NULL) 1309 return FAIL; 1310 } 1311 } // for (round) 1312 1313 if (count > 1) 1314 { 1315 char_u **ptr1; 1316 char_u **ptr2; 1317 char_u **ptr3; 1318 1319 // Sort the matches 1320 sort_strings(*file, count); 1321 1322 // Remove multiple entries 1323 ptr1 = *file; 1324 ptr2 = ptr1 + 1; 1325 ptr3 = ptr1 + count; 1326 1327 while (ptr2 < ptr3) 1328 { 1329 if (STRCMP(*ptr1, *ptr2)) 1330 *++ptr1 = *ptr2++; 1331 else 1332 { 1333 vim_free(*ptr2++); 1334 count--; 1335 } 1336 } 1337 } 1338 1339 *num_file = count; 1340 return (count == 0 ? FAIL : OK); 1341 } 1342 1343 /* 1344 * Check for an abbreviation. 1345 * Cursor is at ptr[col]. 1346 * When inserting, mincol is where insert started. 1347 * For the command line, mincol is what is to be skipped over. 1348 * "c" is the character typed before check_abbr was called. It may have 1349 * ABBR_OFF added to avoid prepending a CTRL-V to it. 1350 * 1351 * Historic vi practice: The last character of an abbreviation must be an id 1352 * character ([a-zA-Z0-9_]). The characters in front of it must be all id 1353 * characters or all non-id characters. This allows for abbr. "#i" to 1354 * "#include". 1355 * 1356 * Vim addition: Allow for abbreviations that end in a non-keyword character. 1357 * Then there must be white space before the abbr. 1358 * 1359 * return TRUE if there is an abbreviation, FALSE if not 1360 */ 1361 int 1362 check_abbr( 1363 int c, 1364 char_u *ptr, 1365 int col, 1366 int mincol) 1367 { 1368 int len; 1369 int scol; // starting column of the abbr. 1370 int j; 1371 char_u *s; 1372 char_u tb[MB_MAXBYTES + 4]; 1373 mapblock_T *mp; 1374 mapblock_T *mp2; 1375 int clen = 0; // length in characters 1376 int is_id = TRUE; 1377 int vim_abbr; 1378 1379 if (typebuf.tb_no_abbr_cnt) // abbrev. are not recursive 1380 return FALSE; 1381 1382 // no remapping implies no abbreviation, except for CTRL-] 1383 if (noremap_keys() && c != Ctrl_RSB) 1384 return FALSE; 1385 1386 // Check for word before the cursor: If it ends in a keyword char all 1387 // chars before it must be keyword chars or non-keyword chars, but not 1388 // white space. If it ends in a non-keyword char we accept any characters 1389 // before it except white space. 1390 if (col == 0) // cannot be an abbr. 1391 return FALSE; 1392 1393 if (has_mbyte) 1394 { 1395 char_u *p; 1396 1397 p = mb_prevptr(ptr, ptr + col); 1398 if (!vim_iswordp(p)) 1399 vim_abbr = TRUE; // Vim added abbr. 1400 else 1401 { 1402 vim_abbr = FALSE; // vi compatible abbr. 1403 if (p > ptr) 1404 is_id = vim_iswordp(mb_prevptr(ptr, p)); 1405 } 1406 clen = 1; 1407 while (p > ptr + mincol) 1408 { 1409 p = mb_prevptr(ptr, p); 1410 if (vim_isspace(*p) || (!vim_abbr && is_id != vim_iswordp(p))) 1411 { 1412 p += (*mb_ptr2len)(p); 1413 break; 1414 } 1415 ++clen; 1416 } 1417 scol = (int)(p - ptr); 1418 } 1419 else 1420 { 1421 if (!vim_iswordc(ptr[col - 1])) 1422 vim_abbr = TRUE; // Vim added abbr. 1423 else 1424 { 1425 vim_abbr = FALSE; // vi compatible abbr. 1426 if (col > 1) 1427 is_id = vim_iswordc(ptr[col - 2]); 1428 } 1429 for (scol = col - 1; scol > 0 && !vim_isspace(ptr[scol - 1]) 1430 && (vim_abbr || is_id == vim_iswordc(ptr[scol - 1])); --scol) 1431 ; 1432 } 1433 1434 if (scol < mincol) 1435 scol = mincol; 1436 if (scol < col) // there is a word in front of the cursor 1437 { 1438 ptr += scol; 1439 len = col - scol; 1440 mp = curbuf->b_first_abbr; 1441 mp2 = first_abbr; 1442 if (mp == NULL) 1443 { 1444 mp = mp2; 1445 mp2 = NULL; 1446 } 1447 for ( ; mp; mp->m_next == NULL 1448 ? (mp = mp2, mp2 = NULL) : (mp = mp->m_next)) 1449 { 1450 int qlen = mp->m_keylen; 1451 char_u *q = mp->m_keys; 1452 int match; 1453 1454 if (vim_strbyte(mp->m_keys, K_SPECIAL) != NULL) 1455 { 1456 char_u *qe = vim_strsave(mp->m_keys); 1457 1458 // might have CSI escaped mp->m_keys 1459 if (qe != NULL) 1460 { 1461 q = qe; 1462 vim_unescape_csi(q); 1463 qlen = (int)STRLEN(q); 1464 } 1465 } 1466 1467 // find entries with right mode and keys 1468 match = (mp->m_mode & State) 1469 && qlen == len 1470 && !STRNCMP(q, ptr, (size_t)len); 1471 if (q != mp->m_keys) 1472 vim_free(q); 1473 if (match) 1474 break; 1475 } 1476 if (mp != NULL) 1477 { 1478 // Found a match: 1479 // Insert the rest of the abbreviation in typebuf.tb_buf[]. 1480 // This goes from end to start. 1481 // 1482 // Characters 0x000 - 0x100: normal chars, may need CTRL-V, 1483 // except K_SPECIAL: Becomes K_SPECIAL KS_SPECIAL KE_FILLER 1484 // Characters where IS_SPECIAL() == TRUE: key codes, need 1485 // K_SPECIAL. Other characters (with ABBR_OFF): don't use CTRL-V. 1486 // 1487 // Character CTRL-] is treated specially - it completes the 1488 // abbreviation, but is not inserted into the input stream. 1489 j = 0; 1490 if (c != Ctrl_RSB) 1491 { 1492 // special key code, split up 1493 if (IS_SPECIAL(c) || c == K_SPECIAL) 1494 { 1495 tb[j++] = K_SPECIAL; 1496 tb[j++] = K_SECOND(c); 1497 tb[j++] = K_THIRD(c); 1498 } 1499 else 1500 { 1501 if (c < ABBR_OFF && (c < ' ' || c > '~')) 1502 tb[j++] = Ctrl_V; // special char needs CTRL-V 1503 if (has_mbyte) 1504 { 1505 // if ABBR_OFF has been added, remove it here 1506 if (c >= ABBR_OFF) 1507 c -= ABBR_OFF; 1508 j += (*mb_char2bytes)(c, tb + j); 1509 } 1510 else 1511 tb[j++] = c; 1512 } 1513 tb[j] = NUL; 1514 // insert the last typed char 1515 (void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent); 1516 } 1517 #ifdef FEAT_EVAL 1518 if (mp->m_expr) 1519 s = eval_map_expr(mp->m_str, c); 1520 else 1521 #endif 1522 s = mp->m_str; 1523 if (s != NULL) 1524 { 1525 // insert the to string 1526 (void)ins_typebuf(s, mp->m_noremap, 0, TRUE, mp->m_silent); 1527 // no abbrev. for these chars 1528 typebuf.tb_no_abbr_cnt += (int)STRLEN(s) + j + 1; 1529 #ifdef FEAT_EVAL 1530 if (mp->m_expr) 1531 vim_free(s); 1532 #endif 1533 } 1534 1535 tb[0] = Ctrl_H; 1536 tb[1] = NUL; 1537 if (has_mbyte) 1538 len = clen; // Delete characters instead of bytes 1539 while (len-- > 0) // delete the from string 1540 (void)ins_typebuf(tb, 1, 0, TRUE, mp->m_silent); 1541 return TRUE; 1542 } 1543 } 1544 return FALSE; 1545 } 1546 1547 #ifdef FEAT_EVAL 1548 /* 1549 * Evaluate the RHS of a mapping or abbreviations and take care of escaping 1550 * special characters. 1551 */ 1552 char_u * 1553 eval_map_expr( 1554 char_u *str, 1555 int c) // NUL or typed character for abbreviation 1556 { 1557 char_u *res; 1558 char_u *p; 1559 char_u *expr; 1560 pos_T save_cursor; 1561 int save_msg_col; 1562 int save_msg_row; 1563 1564 // Remove escaping of CSI, because "str" is in a format to be used as 1565 // typeahead. 1566 expr = vim_strsave(str); 1567 if (expr == NULL) 1568 return NULL; 1569 vim_unescape_csi(expr); 1570 1571 // Forbid changing text or using ":normal" to avoid most of the bad side 1572 // effects. Also restore the cursor position. 1573 ++textlock; 1574 ++ex_normal_lock; 1575 set_vim_var_char(c); // set v:char to the typed character 1576 save_cursor = curwin->w_cursor; 1577 save_msg_col = msg_col; 1578 save_msg_row = msg_row; 1579 p = eval_to_string(expr, NULL, FALSE); 1580 --textlock; 1581 --ex_normal_lock; 1582 curwin->w_cursor = save_cursor; 1583 msg_col = save_msg_col; 1584 msg_row = save_msg_row; 1585 1586 vim_free(expr); 1587 1588 if (p == NULL) 1589 return NULL; 1590 // Escape CSI in the result to be able to use the string as typeahead. 1591 res = vim_strsave_escape_csi(p); 1592 vim_free(p); 1593 1594 return res; 1595 } 1596 #endif 1597 1598 /* 1599 * Copy "p" to allocated memory, escaping K_SPECIAL and CSI so that the result 1600 * can be put in the typeahead buffer. 1601 * Returns NULL when out of memory. 1602 */ 1603 char_u * 1604 vim_strsave_escape_csi( 1605 char_u *p) 1606 { 1607 char_u *res; 1608 char_u *s, *d; 1609 1610 // Need a buffer to hold up to three times as much. Four in case of an 1611 // illegal utf-8 byte: 1612 // 0xc0 -> 0xc3 0x80 -> 0xc3 K_SPECIAL KS_SPECIAL KE_FILLER 1613 res = alloc(STRLEN(p) * 4 + 1); 1614 if (res != NULL) 1615 { 1616 d = res; 1617 for (s = p; *s != NUL; ) 1618 { 1619 if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL) 1620 { 1621 // Copy special key unmodified. 1622 *d++ = *s++; 1623 *d++ = *s++; 1624 *d++ = *s++; 1625 } 1626 else 1627 { 1628 // Add character, possibly multi-byte to destination, escaping 1629 // CSI and K_SPECIAL. Be careful, it can be an illegal byte! 1630 d = add_char2buf(PTR2CHAR(s), d); 1631 s += MB_CPTR2LEN(s); 1632 } 1633 } 1634 *d = NUL; 1635 } 1636 return res; 1637 } 1638 1639 /* 1640 * Remove escaping from CSI and K_SPECIAL characters. Reverse of 1641 * vim_strsave_escape_csi(). Works in-place. 1642 */ 1643 void 1644 vim_unescape_csi(char_u *p) 1645 { 1646 char_u *s = p, *d = p; 1647 1648 while (*s != NUL) 1649 { 1650 if (s[0] == K_SPECIAL && s[1] == KS_SPECIAL && s[2] == KE_FILLER) 1651 { 1652 *d++ = K_SPECIAL; 1653 s += 3; 1654 } 1655 else if ((s[0] == K_SPECIAL || s[0] == CSI) 1656 && s[1] == KS_EXTRA && s[2] == (int)KE_CSI) 1657 { 1658 *d++ = CSI; 1659 s += 3; 1660 } 1661 else 1662 *d++ = *s++; 1663 } 1664 *d = NUL; 1665 } 1666 1667 /* 1668 * Write map commands for the current mappings to an .exrc file. 1669 * Return FAIL on error, OK otherwise. 1670 */ 1671 int 1672 makemap( 1673 FILE *fd, 1674 buf_T *buf) // buffer for local mappings or NULL 1675 { 1676 mapblock_T *mp; 1677 char_u c1, c2, c3; 1678 char_u *p; 1679 char *cmd; 1680 int abbr; 1681 int hash; 1682 int did_cpo = FALSE; 1683 int i; 1684 1685 validate_maphash(); 1686 1687 // Do the loop twice: Once for mappings, once for abbreviations. 1688 // Then loop over all map hash lists. 1689 for (abbr = 0; abbr < 2; ++abbr) 1690 for (hash = 0; hash < 256; ++hash) 1691 { 1692 if (abbr) 1693 { 1694 if (hash > 0) // there is only one abbr list 1695 break; 1696 if (buf != NULL) 1697 mp = buf->b_first_abbr; 1698 else 1699 mp = first_abbr; 1700 } 1701 else 1702 { 1703 if (buf != NULL) 1704 mp = buf->b_maphash[hash]; 1705 else 1706 mp = maphash[hash]; 1707 } 1708 1709 for ( ; mp; mp = mp->m_next) 1710 { 1711 // skip script-local mappings 1712 if (mp->m_noremap == REMAP_SCRIPT) 1713 continue; 1714 1715 // skip mappings that contain a <SNR> (script-local thing), 1716 // they probably don't work when loaded again 1717 for (p = mp->m_str; *p != NUL; ++p) 1718 if (p[0] == K_SPECIAL && p[1] == KS_EXTRA 1719 && p[2] == (int)KE_SNR) 1720 break; 1721 if (*p != NUL) 1722 continue; 1723 1724 // It's possible to create a mapping and then ":unmap" certain 1725 // modes. We recreate this here by mapping the individual 1726 // modes, which requires up to three of them. 1727 c1 = NUL; 1728 c2 = NUL; 1729 c3 = NUL; 1730 if (abbr) 1731 cmd = "abbr"; 1732 else 1733 cmd = "map"; 1734 switch (mp->m_mode) 1735 { 1736 case NORMAL + VISUAL + SELECTMODE + OP_PENDING: 1737 break; 1738 case NORMAL: 1739 c1 = 'n'; 1740 break; 1741 case VISUAL: 1742 c1 = 'x'; 1743 break; 1744 case SELECTMODE: 1745 c1 = 's'; 1746 break; 1747 case OP_PENDING: 1748 c1 = 'o'; 1749 break; 1750 case NORMAL + VISUAL: 1751 c1 = 'n'; 1752 c2 = 'x'; 1753 break; 1754 case NORMAL + SELECTMODE: 1755 c1 = 'n'; 1756 c2 = 's'; 1757 break; 1758 case NORMAL + OP_PENDING: 1759 c1 = 'n'; 1760 c2 = 'o'; 1761 break; 1762 case VISUAL + SELECTMODE: 1763 c1 = 'v'; 1764 break; 1765 case VISUAL + OP_PENDING: 1766 c1 = 'x'; 1767 c2 = 'o'; 1768 break; 1769 case SELECTMODE + OP_PENDING: 1770 c1 = 's'; 1771 c2 = 'o'; 1772 break; 1773 case NORMAL + VISUAL + SELECTMODE: 1774 c1 = 'n'; 1775 c2 = 'v'; 1776 break; 1777 case NORMAL + VISUAL + OP_PENDING: 1778 c1 = 'n'; 1779 c2 = 'x'; 1780 c3 = 'o'; 1781 break; 1782 case NORMAL + SELECTMODE + OP_PENDING: 1783 c1 = 'n'; 1784 c2 = 's'; 1785 c3 = 'o'; 1786 break; 1787 case VISUAL + SELECTMODE + OP_PENDING: 1788 c1 = 'v'; 1789 c2 = 'o'; 1790 break; 1791 case CMDLINE + INSERT: 1792 if (!abbr) 1793 cmd = "map!"; 1794 break; 1795 case CMDLINE: 1796 c1 = 'c'; 1797 break; 1798 case INSERT: 1799 c1 = 'i'; 1800 break; 1801 case LANGMAP: 1802 c1 = 'l'; 1803 break; 1804 case TERMINAL: 1805 c1 = 't'; 1806 break; 1807 default: 1808 iemsg(_("E228: makemap: Illegal mode")); 1809 return FAIL; 1810 } 1811 do // do this twice if c2 is set, 3 times with c3 1812 { 1813 // When outputting <> form, need to make sure that 'cpo' 1814 // is set to the Vim default. 1815 if (!did_cpo) 1816 { 1817 if (*mp->m_str == NUL) // will use <Nop> 1818 did_cpo = TRUE; 1819 else 1820 for (i = 0; i < 2; ++i) 1821 for (p = (i ? mp->m_str : mp->m_keys); *p; ++p) 1822 if (*p == K_SPECIAL || *p == NL) 1823 did_cpo = TRUE; 1824 if (did_cpo) 1825 { 1826 if (fprintf(fd, "let s:cpo_save=&cpo") < 0 1827 || put_eol(fd) < 0 1828 || fprintf(fd, "set cpo&vim") < 0 1829 || put_eol(fd) < 0) 1830 return FAIL; 1831 } 1832 } 1833 if (c1 && putc(c1, fd) < 0) 1834 return FAIL; 1835 if (mp->m_noremap != REMAP_YES && fprintf(fd, "nore") < 0) 1836 return FAIL; 1837 if (fputs(cmd, fd) < 0) 1838 return FAIL; 1839 if (buf != NULL && fputs(" <buffer>", fd) < 0) 1840 return FAIL; 1841 if (mp->m_nowait && fputs(" <nowait>", fd) < 0) 1842 return FAIL; 1843 if (mp->m_silent && fputs(" <silent>", fd) < 0) 1844 return FAIL; 1845 #ifdef FEAT_EVAL 1846 if (mp->m_noremap == REMAP_SCRIPT 1847 && fputs("<script>", fd) < 0) 1848 return FAIL; 1849 if (mp->m_expr && fputs(" <expr>", fd) < 0) 1850 return FAIL; 1851 #endif 1852 1853 if ( putc(' ', fd) < 0 1854 || put_escstr(fd, mp->m_keys, 0) == FAIL 1855 || putc(' ', fd) < 0 1856 || put_escstr(fd, mp->m_str, 1) == FAIL 1857 || put_eol(fd) < 0) 1858 return FAIL; 1859 c1 = c2; 1860 c2 = c3; 1861 c3 = NUL; 1862 } while (c1 != NUL); 1863 } 1864 } 1865 1866 if (did_cpo) 1867 if (fprintf(fd, "let &cpo=s:cpo_save") < 0 1868 || put_eol(fd) < 0 1869 || fprintf(fd, "unlet s:cpo_save") < 0 1870 || put_eol(fd) < 0) 1871 return FAIL; 1872 return OK; 1873 } 1874 1875 /* 1876 * write escape string to file 1877 * "what": 0 for :map lhs, 1 for :map rhs, 2 for :set 1878 * 1879 * return FAIL for failure, OK otherwise 1880 */ 1881 int 1882 put_escstr(FILE *fd, char_u *strstart, int what) 1883 { 1884 char_u *str = strstart; 1885 int c; 1886 int modifiers; 1887 1888 // :map xx <Nop> 1889 if (*str == NUL && what == 1) 1890 { 1891 if (fprintf(fd, "<Nop>") < 0) 1892 return FAIL; 1893 return OK; 1894 } 1895 1896 for ( ; *str != NUL; ++str) 1897 { 1898 char_u *p; 1899 1900 // Check for a multi-byte character, which may contain escaped 1901 // K_SPECIAL and CSI bytes 1902 p = mb_unescape(&str); 1903 if (p != NULL) 1904 { 1905 while (*p != NUL) 1906 if (fputc(*p++, fd) < 0) 1907 return FAIL; 1908 --str; 1909 continue; 1910 } 1911 1912 c = *str; 1913 // Special key codes have to be translated to be able to make sense 1914 // when they are read back. 1915 if (c == K_SPECIAL && what != 2) 1916 { 1917 modifiers = 0x0; 1918 if (str[1] == KS_MODIFIER) 1919 { 1920 modifiers = str[2]; 1921 str += 3; 1922 c = *str; 1923 } 1924 if (c == K_SPECIAL) 1925 { 1926 c = TO_SPECIAL(str[1], str[2]); 1927 str += 2; 1928 } 1929 if (IS_SPECIAL(c) || modifiers) // special key 1930 { 1931 if (fputs((char *)get_special_key_name(c, modifiers), fd) < 0) 1932 return FAIL; 1933 continue; 1934 } 1935 } 1936 1937 // A '\n' in a map command should be written as <NL>. 1938 // A '\n' in a set command should be written as \^V^J. 1939 if (c == NL) 1940 { 1941 if (what == 2) 1942 { 1943 if (fprintf(fd, IF_EB("\\\026\n", "\\" CTRL_V_STR "\n")) < 0) 1944 return FAIL; 1945 } 1946 else 1947 { 1948 if (fprintf(fd, "<NL>") < 0) 1949 return FAIL; 1950 } 1951 continue; 1952 } 1953 1954 // Some characters have to be escaped with CTRL-V to 1955 // prevent them from misinterpreted in DoOneCmd(). 1956 // A space, Tab and '"' has to be escaped with a backslash to 1957 // prevent it to be misinterpreted in do_set(). 1958 // A space has to be escaped with a CTRL-V when it's at the start of a 1959 // ":map" rhs. 1960 // A '<' has to be escaped with a CTRL-V to prevent it being 1961 // interpreted as the start of a special key name. 1962 // A space in the lhs of a :map needs a CTRL-V. 1963 if (what == 2 && (VIM_ISWHITE(c) || c == '"' || c == '\\')) 1964 { 1965 if (putc('\\', fd) < 0) 1966 return FAIL; 1967 } 1968 else if (c < ' ' || c > '~' || c == '|' 1969 || (what == 0 && c == ' ') 1970 || (what == 1 && str == strstart && c == ' ') 1971 || (what != 2 && c == '<')) 1972 { 1973 if (putc(Ctrl_V, fd) < 0) 1974 return FAIL; 1975 } 1976 if (putc(c, fd) < 0) 1977 return FAIL; 1978 } 1979 return OK; 1980 } 1981 1982 /* 1983 * Check all mappings for the presence of special key codes. 1984 * Used after ":set term=xxx". 1985 */ 1986 void 1987 check_map_keycodes(void) 1988 { 1989 mapblock_T *mp; 1990 char_u *p; 1991 int i; 1992 char_u buf[3]; 1993 int abbr; 1994 int hash; 1995 buf_T *bp; 1996 ESTACK_CHECK_DECLARATION 1997 1998 validate_maphash(); 1999 // avoids giving error messages 2000 estack_push(ETYPE_INTERNAL, (char_u *)"mappings", 0); 2001 ESTACK_CHECK_SETUP 2002 2003 // Do this once for each buffer, and then once for global 2004 // mappings/abbreviations with bp == NULL 2005 for (bp = firstbuf; ; bp = bp->b_next) 2006 { 2007 // Do the loop twice: Once for mappings, once for abbreviations. 2008 // Then loop over all map hash lists. 2009 for (abbr = 0; abbr <= 1; ++abbr) 2010 for (hash = 0; hash < 256; ++hash) 2011 { 2012 if (abbr) 2013 { 2014 if (hash) // there is only one abbr list 2015 break; 2016 if (bp != NULL) 2017 mp = bp->b_first_abbr; 2018 else 2019 mp = first_abbr; 2020 } 2021 else 2022 { 2023 if (bp != NULL) 2024 mp = bp->b_maphash[hash]; 2025 else 2026 mp = maphash[hash]; 2027 } 2028 for ( ; mp != NULL; mp = mp->m_next) 2029 { 2030 for (i = 0; i <= 1; ++i) // do this twice 2031 { 2032 if (i == 0) 2033 p = mp->m_keys; // once for the "from" part 2034 else 2035 p = mp->m_str; // and once for the "to" part 2036 while (*p) 2037 { 2038 if (*p == K_SPECIAL) 2039 { 2040 ++p; 2041 if (*p < 128) // for "normal" tcap entries 2042 { 2043 buf[0] = p[0]; 2044 buf[1] = p[1]; 2045 buf[2] = NUL; 2046 (void)add_termcap_entry(buf, FALSE); 2047 } 2048 ++p; 2049 } 2050 ++p; 2051 } 2052 } 2053 } 2054 } 2055 if (bp == NULL) 2056 break; 2057 } 2058 ESTACK_CHECK_NOW 2059 estack_pop(); 2060 } 2061 2062 #if defined(FEAT_EVAL) || defined(PROTO) 2063 /* 2064 * Check the string "keys" against the lhs of all mappings. 2065 * Return pointer to rhs of mapping (mapblock->m_str). 2066 * NULL when no mapping found. 2067 */ 2068 char_u * 2069 check_map( 2070 char_u *keys, 2071 int mode, 2072 int exact, // require exact match 2073 int ign_mod, // ignore preceding modifier 2074 int abbr, // do abbreviations 2075 mapblock_T **mp_ptr, // return: pointer to mapblock or NULL 2076 int *local_ptr) // return: buffer-local mapping or NULL 2077 { 2078 int hash; 2079 int len, minlen; 2080 mapblock_T *mp; 2081 char_u *s; 2082 int local; 2083 2084 validate_maphash(); 2085 2086 len = (int)STRLEN(keys); 2087 for (local = 1; local >= 0; --local) 2088 // loop over all hash lists 2089 for (hash = 0; hash < 256; ++hash) 2090 { 2091 if (abbr) 2092 { 2093 if (hash > 0) // there is only one list. 2094 break; 2095 if (local) 2096 mp = curbuf->b_first_abbr; 2097 else 2098 mp = first_abbr; 2099 } 2100 else if (local) 2101 mp = curbuf->b_maphash[hash]; 2102 else 2103 mp = maphash[hash]; 2104 for ( ; mp != NULL; mp = mp->m_next) 2105 { 2106 // skip entries with wrong mode, wrong length and not matching 2107 // ones 2108 if ((mp->m_mode & mode) && (!exact || mp->m_keylen == len)) 2109 { 2110 if (len > mp->m_keylen) 2111 minlen = mp->m_keylen; 2112 else 2113 minlen = len; 2114 s = mp->m_keys; 2115 if (ign_mod && s[0] == K_SPECIAL && s[1] == KS_MODIFIER 2116 && s[2] != NUL) 2117 { 2118 s += 3; 2119 if (len > mp->m_keylen - 3) 2120 minlen = mp->m_keylen - 3; 2121 } 2122 if (STRNCMP(s, keys, minlen) == 0) 2123 { 2124 if (mp_ptr != NULL) 2125 *mp_ptr = mp; 2126 if (local_ptr != NULL) 2127 *local_ptr = local; 2128 return mp->m_str; 2129 } 2130 } 2131 } 2132 } 2133 2134 return NULL; 2135 } 2136 2137 void 2138 get_maparg(typval_T *argvars, typval_T *rettv, int exact) 2139 { 2140 char_u *keys; 2141 char_u *which; 2142 char_u buf[NUMBUFLEN]; 2143 char_u *keys_buf = NULL; 2144 char_u *rhs; 2145 int mode; 2146 int abbr = FALSE; 2147 int get_dict = FALSE; 2148 mapblock_T *mp; 2149 int buffer_local; 2150 2151 // return empty string for failure 2152 rettv->v_type = VAR_STRING; 2153 rettv->vval.v_string = NULL; 2154 2155 keys = tv_get_string(&argvars[0]); 2156 if (*keys == NUL) 2157 return; 2158 2159 if (argvars[1].v_type != VAR_UNKNOWN) 2160 { 2161 which = tv_get_string_buf_chk(&argvars[1], buf); 2162 if (argvars[2].v_type != VAR_UNKNOWN) 2163 { 2164 abbr = (int)tv_get_number(&argvars[2]); 2165 if (argvars[3].v_type != VAR_UNKNOWN) 2166 get_dict = (int)tv_get_number(&argvars[3]); 2167 } 2168 } 2169 else 2170 which = (char_u *)""; 2171 if (which == NULL) 2172 return; 2173 2174 mode = get_map_mode(&which, 0); 2175 2176 keys = replace_termcodes(keys, &keys_buf, 2177 REPTERM_FROM_PART | REPTERM_DO_LT, NULL); 2178 rhs = check_map(keys, mode, exact, FALSE, abbr, &mp, &buffer_local); 2179 vim_free(keys_buf); 2180 2181 if (!get_dict) 2182 { 2183 // Return a string. 2184 if (rhs != NULL) 2185 { 2186 if (*rhs == NUL) 2187 rettv->vval.v_string = vim_strsave((char_u *)"<Nop>"); 2188 else 2189 rettv->vval.v_string = str2special_save(rhs, FALSE); 2190 } 2191 2192 } 2193 else if (rettv_dict_alloc(rettv) != FAIL && rhs != NULL) 2194 { 2195 // Return a dictionary. 2196 char_u *lhs = str2special_save(mp->m_keys, TRUE); 2197 char_u *mapmode = map_mode_to_chars(mp->m_mode); 2198 dict_T *dict = rettv->vval.v_dict; 2199 2200 dict_add_string(dict, "lhs", lhs); 2201 dict_add_string(dict, "rhs", mp->m_orig_str); 2202 dict_add_number(dict, "noremap", mp->m_noremap ? 1L : 0L); 2203 dict_add_number(dict, "expr", mp->m_expr ? 1L : 0L); 2204 dict_add_number(dict, "silent", mp->m_silent ? 1L : 0L); 2205 dict_add_number(dict, "sid", (long)mp->m_script_ctx.sc_sid); 2206 dict_add_number(dict, "lnum", (long)mp->m_script_ctx.sc_lnum); 2207 dict_add_number(dict, "buffer", (long)buffer_local); 2208 dict_add_number(dict, "nowait", mp->m_nowait ? 1L : 0L); 2209 dict_add_string(dict, "mode", mapmode); 2210 2211 vim_free(lhs); 2212 vim_free(mapmode); 2213 } 2214 } 2215 #endif 2216 2217 #if defined(MSWIN) || defined(MACOS_X) 2218 2219 # define VIS_SEL (VISUAL+SELECTMODE) // abbreviation 2220 2221 /* 2222 * Default mappings for some often used keys. 2223 */ 2224 struct initmap 2225 { 2226 char_u *arg; 2227 int mode; 2228 }; 2229 2230 # ifdef FEAT_GUI_MSWIN 2231 // Use the Windows (CUA) keybindings. (GUI) 2232 static struct initmap initmappings[] = 2233 { 2234 // paste, copy and cut 2235 {(char_u *)"<S-Insert> \"*P", NORMAL}, 2236 {(char_u *)"<S-Insert> \"-d\"*P", VIS_SEL}, 2237 {(char_u *)"<S-Insert> <C-R><C-O>*", INSERT+CMDLINE}, 2238 {(char_u *)"<C-Insert> \"*y", VIS_SEL}, 2239 {(char_u *)"<S-Del> \"*d", VIS_SEL}, 2240 {(char_u *)"<C-Del> \"*d", VIS_SEL}, 2241 {(char_u *)"<C-X> \"*d", VIS_SEL}, 2242 // Missing: CTRL-C (cancel) and CTRL-V (block selection) 2243 }; 2244 # endif 2245 2246 # if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) 2247 // Use the Windows (CUA) keybindings. (Console) 2248 static struct initmap cinitmappings[] = 2249 { 2250 {(char_u *)"\316w <C-Home>", NORMAL+VIS_SEL}, 2251 {(char_u *)"\316w <C-Home>", INSERT+CMDLINE}, 2252 {(char_u *)"\316u <C-End>", NORMAL+VIS_SEL}, 2253 {(char_u *)"\316u <C-End>", INSERT+CMDLINE}, 2254 2255 // paste, copy and cut 2256 # ifdef FEAT_CLIPBOARD 2257 {(char_u *)"\316\324 \"*P", NORMAL}, // SHIFT-Insert is "*P 2258 {(char_u *)"\316\324 \"-d\"*P", VIS_SEL}, // SHIFT-Insert is "-d"*P 2259 {(char_u *)"\316\324 \022\017*", INSERT}, // SHIFT-Insert is ^R^O* 2260 {(char_u *)"\316\325 \"*y", VIS_SEL}, // CTRL-Insert is "*y 2261 {(char_u *)"\316\327 \"*d", VIS_SEL}, // SHIFT-Del is "*d 2262 {(char_u *)"\316\330 \"*d", VIS_SEL}, // CTRL-Del is "*d 2263 {(char_u *)"\030 \"*d", VIS_SEL}, // CTRL-X is "*d 2264 # else 2265 {(char_u *)"\316\324 P", NORMAL}, // SHIFT-Insert is P 2266 {(char_u *)"\316\324 \"-dP", VIS_SEL}, // SHIFT-Insert is "-dP 2267 {(char_u *)"\316\324 \022\017\"", INSERT}, // SHIFT-Insert is ^R^O" 2268 {(char_u *)"\316\325 y", VIS_SEL}, // CTRL-Insert is y 2269 {(char_u *)"\316\327 d", VIS_SEL}, // SHIFT-Del is d 2270 {(char_u *)"\316\330 d", VIS_SEL}, // CTRL-Del is d 2271 # endif 2272 }; 2273 # endif 2274 2275 # if defined(MACOS_X) 2276 static struct initmap initmappings[] = 2277 { 2278 // Use the Standard MacOS binding. 2279 // paste, copy and cut 2280 {(char_u *)"<D-v> \"*P", NORMAL}, 2281 {(char_u *)"<D-v> \"-d\"*P", VIS_SEL}, 2282 {(char_u *)"<D-v> <C-R>*", INSERT+CMDLINE}, 2283 {(char_u *)"<D-c> \"*y", VIS_SEL}, 2284 {(char_u *)"<D-x> \"*d", VIS_SEL}, 2285 {(char_u *)"<Backspace> \"-d", VIS_SEL}, 2286 }; 2287 # endif 2288 2289 # undef VIS_SEL 2290 #endif 2291 2292 /* 2293 * Set up default mappings. 2294 */ 2295 void 2296 init_mappings(void) 2297 { 2298 #if defined(MSWIN) || defined(MACOS_X) 2299 int i; 2300 2301 # if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) 2302 # ifdef VIMDLL 2303 if (!gui.starting) 2304 # endif 2305 { 2306 for (i = 0; 2307 i < (int)(sizeof(cinitmappings) / sizeof(struct initmap)); ++i) 2308 add_map(cinitmappings[i].arg, cinitmappings[i].mode); 2309 } 2310 # endif 2311 # if defined(FEAT_GUI_MSWIN) || defined(MACOS_X) 2312 for (i = 0; i < (int)(sizeof(initmappings) / sizeof(struct initmap)); ++i) 2313 add_map(initmappings[i].arg, initmappings[i].mode); 2314 # endif 2315 #endif 2316 } 2317 2318 #if defined(MSWIN) || defined(FEAT_CMDWIN) || defined(MACOS_X) \ 2319 || defined(PROTO) 2320 /* 2321 * Add a mapping "map" for mode "mode". 2322 * Need to put string in allocated memory, because do_map() will modify it. 2323 */ 2324 void 2325 add_map(char_u *map, int mode) 2326 { 2327 char_u *s; 2328 char_u *cpo_save = p_cpo; 2329 2330 p_cpo = (char_u *)""; // Allow <> notation 2331 s = vim_strsave(map); 2332 if (s != NULL) 2333 { 2334 (void)do_map(0, s, mode, FALSE); 2335 vim_free(s); 2336 } 2337 p_cpo = cpo_save; 2338 } 2339 #endif 2340 2341 #if defined(FEAT_LANGMAP) || defined(PROTO) 2342 /* 2343 * Any character has an equivalent 'langmap' character. This is used for 2344 * keyboards that have a special language mode that sends characters above 2345 * 128 (although other characters can be translated too). The "to" field is a 2346 * Vim command character. This avoids having to switch the keyboard back to 2347 * ASCII mode when leaving Insert mode. 2348 * 2349 * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim 2350 * commands. 2351 * langmap_mapga.ga_data is a sorted table of langmap_entry_T. This does the 2352 * same as langmap_mapchar[] for characters >= 256. 2353 * 2354 * Use growarray for 'langmap' chars >= 256 2355 */ 2356 typedef struct 2357 { 2358 int from; 2359 int to; 2360 } langmap_entry_T; 2361 2362 static garray_T langmap_mapga; 2363 2364 /* 2365 * Search for an entry in "langmap_mapga" for "from". If found set the "to" 2366 * field. If not found insert a new entry at the appropriate location. 2367 */ 2368 static void 2369 langmap_set_entry(int from, int to) 2370 { 2371 langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); 2372 int a = 0; 2373 int b = langmap_mapga.ga_len; 2374 2375 // Do a binary search for an existing entry. 2376 while (a != b) 2377 { 2378 int i = (a + b) / 2; 2379 int d = entries[i].from - from; 2380 2381 if (d == 0) 2382 { 2383 entries[i].to = to; 2384 return; 2385 } 2386 if (d < 0) 2387 a = i + 1; 2388 else 2389 b = i; 2390 } 2391 2392 if (ga_grow(&langmap_mapga, 1) != OK) 2393 return; // out of memory 2394 2395 // insert new entry at position "a" 2396 entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a; 2397 mch_memmove(entries + 1, entries, 2398 (langmap_mapga.ga_len - a) * sizeof(langmap_entry_T)); 2399 ++langmap_mapga.ga_len; 2400 entries[0].from = from; 2401 entries[0].to = to; 2402 } 2403 2404 /* 2405 * Apply 'langmap' to multi-byte character "c" and return the result. 2406 */ 2407 int 2408 langmap_adjust_mb(int c) 2409 { 2410 langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); 2411 int a = 0; 2412 int b = langmap_mapga.ga_len; 2413 2414 while (a != b) 2415 { 2416 int i = (a + b) / 2; 2417 int d = entries[i].from - c; 2418 2419 if (d == 0) 2420 return entries[i].to; // found matching entry 2421 if (d < 0) 2422 a = i + 1; 2423 else 2424 b = i; 2425 } 2426 return c; // no entry found, return "c" unmodified 2427 } 2428 2429 void 2430 langmap_init(void) 2431 { 2432 int i; 2433 2434 for (i = 0; i < 256; i++) 2435 langmap_mapchar[i] = i; // we init with a one-to-one map 2436 ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8); 2437 } 2438 2439 /* 2440 * Called when langmap option is set; the language map can be 2441 * changed at any time! 2442 */ 2443 void 2444 langmap_set(void) 2445 { 2446 char_u *p; 2447 char_u *p2; 2448 int from, to; 2449 2450 ga_clear(&langmap_mapga); // clear the previous map first 2451 langmap_init(); // back to one-to-one map 2452 2453 for (p = p_langmap; p[0] != NUL; ) 2454 { 2455 for (p2 = p; p2[0] != NUL && p2[0] != ',' && p2[0] != ';'; 2456 MB_PTR_ADV(p2)) 2457 { 2458 if (p2[0] == '\\' && p2[1] != NUL) 2459 ++p2; 2460 } 2461 if (p2[0] == ';') 2462 ++p2; // abcd;ABCD form, p2 points to A 2463 else 2464 p2 = NULL; // aAbBcCdD form, p2 is NULL 2465 while (p[0]) 2466 { 2467 if (p[0] == ',') 2468 { 2469 ++p; 2470 break; 2471 } 2472 if (p[0] == '\\' && p[1] != NUL) 2473 ++p; 2474 from = (*mb_ptr2char)(p); 2475 to = NUL; 2476 if (p2 == NULL) 2477 { 2478 MB_PTR_ADV(p); 2479 if (p[0] != ',') 2480 { 2481 if (p[0] == '\\') 2482 ++p; 2483 to = (*mb_ptr2char)(p); 2484 } 2485 } 2486 else 2487 { 2488 if (p2[0] != ',') 2489 { 2490 if (p2[0] == '\\') 2491 ++p2; 2492 to = (*mb_ptr2char)(p2); 2493 } 2494 } 2495 if (to == NUL) 2496 { 2497 semsg(_("E357: 'langmap': Matching character missing for %s"), 2498 transchar(from)); 2499 return; 2500 } 2501 2502 if (from >= 256) 2503 langmap_set_entry(from, to); 2504 else 2505 langmap_mapchar[from & 255] = to; 2506 2507 // Advance to next pair 2508 MB_PTR_ADV(p); 2509 if (p2 != NULL) 2510 { 2511 MB_PTR_ADV(p2); 2512 if (*p == ';') 2513 { 2514 p = p2; 2515 if (p[0] != NUL) 2516 { 2517 if (p[0] != ',') 2518 { 2519 semsg(_("E358: 'langmap': Extra characters after semicolon: %s"), p); 2520 return; 2521 } 2522 ++p; 2523 } 2524 break; 2525 } 2526 } 2527 } 2528 } 2529 } 2530 #endif 2531 2532 static void 2533 do_exmap(exarg_T *eap, int isabbrev) 2534 { 2535 int mode; 2536 char_u *cmdp; 2537 2538 cmdp = eap->cmd; 2539 mode = get_map_mode(&cmdp, eap->forceit || isabbrev); 2540 2541 switch (do_map((*cmdp == 'n') ? 2 : (*cmdp == 'u'), 2542 eap->arg, mode, isabbrev)) 2543 { 2544 case 1: emsg(_(e_invarg)); 2545 break; 2546 case 2: emsg((isabbrev ? _(e_noabbr) : _(e_nomap))); 2547 break; 2548 } 2549 } 2550 2551 /* 2552 * ":abbreviate" and friends. 2553 */ 2554 void 2555 ex_abbreviate(exarg_T *eap) 2556 { 2557 do_exmap(eap, TRUE); // almost the same as mapping 2558 } 2559 2560 /* 2561 * ":map" and friends. 2562 */ 2563 void 2564 ex_map(exarg_T *eap) 2565 { 2566 // If we are sourcing .exrc or .vimrc in current directory we 2567 // print the mappings for security reasons. 2568 if (secure) 2569 { 2570 secure = 2; 2571 msg_outtrans(eap->cmd); 2572 msg_putchar('\n'); 2573 } 2574 do_exmap(eap, FALSE); 2575 } 2576 2577 /* 2578 * ":unmap" and friends. 2579 */ 2580 void 2581 ex_unmap(exarg_T *eap) 2582 { 2583 do_exmap(eap, FALSE); 2584 } 2585 2586 /* 2587 * ":mapclear" and friends. 2588 */ 2589 void 2590 ex_mapclear(exarg_T *eap) 2591 { 2592 map_clear(eap->cmd, eap->arg, eap->forceit, FALSE); 2593 } 2594 2595 /* 2596 * ":abclear" and friends. 2597 */ 2598 void 2599 ex_abclear(exarg_T *eap) 2600 { 2601 map_clear(eap->cmd, eap->arg, TRUE, TRUE); 2602 } 2603