]> granicus.if.org Git - vim/commitdiff
patch 8.2.4705: jump list marker disappears v8.2.4705
authorzeertzjq <zeertzjq@outlook.com>
Thu, 7 Apr 2022 12:58:04 +0000 (13:58 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 7 Apr 2022 12:58:04 +0000 (13:58 +0100)
Problem:    Jump list marker disappears.
Solution:   Reset reg_executing later. (closes #10111, closes #10100)

src/ex_docmd.c
src/getchar.c
src/globals.h
src/structs.h
src/testdir/test_registers.vim
src/version.c

index 2d5752445b0e6675d966b1d3daf8a8ac51452c80..90ca7ade2bd99a9d2e01c43118c21d403b021c28 100644 (file)
@@ -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;
 
index b81f64a65c0aeeae7440a0bd69ad3e270575ccc3..29ad56e6a176f8084bbc80bbe8c9bd27aee57d6f 100644 (file)
@@ -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
@@ -2963,6 +2963,27 @@ vungetc(int c)
     old_KeyStuffed = KeyStuffed;
 }
 
+/*
+ * 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
@@ -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
index f690efffc4d5481e7d6373df76200aa4ebf8903a..da1ff76391bcc4e2cf9d4edeb2e93d3b9da3346d 100644 (file)
@@ -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.
index a1dbfbed28478726d378c56fd7f45b28e549f129..b8648a5455e9b3f86b7ea1e9f762fa053bd505b4 100644 (file)
@@ -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;
index 078b78dfdf39ab859fce11fbfdaa2e68df0ad0c7..51543c00c1f789476965264399dec2c2108e3fbc 100644 (file)
@@ -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()
index 1bc106337c2e2c8b2f381a88dce77f7fb80cdb3d..62623614a20037db8a4bad1d3f12bfad73219095 100644 (file)
@@ -746,6 +746,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4705,
 /**/
     4704,
 /**/