Mercurial > vim
changeset 28359:390dfc3e409b v8.2.4705
patch 8.2.4705: jump list marker disappears
Commit: https://github.com/vim/vim/commit/6d4e725a3447af6f69305fdc9f1e1ff8d82e3863
Author: zeertzjq <zeertzjq@outlook.com>
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Thu, 07 Apr 2022 15:00:05 +0200 |
parents | 44be5f4c12d4 |
children | af739ab30d2a |
files | src/ex_docmd.c src/getchar.c src/globals.h src/structs.h src/testdir/test_registers.vim src/version.c |
diffstat | 6 files changed, 52 insertions(+), 4 deletions(-) [+] |
line wrap: on
line diff
--- 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;
--- 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
--- 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.
--- 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;
--- 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()