changeset 32379:89679a3f2e09 v9.0.1521

patch 9.0.1521: failing redo of command with control characters Commit: https://github.com/vim/vim/commit/30b6d6104c3d541c41c868989c020b743e01af08 Author: zeertzjq <zeertzjq@outlook.com> Date: Sun May 7 17:39:23 2023 +0100 patch 9.0.1521: failing redo of command with control characters Problem: Failing redo of command with control characters. Solution: Use AppendToRedobuffLit() for colon commands. (closes https://github.com/vim/vim/issues/12354)
author Bram Moolenaar <Bram@vim.org>
date Sun, 07 May 2023 18:45:05 +0200
parents a40f038ce8b5
children a8b5d3012377
files src/getchar.c src/ops.c src/testdir/test_normal.vim src/version.c
diffstat 4 files changed, 34 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -43,8 +43,8 @@ static buffheader_T recordbuff = {{NULL,
 static int typeahead_char = 0;		// typeahead char that's not flushed
 
 /*
- * when block_redo is TRUE redo buffer will not be changed
- * used by edit() to repeat insertions and 'V' command for redoing
+ * When block_redo is TRUE the redo buffer will not be changed.
+ * Used by edit() to repeat insertions.
  */
 static int	block_redo = FALSE;
 
@@ -609,11 +609,14 @@ AppendToRedobuffLit(
     void
 AppendToRedobuffSpec(char_u *s)
 {
+    if (block_redo)
+	return;
+
     while (*s != NUL)
     {
 	if (*s == K_SPECIAL && s[1] != NUL && s[2] != NUL)
 	{
-	    // insert special key literally
+	    // Insert special key literally.
 	    add_buff(&redobuff, s, 3L);
 	    s += 3;
 	}
--- a/src/ops.c
+++ b/src/ops.c
@@ -3701,7 +3701,10 @@ do_pending_operator(cmdarg_T *cap, int o
 		    ResetRedobuff();
 		else
 		{
-		    AppendToRedobuffSpec(repeat_cmdline);
+		    if (cap->cmdchar == ':')
+			AppendToRedobuffLit(repeat_cmdline, -1);
+		    else
+			AppendToRedobuffSpec(repeat_cmdline);
 		    AppendToRedobuff(NL_STR);
 		    VIM_CLEAR(repeat_cmdline);
 		}
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -3635,11 +3635,32 @@ func Test_horiz_motion()
   bwipe!
 endfunc
 
-" Test for using a : command in operator pending mode
+" Test for using a ":" command in operator pending mode
 func Test_normal_colon_op()
   new
   call setline(1, ['one', 'two'])
   call assert_beeps("normal! Gc:d\<CR>")
+  call assert_equal(['one'], getline(1, '$'))
+
+  call setline(1, ['one…two…three!'])
+  normal! $
+  " Using ":" as a movement is characterwise exclusive
+  call feedkeys("d:normal! F…\<CR>", 'xt')
+  call assert_equal(['one…two!'], getline(1, '$'))
+  " Check that redoing a command with 0x80 bytes works
+  call feedkeys('.', 'xt')
+  call assert_equal(['one!'], getline(1, '$'))
+
+  call setline(1, ['one', 'two', 'three', 'four', 'five'])
+  " Add this to the command history
+  call feedkeys(":normal! G0\<CR>", 'xt')
+  " Use :normal! with control characters in operator pending mode
+  call feedkeys("d:normal! \<C-V>\<C-P>\<C-V>\<C-P>\<CR>", 'xt')
+  call assert_equal(['one', 'two', 'five'], getline(1, '$'))
+  " Check that redoing a command with control characters works
+  call feedkeys('.', 'xt')
+  call assert_equal(['five'], getline(1, '$'))
+
   bwipe!
 endfunc
 
--- 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 */
 /**/
+    1521,
+/**/
     1520,
 /**/
     1519,