# HG changeset patch # User Bram Moolenaar # Date 1649336405 -7200 # Node ID 390dfc3e409b641b7d1d696af61a5692e74dfaeb # Parent 44be5f4c12d4d7cc28109356c85e94f70d5823fd patch 8.2.4705: jump list marker disappears Commit: https://github.com/vim/vim/commit/6d4e725a3447af6f69305fdc9f1e1ff8d82e3863 Author: zeertzjq Date: Thu Apr 7 13:58:04 2022 +0100 patch 8.2.4705: jump list marker disappears Problem: Jump list marker disappears. Solution: Reset reg_executing later. (closes https://github.com/vim/vim/issues/10111, closes https://github.com/vim/vim/issues/10100) diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- 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 --- a/src/getchar.c +++ b/src/getchar.c @@ -1421,7 +1421,7 @@ static int old_mouse_row; // mouse_row r 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 --- a/src/globals.h +++ b/src/globals.h @@ -1123,6 +1123,8 @@ EXTERN int ex_no_reprint INIT(= FALSE); 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 --- 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 --- 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 + let @a = 's' + call feedkeys("@aqaq\", 'tx') + call assert_equal('', @a) + call assert_equal('', getline(1)) + + call setline(1, 'aaa') + nnoremap s qa + let @a = 'fa' + call feedkeys("@asq\", '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 --- 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,