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 #12354)
diff --git a/src/getchar.c b/src/getchar.c
index d510e45..1c3cdb1 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -43,8 +43,8 @@
 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 @@
     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;
 	}
diff --git a/src/ops.c b/src/ops.c
index 4c64e05..d46a049 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -3701,7 +3701,10 @@
 		    ResetRedobuff();
 		else
 		{
-		    AppendToRedobuffSpec(repeat_cmdline);
+		    if (cap->cmdchar == ':')
+			AppendToRedobuffLit(repeat_cmdline, -1);
+		    else
+			AppendToRedobuffSpec(repeat_cmdline);
 		    AppendToRedobuff(NL_STR);
 		    VIM_CLEAR(repeat_cmdline);
 		}
diff --git a/src/testdir/test_normal.vim b/src/testdir/test_normal.vim
index 03d29ae..470b41c 100644
--- a/src/testdir/test_normal.vim
+++ b/src/testdir/test_normal.vim
@@ -3635,11 +3635,32 @@
   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
 
diff --git a/src/version.c b/src/version.c
index 35ea18a..454e246 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    1521,
+/**/
     1520,
 /**/
     1519,