]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0415: Wrong behavior when executing register that ends in Insert mode v9.2.0415
authorzeertzjq <zeertzjq@outlook.com>
Wed, 29 Apr 2026 16:10:04 +0000 (16:10 +0000)
committerChristian Brabandt <cb@256bit.org>
Wed, 29 Apr 2026 16:11:56 +0000 (16:11 +0000)
Problem:  Wrong behavior when executing register that ends in Insert
          mode from Ctrl-O (Emilien Breton)
Solution: Use :startinsert etc. to restore Insert mode after executing
          the register contents (zeertzjq).

fixes:  #20085
closes: #20091

Signed-off-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/register.c
src/testdir/test_registers.vim
src/version.c

index 9eeb88f44266b1b3c71d5a1e4b6d3d19de5ec882..9f0e06b54686ee5c2e28f13b33d05f1044c4024c 100644 (file)
@@ -787,22 +787,18 @@ do_execreg(
     static void
 put_reedit_in_typebuf(int silent)
 {
-    char_u     buf[3];
-
     if (restart_edit == NUL)
        return;
 
-    if (restart_edit == 'V')
-    {
-       buf[0] = 'g';
-       buf[1] = 'R';
-       buf[2] = NUL;
-    }
-    else
-    {
-       buf[0] = restart_edit == 'I' ? 'i' : restart_edit;
-       buf[1] = NUL;
-    }
+    char_u     buf[] = { K_SPECIAL, KS_EXTRA, KE_COMMAND,
+       // :startinsert
+       's', 't', 'a', 'r', 't', 'i', CAR, NUL };
+    if (restart_edit == 'R')
+       buf[8] = 'r';  // :startreplace
+    else if (restart_edit == 'V')
+       buf[8] = 'g';  // :startgreplace
+    else if (restart_edit == 'A')
+       buf[8] = '!';  // :startinsert!
     if (ins_typebuf(buf, REMAP_NONE, 0, TRUE, silent) == OK)
        restart_edit = NUL;
 }
index 245340c82a013437a08076ba9d2100ec8c795553..bb1dd31f3e0261a1f574c650ae90247124074eb0 100644 (file)
@@ -582,21 +582,41 @@ func Test_clipboard_regs_both_unnamed()
   bwipe!
 endfunc
 
-" Test for restarting the current mode (insert or virtual replace) after
+" Test for restarting the current mode (insert or (virtual) replace) after
 " executing the contents of a register
-func Test_put_reg_restart_mode()
+func Test_exec_reg_restart_mode()
   new
-  call append(0, 'editor')
-  normal gg
+
   let @r = "ivim \<Esc>"
-  call feedkeys("i\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
+
+  call setline(1, 'editor')
+  normal gg
+  call feedkeys("i\<C-O>@r\<C-R>=mode(1)\<CR>", 'xt')
   call assert_equal('vimi editor', getline(1))
 
   call setline(1, 'editor')
   normal gg
-  call feedkeys("gR\<C-O>@r\<C-R>=mode()\<CR>", 'xt')
+  call feedkeys("R\<C-O>@r\<C-R>=mode(1)\<CR>", 'xt')
   call assert_equal('vimReditor', getline(1))
 
+  call setline(1, 'editor')
+  normal gg
+  call feedkeys("gR\<C-O>@r\<C-R>=mode(1)\<CR>", 'xt')
+  call assert_equal('vimRvditor', getline(1))
+
+  " If the register doesn't return to Normal mode, Vim should stay in whatever
+  " mode the register ends up with, and should not insert extra text. #20085
+  for [s0, expected] in
+        \ [['i', 'vim editor,i'], ['R', 'vim or,R'], ['gR', 'vim or,Rv']]
+    let @r = $"{s0}vim "
+    for s1 in ['i', 'R', 'gR']
+      call setline(1, 'editor')
+      normal gg
+      call feedkeys($"{s1}\<C-O>@r\<End>,\<C-R>=mode(1)\<CR>", 'xt')
+      call assert_equal(expected, getline(1))
+    endfor
+  endfor
+
   bwipe!
 endfunc
 
index 08ebffbb594e39393ac19f915043243a77ec6155..c54177a4a9b4ac6ac49e71d8446c21fa18537fb8 100644 (file)
@@ -729,6 +729,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    415,
 /**/
     414,
 /**/