Skip to content

Commit

Permalink
patch 9.0.0387: repeat <ScriptCmd> mapping doesn't use right script c…
Browse files Browse the repository at this point in the history
…ontext

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)
  • Loading branch information
brammool committed Sep 5, 2022
1 parent b1f471e commit ddf7dba
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 4 deletions.
76 changes: 72 additions & 4 deletions src/getchar.c
Expand Up @@ -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);
Expand Down Expand Up @@ -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 == '"')
{
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -1795,8 +1812,22 @@ vgetc(void)
// avoid it being recognized as the start of a special key.
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)
Expand Down Expand Up @@ -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 (
Expand All @@ -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
Expand Down Expand Up @@ -3896,17 +3930,48 @@ 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)
{
int res;
#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

Expand All @@ -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
2 changes: 2 additions & 0 deletions src/keymap.h
Expand Up @@ -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};
};

/*
Expand Down Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions src/normal.c
Expand Up @@ -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('"');
Expand Down
1 change: 1 addition & 0 deletions src/proto/getchar.pro
Expand Up @@ -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 : */
29 changes: 29 additions & 0 deletions src/testdir/test_mapping.vim
Expand Up @@ -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
Expand Down
2 changes: 2 additions & 0 deletions src/version.c
Expand Up @@ -703,6 +703,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
387,
/**/
386,
/**/
Expand Down

0 comments on commit ddf7dba

Please sign in to comment.