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