Mercurial > vim
comparison src/map.c @ 29173:1ec1ba7e7728 v8.2.5106
patch 8.2.5106: default cmdwin mappings are re-mappable
Commit: https://github.com/vim/vim/commit/44068e97dbd8fc8ebd93113e436a1e37a6bff52c
Author: zeertzjq <zeertzjq@outlook.com>
Date: Thu Jun 16 11:14:55 2022 +0100
patch 8.2.5106: default cmdwin mappings are re-mappable
Problem: Default cmdwin mappings are re-mappable.
Solution: Make the default mappings not re-mappable. (closes https://github.com/vim/vim/issues/10580) Use
symbols for the first do_map() argument.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 16 Jun 2022 12:30:04 +0200 |
parents | 45c182c4f7e9 |
children | 755ab148288b |
comparison
equal
deleted
inserted
replaced
29172:d08526b7bcd4 | 29173:1ec1ba7e7728 |
---|---|
291 * abbr {lhs} : show abbreviations for {lhs} | 291 * abbr {lhs} : show abbreviations for {lhs} |
292 * abbr {lhs} {rhs} : set abbreviation for {lhs} to {rhs} | 292 * abbr {lhs} {rhs} : set abbreviation for {lhs} to {rhs} |
293 * noreabbr {lhs} {rhs} : same, but no remapping for {rhs} | 293 * noreabbr {lhs} {rhs} : same, but no remapping for {rhs} |
294 * unabbr {lhs} : remove abbreviation for {lhs} | 294 * unabbr {lhs} : remove abbreviation for {lhs} |
295 * | 295 * |
296 * maptype: 0 for :map, 1 for :unmap, 2 for noremap. | 296 * maptype: MAPTYPE_MAP for :map |
297 * MAPTYPE_UNMAP for :unmap | |
298 * MAPTYPE_NOREMAP for noremap | |
297 * | 299 * |
298 * arg is pointer to any arguments. Note: arg cannot be a read-only string, | 300 * arg is pointer to any arguments. Note: arg cannot be a read-only string, |
299 * it will be modified. | 301 * it will be modified. |
300 * | 302 * |
301 * for :map mode is MODE_NORMAL | MODE_VISUAL | MODE_SELECT | MODE_OP_PENDING | 303 * for :map mode is MODE_NORMAL | MODE_VISUAL | MODE_SELECT | MODE_OP_PENDING |
358 keys = arg; | 360 keys = arg; |
359 map_table = maphash; | 361 map_table = maphash; |
360 abbr_table = &first_abbr; | 362 abbr_table = &first_abbr; |
361 | 363 |
362 // For ":noremap" don't remap, otherwise do remap. | 364 // For ":noremap" don't remap, otherwise do remap. |
363 if (maptype == 2) | 365 if (maptype == MAPTYPE_NOREMAP) |
364 noremap = REMAP_NONE; | 366 noremap = REMAP_NONE; |
365 else | 367 else |
366 noremap = REMAP_YES; | 368 noremap = REMAP_YES; |
367 | 369 |
368 // Accept <buffer>, <nowait>, <silent>, <expr> <script> and <unique> in | 370 // Accept <buffer>, <nowait>, <silent>, <expr> <script> and <unique> in |
434 // Find end of keys and skip CTRL-Vs (and backslashes) in it. | 436 // Find end of keys and skip CTRL-Vs (and backslashes) in it. |
435 // Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'. | 437 // Accept backslash like CTRL-V when 'cpoptions' does not contain 'B'. |
436 // with :unmap white space is included in the keys, no argument possible. | 438 // with :unmap white space is included in the keys, no argument possible. |
437 p = keys; | 439 p = keys; |
438 do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL); | 440 do_backslash = (vim_strchr(p_cpo, CPO_BSLASH) == NULL); |
439 while (*p && (maptype == 1 || !VIM_ISWHITE(*p))) | 441 while (*p && (maptype == MAPTYPE_UNMAP || !VIM_ISWHITE(*p))) |
440 { | 442 { |
441 if ((p[0] == Ctrl_V || (do_backslash && p[0] == '\\')) && | 443 if ((p[0] == Ctrl_V || (do_backslash && p[0] == '\\')) && |
442 p[1] != NUL) | 444 p[1] != NUL) |
443 ++p; // skip CTRL-V or backslash | 445 ++p; // skip CTRL-V or backslash |
444 ++p; | 446 ++p; |
448 | 450 |
449 p = skipwhite(p); | 451 p = skipwhite(p); |
450 rhs = p; | 452 rhs = p; |
451 hasarg = (*rhs != NUL); | 453 hasarg = (*rhs != NUL); |
452 haskey = (*keys != NUL); | 454 haskey = (*keys != NUL); |
453 do_print = !haskey || (maptype != 1 && !hasarg); | 455 do_print = !haskey || (maptype != MAPTYPE_UNMAP && !hasarg); |
454 | 456 |
455 // check for :unmap without argument | 457 // check for :unmap without argument |
456 if (maptype == 1 && !haskey) | 458 if (maptype == MAPTYPE_UNMAP && !haskey) |
457 { | 459 { |
458 retval = 1; | 460 retval = 1; |
459 goto theend; | 461 goto theend; |
460 } | 462 } |
461 | 463 |
522 { | 524 { |
523 retval = 1; | 525 retval = 1; |
524 goto theend; | 526 goto theend; |
525 } | 527 } |
526 | 528 |
527 if (abbrev && maptype != 1) | 529 if (abbrev && maptype != MAPTYPE_UNMAP) |
528 { | 530 { |
529 // If an abbreviation ends in a keyword character, the | 531 // If an abbreviation ends in a keyword character, the |
530 // rest must be all keyword-char or all non-keyword-char. | 532 // rest must be all keyword-char or all non-keyword-char. |
531 // Otherwise we won't be able to find the start of it in a | 533 // Otherwise we won't be able to find the start of it in a |
532 // vi-compatible way. | 534 // vi-compatible way. |
578 if (do_print) | 580 if (do_print) |
579 msg_start(); | 581 msg_start(); |
580 | 582 |
581 // Check if a new local mapping wasn't already defined globally. | 583 // Check if a new local mapping wasn't already defined globally. |
582 if (unique && map_table == curbuf->b_maphash | 584 if (unique && map_table == curbuf->b_maphash |
583 && haskey && hasarg && maptype != 1) | 585 && haskey && hasarg && maptype != MAPTYPE_UNMAP) |
584 { | 586 { |
585 // need to loop over all global hash lists | 587 // need to loop over all global hash lists |
586 for (hash = 0; hash < 256 && !got_int; ++hash) | 588 for (hash = 0; hash < 256 && !got_int; ++hash) |
587 { | 589 { |
588 if (abbrev) | 590 if (abbrev) |
613 } | 615 } |
614 } | 616 } |
615 } | 617 } |
616 | 618 |
617 // When listing global mappings, also list buffer-local ones here. | 619 // When listing global mappings, also list buffer-local ones here. |
618 if (map_table != curbuf->b_maphash && !hasarg && maptype != 1) | 620 if (map_table != curbuf->b_maphash && !hasarg |
621 && maptype != MAPTYPE_UNMAP) | |
619 { | 622 { |
620 // need to loop over all global hash lists | 623 // need to loop over all global hash lists |
621 for (hash = 0; hash < 256 && !got_int; ++hash) | 624 for (hash = 0; hash < 256 && !got_int; ++hash) |
622 { | 625 { |
623 if (abbrev) | 626 if (abbrev) |
657 // For :unmap we may loop two times: once to try to unmap an entry with | 660 // For :unmap we may loop two times: once to try to unmap an entry with |
658 // a matching 'from' part, a second time, if the first fails, to unmap | 661 // a matching 'from' part, a second time, if the first fails, to unmap |
659 // an entry with a matching 'to' part. This was done to allow | 662 // an entry with a matching 'to' part. This was done to allow |
660 // ":ab foo bar" to be unmapped by typing ":unab foo", where "foo" will | 663 // ":ab foo bar" to be unmapped by typing ":unab foo", where "foo" will |
661 // be replaced by "bar" because of the abbreviation. | 664 // be replaced by "bar" because of the abbreviation. |
662 for (round = 0; (round == 0 || maptype == 1) && round <= 1 | 665 for (round = 0; (round == 0 || maptype == MAPTYPE_UNMAP) && round <= 1 |
663 && !did_it && !got_int; ++round) | 666 && !did_it && !got_int; ++round) |
664 { | 667 { |
665 // need to loop over all hash lists | 668 // need to loop over all hash lists |
666 for (hash = 0; hash < 256 && !got_int; ++hash) | 669 for (hash = 0; hash < 256 && !got_int; ++hash) |
667 { | 670 { |
702 n = mp->m_keylen; | 705 n = mp->m_keylen; |
703 p = mp->m_keys; | 706 p = mp->m_keys; |
704 } | 707 } |
705 if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0) | 708 if (STRNCMP(p, keys, (size_t)(n < len ? n : len)) == 0) |
706 { | 709 { |
707 if (maptype == 1) | 710 if (maptype == MAPTYPE_UNMAP) |
708 { | 711 { |
709 // Delete entry. | 712 // Delete entry. |
710 // Only accept a full match. For abbreviations | 713 // Only accept a full match. For abbreviations |
711 // we ignore trailing space when matching with | 714 // we ignore trailing space when matching with |
712 // the "lhs", since an abbreviation can't have | 715 // the "lhs", since an abbreviation can't have |
803 mpp = &(mp->m_next); | 806 mpp = &(mp->m_next); |
804 } | 807 } |
805 } | 808 } |
806 } | 809 } |
807 | 810 |
808 if (maptype == 1) | 811 if (maptype == MAPTYPE_UNMAP) |
809 { | 812 { |
810 // delete entry | 813 // delete entry |
811 if (!did_it) | 814 if (!did_it) |
812 { | 815 { |
813 if (!keyround1_simplified) | 816 if (!keyround1_simplified) |
2659 { | 2662 { |
2660 arg = vim_strsave(lhs); | 2663 arg = vim_strsave(lhs); |
2661 if (arg == NULL) | 2664 if (arg == NULL) |
2662 return; | 2665 return; |
2663 } | 2666 } |
2664 do_map(1, arg, mode, is_abbr); | 2667 do_map(MAPTYPE_UNMAP, arg, mode, is_abbr); |
2665 vim_free(arg); | 2668 vim_free(arg); |
2666 | 2669 |
2667 (void)map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs, noremap, | 2670 (void)map_add(map_table, abbr_table, lhsraw, rhs, orig_rhs, noremap, |
2668 nowait, silent, mode, is_abbr, expr, sid, scriptversion, lnum, 0); | 2671 nowait, silent, mode, is_abbr, expr, sid, scriptversion, lnum, 0); |
2669 if (lhsrawalt != NULL) | 2672 if (lhsrawalt != NULL) |
2764 # ifdef VIMDLL | 2767 # ifdef VIMDLL |
2765 if (!gui.starting) | 2768 if (!gui.starting) |
2766 # endif | 2769 # endif |
2767 { | 2770 { |
2768 for (i = 0; i < (int)ARRAY_LENGTH(cinitmappings); ++i) | 2771 for (i = 0; i < (int)ARRAY_LENGTH(cinitmappings); ++i) |
2769 add_map(cinitmappings[i].arg, cinitmappings[i].mode); | 2772 add_map(cinitmappings[i].arg, cinitmappings[i].mode, FALSE); |
2770 } | 2773 } |
2771 # endif | 2774 # endif |
2772 # if defined(FEAT_GUI_MSWIN) || defined(MACOS_X) | 2775 # if defined(FEAT_GUI_MSWIN) || defined(MACOS_X) |
2773 for (i = 0; i < (int)ARRAY_LENGTH(initmappings); ++i) | 2776 for (i = 0; i < (int)ARRAY_LENGTH(initmappings); ++i) |
2774 add_map(initmappings[i].arg, initmappings[i].mode); | 2777 add_map(initmappings[i].arg, initmappings[i].mode, FALSE); |
2775 # endif | 2778 # endif |
2776 #endif | 2779 #endif |
2777 } | 2780 } |
2778 | 2781 |
2779 #if defined(MSWIN) || defined(FEAT_CMDWIN) || defined(MACOS_X) \ | 2782 #if defined(MSWIN) || defined(FEAT_CMDWIN) || defined(MACOS_X) \ |
2780 || defined(PROTO) | 2783 || defined(PROTO) |
2781 /* | 2784 /* |
2782 * Add a mapping "map" for mode "mode". | 2785 * Add a mapping "map" for mode "mode". |
2786 * When "nore" is TRUE use MAPTYPE_NOREMAP. | |
2783 * Need to put string in allocated memory, because do_map() will modify it. | 2787 * Need to put string in allocated memory, because do_map() will modify it. |
2784 */ | 2788 */ |
2785 void | 2789 void |
2786 add_map(char_u *map, int mode) | 2790 add_map(char_u *map, int mode, int nore) |
2787 { | 2791 { |
2788 char_u *s; | 2792 char_u *s; |
2789 char_u *cpo_save = p_cpo; | 2793 char_u *cpo_save = p_cpo; |
2790 | 2794 |
2791 p_cpo = empty_option; // Allow <> notation | 2795 p_cpo = empty_option; // Allow <> notation |
2792 s = vim_strsave(map); | 2796 s = vim_strsave(map); |
2793 if (s != NULL) | 2797 if (s != NULL) |
2794 { | 2798 { |
2795 (void)do_map(0, s, mode, FALSE); | 2799 (void)do_map(nore ? MAPTYPE_NOREMAP : MAPTYPE_MAP, s, mode, FALSE); |
2796 vim_free(s); | 2800 vim_free(s); |
2797 } | 2801 } |
2798 p_cpo = cpo_save; | 2802 p_cpo = cpo_save; |
2799 } | 2803 } |
2800 #endif | 2804 #endif |
2997 char_u *cmdp; | 3001 char_u *cmdp; |
2998 | 3002 |
2999 cmdp = eap->cmd; | 3003 cmdp = eap->cmd; |
3000 mode = get_map_mode(&cmdp, eap->forceit || isabbrev); | 3004 mode = get_map_mode(&cmdp, eap->forceit || isabbrev); |
3001 | 3005 |
3002 switch (do_map((*cmdp == 'n') ? 2 : (*cmdp == 'u'), | 3006 switch (do_map(*cmdp == 'n' ? MAPTYPE_NOREMAP |
3007 : *cmdp == 'u' ? MAPTYPE_UNMAP : MAPTYPE_MAP, | |
3003 eap->arg, mode, isabbrev)) | 3008 eap->arg, mode, isabbrev)) |
3004 { | 3009 { |
3005 case 1: emsg(_(e_invalid_argument)); | 3010 case 1: emsg(_(e_invalid_argument)); |
3006 break; | 3011 break; |
3007 case 2: emsg((isabbrev ? _(e_no_such_abbreviation) | 3012 case 2: emsg((isabbrev ? _(e_no_such_abbreviation) |