patch 8.2.4705: jump list marker disappears

Problem:    Jump list marker disappears.
Solution:   Reset reg_executing later. (closes #10111, closes #10100)
diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 2d57524..90ca7ad 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -1733,6 +1733,7 @@
     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 @@
     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 @@
     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 @@
     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 b81f64a..29ad56e 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1421,7 +1421,7 @@
 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 @@
 
 /*
  * 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 @@
 }
 
 /*
+ * 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 @@
 
     init_typebuf();
     start_stuff();
-    if (advance && typebuf.tb_maplen == 0)
-	reg_executing = 0;
+    check_end_reg_executing(advance);
     do
     {
 /*
@@ -3068,6 +3088,7 @@
 #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 f690eff..da1ff76 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1123,6 +1123,8 @@
 
 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 a1dbfbe..b8648a5 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -4302,6 +4302,7 @@
     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 078b78d..51543c0 100644
--- a/src/testdir/test_registers.vim
+++ b/src/testdir/test_registers.vim
@@ -759,6 +759,24 @@
   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 1bc1063..6262361 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    4705,
+/**/
     4704,
 /**/
     4703,