changeset 32031:e9b8deedab60 v9.0.1347

patch 9.0.1347: "gr CTRL-O" stays in Insert mode Commit: https://github.com/vim/vim/commit/2824d1ee325ea61855c26f77e7a4e095b9606720 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Feb 23 20:13:04 2023 +0000 patch 9.0.1347: "gr CTRL-O" stays in Insert mode Problem: "gr CTRL-O" stays in Insert mode. (Pierre Ganty) Solution: Do not set restart_edit when "cmdchar" is 'v'. (closes https://github.com/vim/vim/issues/12045)
author Bram Moolenaar <Bram@vim.org>
date Thu, 23 Feb 2023 21:15:03 +0100
parents 91ee05af181e
children 265476b2cfeb
files src/edit.c src/testdir/test_edit.vim src/version.c
diffstat 3 files changed, 22 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/edit.c
+++ b/src/edit.c
@@ -45,7 +45,7 @@ static void ins_ctrl_(void);
 #endif
 static int ins_start_select(int c);
 static void ins_insert(int replaceState);
-static void ins_ctrl_o(void);
+static void ins_ctrl_o(int cmdchar);
 static void ins_shift(int c, int lastc);
 static void ins_del(void);
 static int  ins_bs(int c, int mode, int *inserted_space_p);
@@ -429,7 +429,8 @@ edit(
     /*
      * Main loop in Insert mode: repeat until Insert mode is left.
      */
-    for (;;)
+    int did_loop = FALSE;
+    for (;; did_loop = TRUE)
     {
 #ifdef FEAT_RIGHTLEFT
 	if (!revins_legal)
@@ -588,6 +589,8 @@ edit(
 	if (cmdchar == K_PS)
 	    // Got here from normal mode when bracketed paste started.
 	    c = K_PS;
+	else if (cmdchar == 'v' && did_loop)
+	    c = ESC;  // in case the stuffed Esc was consumed already
 	else
 	    do
 	    {
@@ -717,7 +720,7 @@ edit(
 	    {
 		if (c == Ctrl_O)
 		{
-		    ins_ctrl_o();
+		    ins_ctrl_o(cmdchar);
 		    ins_at_eol = FALSE;	// cursor keeps its column
 		    nomove = TRUE;
 		}
@@ -860,7 +863,7 @@ doESCkey:
 #endif
 	    if (echeck_abbr(Ctrl_O + ABBR_OFF))
 		break;
-	    ins_ctrl_o();
+	    ins_ctrl_o(cmdchar);
 
 	    // don't move the cursor left when 'virtualedit' has "onemore".
 	    if (get_ve_flags() & VE_ONEMORE)
@@ -3848,8 +3851,10 @@ ins_insert(int replaceState)
  * Pressed CTRL-O in Insert mode.
  */
     static void
-ins_ctrl_o(void)
+ins_ctrl_o(int cmdchar)
 {
+    if (cmdchar == 'v')
+	return;  // abort replacing one char for gr CTRL-O
     if (State & VREPLACE_FLAG)
 	restart_edit = 'V';
     else if (State & REPLACE_FLAG)
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -2064,6 +2064,16 @@ func Test_edit_CTRL_hat()
   bwipe!
 endfunc
 
+" Test "gr" followed by an Insert mode command does get out of Insert mode.
+func Test_edit_gr_special()
+  enew
+  call setline(1, ['abcdef', 'xxxxxx'])
+  exe "normal! gr\<C-O>x"
+  call assert_equal('bcdef', getline(1))
+
+  bwipe!
+endfunc
+
 " Weird long file name was going over the end of NameBuff
 func Test_edit_overlong_file_name()
   CheckUnix
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1347,
+/**/
     1346,
 /**/
     1345,