summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/getchar.c76
-rw-r--r--src/keymap.h2
-rw-r--r--src/normal.c7
-rw-r--r--src/proto/getchar.pro1
-rw-r--r--src/testdir/test_mapping.vim29
-rw-r--r--src/version.c2
6 files changed, 113 insertions, 4 deletions
diff --git a/src/getchar.c b/src/getchar.c
index 51faa2382..d49c02635 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -85,6 +85,7 @@ static int last_recorded_len = 0; // number of last recorded chars
#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,6 +838,22 @@ start_redo(long count, int old_redo)
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,7 +893,7 @@ start_redo(long count, int old_redo)
add_num_buff(&readbuf2, count);
}
- // copy from the redo buffer into the stuff buffer
+ // copy the rest from the redo buffer into the stuff buffer
add_char_buff(&readbuf2, c);
copy_redo(old_redo);
return OK;
@@ -1796,7 +1813,21 @@ vgetc(void)
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,6 +2953,10 @@ handle_mapping(
{
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,7 +2975,6 @@ handle_mapping(
#ifdef FEAT_EVAL
if (save_m_expr)
vim_free(map_str);
- last_used_map = mp;
#endif
}
#ifdef FEAT_EVAL
@@ -3896,6 +3930,29 @@ getcmdkeycmd(
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,10 +3960,18 @@ do_cmdkey_command(int key UNUSED, int flags)
#ifdef FEAT_EVAL
sctx_T save_current_sctx = {-1, 0, 0, 0};
- if (key == K_SCRIPT_COMMAND && last_used_map != NULL)
+ if (key == K_SCRIPT_COMMAND
+ && (last_used_map != NULL || SCRIPT_ID_VALID(last_used_sid)))
{
save_current_sctx = current_sctx;
- current_sctx = last_used_map->m_script_ctx;
+ 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,6 +3990,9 @@ do_cmdkey_command(int key UNUSED, int flags)
reset_last_used_map(mapblock_T *mp)
{
if (last_used_map == mp)
+ {
last_used_map = NULL;
+ last_used_sid = -1;
+ }
}
#endif
diff --git a/src/keymap.h b/src/keymap.h
index 6350772c7..910df7d02 100644
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -277,6 +277,7 @@ enum key_extra
, 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,6 +484,7 @@ enum key_extra
#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
diff --git a/src/normal.c b/src/normal.c
index fb2bced04..8351685d1 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -1466,6 +1466,13 @@ prep_redo_num2(
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('"');
diff --git a/src/proto/getchar.pro b/src/proto/getchar.pro
index 47af0bb32..66c1e9b72 100644
--- a/src/proto/getchar.pro
+++ b/src/proto/getchar.pro
@@ -52,6 +52,7 @@ void parse_queued_messages(void);
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 : */
diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim
index 2927ba718..bc5b487f2 100644
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -1529,6 +1529,35 @@ func Test_map_script_cmd_survives_unmap()
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
diff --git a/src/version.c b/src/version.c
index fc8850161..5ab26b102 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 387,
+/**/
386,
/**/
385,