diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-04-07 13:58:04 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-04-07 13:58:04 +0100 |
commit | 6d4e725a3447af6f69305fdc9f1e1ff8d82e3863 (patch) | |
tree | 2b8acbed1a0774ac7def27ea696f7ad59e93a6d7 /src | |
parent | f26c16144ddb27642c09f2cf5271afd163b36306 (diff) |
patch 8.2.4705: jump list marker disappearsv8.2.4705
Problem: Jump list marker disappears.
Solution: Reset reg_executing later. (closes #10111, closes #10100)
Diffstat (limited to 'src')
-rw-r--r-- | src/ex_docmd.c | 4 | ||||
-rw-r--r-- | src/getchar.c | 29 | ||||
-rw-r--r-- | src/globals.h | 2 | ||||
-rw-r--r-- | src/structs.h | 1 | ||||
-rw-r--r-- | src/testdir/test_registers.vim | 18 | ||||
-rw-r--r-- | src/version.c | 2 |
6 files changed, 52 insertions, 4 deletions
diff --git a/src/ex_docmd.c b/src/ex_docmd.c index 2d5752445b..90ca7ade2b 100644 --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -1733,6 +1733,7 @@ do_one_cmd( exarg_T ea; // Ex command arguments cmdmod_T save_cmdmod; int save_reg_executing = reg_executing; + int save_pending_end_reg_executing = pending_end_reg_executing; int ni; // set when Not Implemented char_u *cmd; int starts_with_colon = FALSE; @@ -2630,6 +2631,7 @@ doend: undo_cmdmod(&cmdmod); cmdmod = save_cmdmod; reg_executing = save_reg_executing; + pending_end_reg_executing = save_pending_end_reg_executing; if (ea.nextcmd && *ea.nextcmd == NUL) // not really a next command ea.nextcmd = NULL; @@ -8456,6 +8458,7 @@ save_current_state(save_state_T *sst) sst->save_finish_op = finish_op; sst->save_opcount = opcount; sst->save_reg_executing = reg_executing; + sst->save_pending_end_reg_executing = pending_end_reg_executing; msg_scroll = FALSE; // no msg scrolling in Normal mode restart_edit = 0; // don't go to Insert mode @@ -8485,6 +8488,7 @@ restore_current_state(save_state_T *sst) finish_op = sst->save_finish_op; opcount = sst->save_opcount; reg_executing = sst->save_reg_executing; + pending_end_reg_executing = sst->save_pending_end_reg_executing; msg_didout |= sst->save_msg_didout; // don't reset msg_didout now current_sctx.sc_version = sst->save_script_version; diff --git a/src/getchar.c b/src/getchar.c index b81f64a65c..29ad56e6a1 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -1421,7 +1421,7 @@ static int old_mouse_row; // mouse_row related to old_char static int old_mouse_col; // mouse_col related to old_char static int old_KeyStuffed; // whether old_char was stuffed -static int can_get_old_char() +static int can_get_old_char(void) { // If the old character was not stuffed and characters have been added to // the stuff buffer, need to first get the stuffed characters instead. @@ -2950,7 +2950,7 @@ handle_mapping( /* * unget one character (can only be done once!) - * If the character was stuffed, vgetc() will get it next time it was called. + * If the character was stuffed, vgetc() will get it next time it is called. * Otherwise vgetc() will only get it when the stuff buffer is empty. */ void @@ -2964,6 +2964,27 @@ vungetc(int c) } /* + * When peeking and not getting a character, reg_executing cannot be cleared + * yet, so set a flag to clear it later. + */ + static void +check_end_reg_executing(int advance) +{ + if (reg_executing != 0 && (typebuf.tb_maplen == 0 + || pending_end_reg_executing)) + { + if (advance) + { + reg_executing = 0; + pending_end_reg_executing = FALSE; + } + else + pending_end_reg_executing = TRUE; + } + +} + +/* * Get a byte: * 1. from the stuffbuffer * This is used for abbreviated commands like "D" -> "d$". @@ -3026,8 +3047,7 @@ vgetorpeek(int advance) init_typebuf(); start_stuff(); - if (advance && typebuf.tb_maplen == 0) - reg_executing = 0; + check_end_reg_executing(advance); do { /* @@ -3068,6 +3088,7 @@ vgetorpeek(int advance) #ifdef FEAT_CMDL_INFO int showcmd_idx; #endif + check_end_reg_executing(advance); /* * ui_breakcheck() is slow, don't use it too often when * inside a mapping. But call it each time for typed diff --git a/src/globals.h b/src/globals.h index f690efffc4..da1ff76391 100644 --- a/src/globals.h +++ b/src/globals.h @@ -1123,6 +1123,8 @@ EXTERN int ex_no_reprint INIT(= FALSE); // no need to print after z or p EXTERN int reg_recording INIT(= 0); // register for recording or zero EXTERN int reg_executing INIT(= 0); // register being executed or zero +// Flag set when peeking a character and found the end of executed register +EXTERN int pending_end_reg_executing INIT(= 0); // Set when a modifyOtherKeys sequence was seen, then simplified mappings will // no longer be used. diff --git a/src/structs.h b/src/structs.h index a1dbfbed28..b8648a5455 100644 --- a/src/structs.h +++ b/src/structs.h @@ -4302,6 +4302,7 @@ typedef struct { int save_finish_op; int save_opcount; int save_reg_executing; + int save_pending_end_reg_executing; int save_script_version; tasave_T tabuf; } save_state_T; diff --git a/src/testdir/test_registers.vim b/src/testdir/test_registers.vim index 078b78dfdf..51543c00c1 100644 --- a/src/testdir/test_registers.vim +++ b/src/testdir/test_registers.vim @@ -759,6 +759,24 @@ func Test_record_in_select_mode() bwipe! endfunc +func Test_end_reg_executing() + nnoremap s <Nop> + let @a = 's' + call feedkeys("@aqaq\<Esc>", 'tx') + call assert_equal('', @a) + call assert_equal('', getline(1)) + + call setline(1, 'aaa') + nnoremap s qa + let @a = 'fa' + call feedkeys("@asq\<Esc>", 'tx') + call assert_equal('', @a) + call assert_equal('aaa', getline(1)) + + nunmap s + bwipe! +endfunc + " Make sure that y_append is correctly reset " and the previous register is working as expected func Test_register_y_append_reset() diff --git a/src/version.c b/src/version.c index 1bc106337c..62623614a2 100644 --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4705, +/**/ 4704, /**/ 4703, |