Patch 9.0.0387
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)
Files: src/getchar.c, src/proto/
getchar.pro, src/keymap.h, src/normal.c,
src/testdir/test_mapping.vim
*** ../vim-9.0.0386/src/getchar.c 2022-09-05 13:05:26.034229996 +0100
--- src/getchar.c 2022-09-05 16:50:04.679709793 +0100
***************
*** 85,90 ****
--- 85,91 ----
#ifdef FEAT_EVAL
mapblock_T *last_used_map = NULL;
+ int last_used_sid = -1;
#endif
static int read_readbuf(buffheader_T *buf, int advance);
***************
*** 837,842 ****
--- 838,859 ----
c = read_redo(FALSE, old_redo);
+ #ifdef FEAT_EVAL
+ if (c == K_SID)
+ {
+ // Copy the <SID>{sid}; sequence
+ add_char_buff(&readbuf2, c);
+ for (;;)
+ {
+ c = read_redo(FALSE, old_redo);
+ add_char_buff(&readbuf2, c);
+ if (!isdigit(c))
+ break;
+ }
+ c = read_redo(FALSE, old_redo);
+ }
+ #endif
+
// copy the buffer name, if present
if (c == '"')
{
***************
*** 876,882 ****
add_num_buff(&readbuf2, count);
}
! // copy from the redo buffer into the stuff buffer
add_char_buff(&readbuf2, c);
copy_redo(old_redo);
return OK;
--- 893,899 ----
add_num_buff(&readbuf2, count);
}
! // copy the rest from the redo buffer into the stuff buffer
add_char_buff(&readbuf2, c);
copy_redo(old_redo);
return OK;
***************
*** 1796,1802 ****
--- 1813,1833 ----
if (c == K_CSI)
c = CSI;
#endif
+ #ifdef FEAT_EVAL
+ if (c == K_SID)
+ {
+ int j;
+
+ // Handle <SID>{sid}; Do up to 20 digits for safety.
+ last_used_sid = 0;
+ for (j = 0; j < 20 && isdigit(c = vgetorpeek(TRUE)); ++j)
+ last_used_sid = last_used_sid * 10 + (c - '0');
+ last_used_map = NULL;
+ continue;
+ }
+ #endif
}
+
// a keypad or special function key was not mapped, use it like
// its ASCII equivalent
switch (c)
***************
*** 2922,2927 ****
--- 2953,2962 ----
{
int noremap;
+ #ifdef FEAT_EVAL
+ last_used_map = mp;
+ last_used_sid = -1;
+ #endif
if (save_m_noremap != REMAP_YES)
noremap = save_m_noremap;
else if (
***************
*** 2940,2946 ****
#ifdef FEAT_EVAL
if (save_m_expr)
vim_free(map_str);
- last_used_map = mp;
#endif
}
#ifdef FEAT_EVAL
--- 2975,2980 ----
***************
*** 3896,3901 ****
--- 3930,3958 ----
return (char_u *)line_ga.ga_data;
}
+ #if defined(FEAT_EVAL) || defined(PROTO)
+ /*
+ * If there was a mapping put info about it in the redo buffer, so that "."
+ * will use the same script context. We only need the SID.
+ */
+ void
+ may_add_last_used_map_to_redobuff(void)
+ {
+ char_u buf[3 + 20];
+
+ if (last_used_map == NULL || last_used_map->m_script_ctx.sc_sid < 0)
+ return;
+
+ // <K_SID>{nr};
+ buf[0] = K_SPECIAL;
+ buf[1] = KS_EXTRA;
+ buf[2] = KE_SID;
+ vim_snprintf((char *)buf + 3, 20, "%d;",
+ last_used_map->m_script_ctx.sc_sid);
+ add_buff(&redobuff, buf, -1L);
+ }
+ #endif
+
int
do_cmdkey_command(int key UNUSED, int flags)
{
***************
*** 3903,3912 ****
#ifdef FEAT_EVAL
sctx_T save_current_sctx = {-1, 0, 0, 0};
! if (key == K_SCRIPT_COMMAND && last_used_map != NULL)
{
save_current_sctx = current_sctx;
! current_sctx = last_used_map->m_script_ctx;
}
#endif
--- 3960,3977 ----
#ifdef FEAT_EVAL
sctx_T save_current_sctx = {-1, 0, 0, 0};
! if (key == K_SCRIPT_COMMAND
! && (last_used_map != NULL || SCRIPT_ID_VALID(last_used_sid)))
{
save_current_sctx = current_sctx;
! if (last_used_map != NULL)
! current_sctx = last_used_map->m_script_ctx;
! else
! {
! current_sctx.sc_sid = last_used_sid;
! current_sctx.sc_lnum = 0;
! current_sctx.sc_version = SCRIPT_ITEM(last_used_sid)->sn_version;
! }
}
#endif
***************
*** 3925,3930 ****
--- 3990,3998 ----
reset_last_used_map(mapblock_T *mp)
{
if (last_used_map == mp)
+ {
last_used_map = NULL;
+ last_used_sid = -1;
+ }
}
#endif
*** ../vim-9.0.0386/src/proto/
getchar.pro 2022-06-27 23:15:07.000000000 +0100
--- src/proto/
getchar.pro 2022-09-05 15:48:38.243636493 +0100
***************
*** 52,57 ****
--- 52,58 ----
void vungetc(int c);
int fix_input_buffer(char_u *buf, int len);
int input_available(void);
+ void may_add_last_used_map_to_redobuff(void);
int do_cmdkey_command(int key, int flags);
void reset_last_used_map(mapblock_T *mp);
/* vim: set ft=c : */
*** ../vim-9.0.0386/src/keymap.h 2022-05-09 19:16:21.000000000 +0100
--- src/keymap.h 2022-09-05 15:11:28.574604295 +0100
***************
*** 277,282 ****
--- 277,283 ----
, KE_COMMAND = 103 // <Cmd> special key
, KE_SCRIPT_COMMAND = 104 // <ScriptCmd> special key
, KE_S_BS = 105 // shift + <BS>
+ , KE_SID = 106 // <SID> special key, followed by {nr};
};
/*
***************
*** 483,488 ****
--- 484,490 ----
#define K_COMMAND TERMCAP2KEY(KS_EXTRA, KE_COMMAND)
#define K_SCRIPT_COMMAND TERMCAP2KEY(KS_EXTRA, KE_SCRIPT_COMMAND)
+ #define K_SID TERMCAP2KEY(KS_EXTRA, KE_SID)
// Bits for modifier mask
// 0x01 cannot be used, because the modifier must be 0x02 or higher
*** ../vim-9.0.0386/src/normal.c 2022-08-31 14:46:07.907016957 +0100
--- src/normal.c 2022-09-05 15:48:22.403657169 +0100
***************
*** 1466,1471 ****
--- 1466,1478 ----
int cmd5)
{
ResetRedobuff();
+
+ #ifdef FEAT_EVAL
+ // Put info about a mapping in the redo buffer, so that "." will use the
+ // same script context.
+ may_add_last_used_map_to_redobuff();
+ #endif
+
if (regname != 0) // yank from specified buffer
{
AppendCharToRedobuff('"');
*** ../vim-9.0.0386/src/testdir/test_mapping.vim 2022-07-01 16:35:38.406031649 +0100
--- src/testdir/test_mapping.vim 2022-09-05 16:39:55.404396060 +0100
***************
*** 1529,1534 ****
--- 1529,1563 ----
autocmd! CmdlineEnter
endfunc
+ func Test_map_script_cmd_redo()
+ call mkdir('Xmapcmd')
+ let lines =<< trim END
+ vim9script
+ import autoload './script.vim'
+ onoremap <F3> <ScriptCmd>script.Func()<CR>
+ END
+ call writefile(lines, 'Xmapcmd/plugin.vim')
+
+ let lines =<< trim END
+ vim9script
+ export def Func()
+ normal! dd
+ enddef
+ END
+ call writefile(lines, 'Xmapcmd/script.vim')
+ new
+ call setline(1, ['one', 'two', 'three', 'four'])
+ nnoremap j j
+ source Xmapcmd/plugin.vim
+ call feedkeys("d\<F3>j.", 'xt')
+ call assert_equal(['two', 'four'], getline(1, '$'))
+
+ ounmap <F3>
+ nunmap j
+ call delete('Xmapcmd', 'rf')
+ bwipe!
+ endfunc
+
" Test for using <script> with a map to remap characters in rhs
func Test_script_local_remap()
new
*** ../vim-9.0.0386/src/version.c 2022-09-05 14:33:42.202419990 +0100
--- src/version.c 2022-09-05 16:51:56.031577969 +0100
***************
*** 705,706 ****
--- 705,708 ----
{ /* Add new patch number below this line */
+ /**/
+ 387,
/**/
--
Everybody wants to go to heaven, but nobody wants to die.
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///