summaryrefslogtreecommitdiffstats
path: root/src/getchar.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-09-05 16:53:21 +0100
committerBram Moolenaar <Bram@vim.org>2022-09-05 16:53:21 +0100
commitddf7dba96e05a41c7a228b153146237e0a21b146 (patch)
treeb5865b60ab795b541a902b2be3c39c0df353ca37 /src/getchar.c
parentb1f471ee20b0fa783ecd6e29aa69067e6c821376 (diff)
patch 9.0.0387: repeat <ScriptCmd> mapping doesn't use right script contextv9.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)
Diffstat (limited to 'src/getchar.c')
-rw-r--r--src/getchar.c76
1 files changed, 72 insertions, 4 deletions
diff --git a/src/getchar.c b/src/getchar.c
index 51faa2382c..d49c02635b 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