Mercurial > vim
comparison src/getchar.c @ 30102:539fb427124d v9.0.0387
patch 9.0.0387: repeat <ScriptCmd> mapping doesn't use right script context
Commit: https://github.com/vim/vim/commit/ddf7dba96e05a41c7a228b153146237e0a21b146
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Sep 5 16:53:21 2022 +0100
patch 9.0.0387: repeat <ScriptCmd> mapping doesn't use right script context
Problem: repeating a <ScriptCmd> mapping does not use the right script
context.
Solution: When using a mapping put <SID>{sid}; in the redo buffer.
(closes #11049)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 05 Sep 2022 18:00:05 +0200 |
parents | 5b4f3129cadc |
children | cabceac53ade |
comparison
equal
deleted
inserted
replaced
30101:50cb1d7be810 | 30102:539fb427124d |
---|---|
83 | 83 |
84 static int last_recorded_len = 0; // number of last recorded chars | 84 static int last_recorded_len = 0; // number of last recorded chars |
85 | 85 |
86 #ifdef FEAT_EVAL | 86 #ifdef FEAT_EVAL |
87 mapblock_T *last_used_map = NULL; | 87 mapblock_T *last_used_map = NULL; |
88 int last_used_sid = -1; | |
88 #endif | 89 #endif |
89 | 90 |
90 static int read_readbuf(buffheader_T *buf, int advance); | 91 static int read_readbuf(buffheader_T *buf, int advance); |
91 static void init_typebuf(void); | 92 static void init_typebuf(void); |
92 static void may_sync_undo(void); | 93 static void may_sync_undo(void); |
835 if (read_redo(TRUE, old_redo) == FAIL) | 836 if (read_redo(TRUE, old_redo) == FAIL) |
836 return FAIL; | 837 return FAIL; |
837 | 838 |
838 c = read_redo(FALSE, old_redo); | 839 c = read_redo(FALSE, old_redo); |
839 | 840 |
841 #ifdef FEAT_EVAL | |
842 if (c == K_SID) | |
843 { | |
844 // Copy the <SID>{sid}; sequence | |
845 add_char_buff(&readbuf2, c); | |
846 for (;;) | |
847 { | |
848 c = read_redo(FALSE, old_redo); | |
849 add_char_buff(&readbuf2, c); | |
850 if (!isdigit(c)) | |
851 break; | |
852 } | |
853 c = read_redo(FALSE, old_redo); | |
854 } | |
855 #endif | |
856 | |
840 // copy the buffer name, if present | 857 // copy the buffer name, if present |
841 if (c == '"') | 858 if (c == '"') |
842 { | 859 { |
843 add_buff(&readbuf2, (char_u *)"\"", 1L); | 860 add_buff(&readbuf2, (char_u *)"\"", 1L); |
844 c = read_redo(FALSE, old_redo); | 861 c = read_redo(FALSE, old_redo); |
874 while (VIM_ISDIGIT(c)) // skip "old" count | 891 while (VIM_ISDIGIT(c)) // skip "old" count |
875 c = read_redo(FALSE, old_redo); | 892 c = read_redo(FALSE, old_redo); |
876 add_num_buff(&readbuf2, count); | 893 add_num_buff(&readbuf2, count); |
877 } | 894 } |
878 | 895 |
879 // copy from the redo buffer into the stuff buffer | 896 // copy the rest from the redo buffer into the stuff buffer |
880 add_char_buff(&readbuf2, c); | 897 add_char_buff(&readbuf2, c); |
881 copy_redo(old_redo); | 898 copy_redo(old_redo); |
882 return OK; | 899 return OK; |
883 } | 900 } |
884 | 901 |
1794 // Translate K_CSI to CSI. The special key is only used to | 1811 // Translate K_CSI to CSI. The special key is only used to |
1795 // avoid it being recognized as the start of a special key. | 1812 // avoid it being recognized as the start of a special key. |
1796 if (c == K_CSI) | 1813 if (c == K_CSI) |
1797 c = CSI; | 1814 c = CSI; |
1798 #endif | 1815 #endif |
1816 #ifdef FEAT_EVAL | |
1817 if (c == K_SID) | |
1818 { | |
1819 int j; | |
1820 | |
1821 // Handle <SID>{sid}; Do up to 20 digits for safety. | |
1822 last_used_sid = 0; | |
1823 for (j = 0; j < 20 && isdigit(c = vgetorpeek(TRUE)); ++j) | |
1824 last_used_sid = last_used_sid * 10 + (c - '0'); | |
1825 last_used_map = NULL; | |
1826 continue; | |
1827 } | |
1828 #endif | |
1799 } | 1829 } |
1830 | |
1800 // a keypad or special function key was not mapped, use it like | 1831 // a keypad or special function key was not mapped, use it like |
1801 // its ASCII equivalent | 1832 // its ASCII equivalent |
1802 switch (c) | 1833 switch (c) |
1803 { | 1834 { |
1804 case K_KPLUS: c = '+'; break; | 1835 case K_KPLUS: c = '+'; break; |
2920 i = FAIL; | 2951 i = FAIL; |
2921 else | 2952 else |
2922 { | 2953 { |
2923 int noremap; | 2954 int noremap; |
2924 | 2955 |
2956 #ifdef FEAT_EVAL | |
2957 last_used_map = mp; | |
2958 last_used_sid = -1; | |
2959 #endif | |
2925 if (save_m_noremap != REMAP_YES) | 2960 if (save_m_noremap != REMAP_YES) |
2926 noremap = save_m_noremap; | 2961 noremap = save_m_noremap; |
2927 else if ( | 2962 else if ( |
2928 #ifdef FEAT_EVAL | 2963 #ifdef FEAT_EVAL |
2929 STRNCMP(map_str, save_m_keys != NULL ? save_m_keys : mp->m_keys, | 2964 STRNCMP(map_str, save_m_keys != NULL ? save_m_keys : mp->m_keys, |
2938 i = ins_typebuf(map_str, noremap, | 2973 i = ins_typebuf(map_str, noremap, |
2939 0, TRUE, cmd_silent || save_m_silent); | 2974 0, TRUE, cmd_silent || save_m_silent); |
2940 #ifdef FEAT_EVAL | 2975 #ifdef FEAT_EVAL |
2941 if (save_m_expr) | 2976 if (save_m_expr) |
2942 vim_free(map_str); | 2977 vim_free(map_str); |
2943 last_used_map = mp; | |
2944 #endif | 2978 #endif |
2945 } | 2979 } |
2946 #ifdef FEAT_EVAL | 2980 #ifdef FEAT_EVAL |
2947 vim_free(save_m_keys); | 2981 vim_free(save_m_keys); |
2948 #endif | 2982 #endif |
3894 ga_clear(&line_ga); | 3928 ga_clear(&line_ga); |
3895 | 3929 |
3896 return (char_u *)line_ga.ga_data; | 3930 return (char_u *)line_ga.ga_data; |
3897 } | 3931 } |
3898 | 3932 |
3933 #if defined(FEAT_EVAL) || defined(PROTO) | |
3934 /* | |
3935 * If there was a mapping put info about it in the redo buffer, so that "." | |
3936 * will use the same script context. We only need the SID. | |
3937 */ | |
3938 void | |
3939 may_add_last_used_map_to_redobuff(void) | |
3940 { | |
3941 char_u buf[3 + 20]; | |
3942 | |
3943 if (last_used_map == NULL || last_used_map->m_script_ctx.sc_sid < 0) | |
3944 return; | |
3945 | |
3946 // <K_SID>{nr}; | |
3947 buf[0] = K_SPECIAL; | |
3948 buf[1] = KS_EXTRA; | |
3949 buf[2] = KE_SID; | |
3950 vim_snprintf((char *)buf + 3, 20, "%d;", | |
3951 last_used_map->m_script_ctx.sc_sid); | |
3952 add_buff(&redobuff, buf, -1L); | |
3953 } | |
3954 #endif | |
3955 | |
3899 int | 3956 int |
3900 do_cmdkey_command(int key UNUSED, int flags) | 3957 do_cmdkey_command(int key UNUSED, int flags) |
3901 { | 3958 { |
3902 int res; | 3959 int res; |
3903 #ifdef FEAT_EVAL | 3960 #ifdef FEAT_EVAL |
3904 sctx_T save_current_sctx = {-1, 0, 0, 0}; | 3961 sctx_T save_current_sctx = {-1, 0, 0, 0}; |
3905 | 3962 |
3906 if (key == K_SCRIPT_COMMAND && last_used_map != NULL) | 3963 if (key == K_SCRIPT_COMMAND |
3964 && (last_used_map != NULL || SCRIPT_ID_VALID(last_used_sid))) | |
3907 { | 3965 { |
3908 save_current_sctx = current_sctx; | 3966 save_current_sctx = current_sctx; |
3909 current_sctx = last_used_map->m_script_ctx; | 3967 if (last_used_map != NULL) |
3968 current_sctx = last_used_map->m_script_ctx; | |
3969 else | |
3970 { | |
3971 current_sctx.sc_sid = last_used_sid; | |
3972 current_sctx.sc_lnum = 0; | |
3973 current_sctx.sc_version = SCRIPT_ITEM(last_used_sid)->sn_version; | |
3974 } | |
3910 } | 3975 } |
3911 #endif | 3976 #endif |
3912 | 3977 |
3913 res = do_cmdline(NULL, getcmdkeycmd, NULL, flags); | 3978 res = do_cmdline(NULL, getcmdkeycmd, NULL, flags); |
3914 | 3979 |
3923 #if defined(FEAT_EVAL) || defined(PROTO) | 3988 #if defined(FEAT_EVAL) || defined(PROTO) |
3924 void | 3989 void |
3925 reset_last_used_map(mapblock_T *mp) | 3990 reset_last_used_map(mapblock_T *mp) |
3926 { | 3991 { |
3927 if (last_used_map == mp) | 3992 if (last_used_map == mp) |
3993 { | |
3928 last_used_map = NULL; | 3994 last_used_map = NULL; |
3929 } | 3995 last_used_sid = -1; |
3930 #endif | 3996 } |
3997 } | |
3998 #endif |