patch 8.2.0855: GUI tests fail because the test doesn't use a modifier

Problem:    GUI tests fail because the test doesn't use a modifier.
Solution:   Add "\{xxx}" to be able to encode a modifier.
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 0585ce0..11cc772 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -1353,6 +1353,9 @@
 	To use the double quote character it must be escaped: "<M-\">".
 	Don't use <Char-xxxx> to get a utf-8 character, use \uxxxx as
 	mentioned above.
+\{xxx}	like \<xxx> but prepends a modifier instead of including it in the
+	character.  E.g. "\<C-w>" is one character 0x17 while "\{C-w}" is four
+	bytes: 3 for the CTRL modifier and then character "W".
 
 Note that "\xff" is stored as the byte 255, which may be invalid in some
 encodings.  Use "\u00ff" to store character 255 according to the current value
diff --git a/src/gui_mac.c b/src/gui_mac.c
index b048375..1ca2d56 100644
--- a/src/gui_mac.c
+++ b/src/gui_mac.c
@@ -4755,8 +4755,7 @@
 	char_u	    *p_actext;
 
 	p_actext = menu->actext;
-	key = find_special_key(&p_actext, &modifiers, FALSE, FALSE, FALSE,
-								   TRUE, NULL);
+	key = find_special_key(&p_actext, &modifiers, FSK_SIMPLIFY, NULL);
 	if (*p_actext != 0)
 	    key = 0; // error: trailing text
 	// find_special_key() returns a keycode with as many of the
diff --git a/src/highlight.c b/src/highlight.c
index 7a7e537..9da87f2 100644
--- a/src/highlight.c
+++ b/src/highlight.c
@@ -1412,8 +1412,7 @@
 		 */
 		for (p = arg, off = 0; off < 100 - 6 && *p; )
 		{
-		    len = trans_special(&p, buf + off, FALSE, FALSE,
-								   TRUE, NULL);
+		    len = trans_special(&p, buf + off, FSK_SIMPLIFY, NULL);
 		    if (len > 0)	    // recognized special char
 			off += len;
 		    else		    // copy as normal char
diff --git a/src/misc2.c b/src/misc2.c
index 678b73c..61c997d 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -2703,20 +2703,17 @@
 trans_special(
     char_u	**srcp,
     char_u	*dst,
-    int		keycode,    // prefer key code, e.g. K_DEL instead of DEL
-    int		in_string,  // TRUE when inside a double quoted string
-    int		simplify,	// simplify <C-H> and <A-x>
-    int		*did_simplify)  // found <C-H> or <A-x>
+    int		flags,		// FSK_ values
+    int		*did_simplify)  // FSK_SIMPLIFY and found <C-H> or <A-x>
 {
     int		modifiers = 0;
     int		key;
 
-    key = find_special_key(srcp, &modifiers, keycode, FALSE, in_string,
-						       simplify, did_simplify);
+    key = find_special_key(srcp, &modifiers, flags, did_simplify);
     if (key == 0)
 	return 0;
 
-    return special_to_buf(key, modifiers, keycode, dst);
+    return special_to_buf(key, modifiers, flags & FSK_KEYCODE, dst);
 }
 
 /*
@@ -2764,24 +2761,23 @@
 find_special_key(
     char_u	**srcp,
     int		*modp,
-    int		keycode,	// prefer key code, e.g. K_DEL instead of DEL
-    int		keep_x_key,	// don't translate xHome to Home key
-    int		in_string,	// TRUE in string, double quote is escaped
-    int		simplify,	// simplify <C-H> and <A-x>
+    int		flags,		// FSK_ values
     int		*did_simplify)  // found <C-H> or <A-x>
 {
     char_u	*last_dash;
     char_u	*end_of_name;
     char_u	*src;
     char_u	*bp;
+    int		in_string = flags & FSK_IN_STRING;
     int		modifiers;
     int		bit;
     int		key;
+    int		endchar = (flags & FSK_CURLY) ? '}' : '>';
     uvarnumber_T	n;
     int		l;
 
     src = *srcp;
-    if (src[0] != '<')
+    if (src[0] != ((flags & FSK_CURLY) ? '{' : '<'))
 	return 0;
 
     // Find end of modifier list
@@ -2800,15 +2796,15 @@
 		// Anything accepted, like <C-?>.
 		// <C-"> or <M-"> are not special in strings as " is
 		// the string delimiter. With a backslash it works: <M-\">
-		if (!(in_string && bp[1] == '"') && bp[l + 1] == '>')
+		if (!(in_string && bp[1] == '"') && bp[l + 1] == endchar)
 		    bp += l;
 		else if (in_string && bp[1] == '\\' && bp[2] == '"'
-							       && bp[3] == '>')
+							   && bp[3] == endchar)
 		    bp += 2;
 	    }
 	}
 	if (bp[0] == 't' && bp[1] == '_' && bp[2] && bp[3])
-	    bp += 3;	// skip t_xx, xx may be '-' or '>'
+	    bp += 3;	// skip t_xx, xx may be '-' or '>'/'}'
 	else if (STRNICMP(bp, "char-", 5) == 0)
 	{
 	    vim_str2nr(bp + 5, NULL, &l, STR2NR_ALL, NULL, NULL, 0, TRUE);
@@ -2822,7 +2818,7 @@
 	}
     }
 
-    if (*bp == '>')	// found matching '>'
+    if (*bp == endchar)	// found matching '>' or '}'
     {
 	end_of_name = bp + 1;
 
@@ -2868,12 +2864,12 @@
 		    l = mb_ptr2len(last_dash + off);
 		else
 		    l = 1;
-		if (modifiers != 0 && last_dash[l + off] == '>')
+		if (modifiers != 0 && last_dash[l + off] == endchar)
 		    key = PTR2CHAR(last_dash + off);
 		else
 		{
 		    key = get_special_key_code(last_dash + off);
-		    if (!keep_x_key)
+		    if (!(flags & FSK_KEEP_X_KEY))
 			key = handle_x_keys(key);
 		}
 	    }
@@ -2890,7 +2886,7 @@
 		 */
 		key = simplify_key(key, &modifiers);
 
-		if (!keycode)
+		if (!(flags & FSK_KEYCODE))
 		{
 		    // don't want keycode, use single byte code
 		    if (key == K_BS)
@@ -2902,7 +2898,7 @@
 		// Normal Key with modifier: Try to make a single byte code.
 		if (!IS_SPECIAL(key))
 		    key = extract_modifiers(key, &modifiers,
-						       simplify, did_simplify);
+					   flags & FSK_SIMPLIFY, did_simplify);
 
 		*modp = modifiers;
 		*srcp = end_of_name;
diff --git a/src/option.c b/src/option.c
index 8574f7f..45a6231 100644
--- a/src/option.c
+++ b/src/option.c
@@ -4330,7 +4330,8 @@
     {
 	--arg;			    // put arg at the '<'
 	modifiers = 0;
-	key = find_special_key(&arg, &modifiers, TRUE, TRUE, FALSE, TRUE, NULL);
+	key = find_special_key(&arg, &modifiers,
+			    FSK_KEYCODE | FSK_KEEP_X_KEY | FSK_SIMPLIFY, NULL);
 	if (modifiers)		    // can't handle modifiers here
 	    key = 0;
     }
diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro
index 592c7d1..44f22f2 100644
--- a/src/proto/misc2.pro
+++ b/src/proto/misc2.pro
@@ -68,9 +68,9 @@
 int simplify_key(int key, int *modifiers);
 int handle_x_keys(int key);
 char_u *get_special_key_name(int c, int modifiers);
-int trans_special(char_u **srcp, char_u *dst, int keycode, int in_string, int simplify, int *did_simplify);
+int trans_special(char_u **srcp, char_u *dst, int flags, int *did_simplify);
 int special_to_buf(int key, int modifiers, int keycode, char_u *dst);
-int find_special_key(char_u **srcp, int *modp, int keycode, int keep_x_key, int in_string, int simplify, int *did_simplify);
+int find_special_key(char_u **srcp, int *modp, int flags, int *did_simplify);
 int extract_modifiers(int key, int *modp, int simplify, int *did_simplify);
 int find_special_key_in_table(int c);
 int get_special_key_code(char_u *name);
diff --git a/src/term.c b/src/term.c
index 7c92f3e..f93fde8 100644
--- a/src/term.c
+++ b/src/term.c
@@ -5488,8 +5488,9 @@
 	    }
 #endif
 
-	    slen = trans_special(&src, result + dlen, TRUE, FALSE,
-			     (flags & REPTERM_NO_SIMPLIFY) == 0, did_simplify);
+	    slen = trans_special(&src, result + dlen, FSK_KEYCODE
+			  | ((flags & REPTERM_NO_SIMPLIFY) ? 0 : FSK_SIMPLIFY),
+								 did_simplify);
 	    if (slen)
 	    {
 		dlen += slen;
diff --git a/src/testdir/test_backspace_opt.vim b/src/testdir/test_backspace_opt.vim
index ad051cc..503643a 100644
--- a/src/testdir/test_backspace_opt.vim
+++ b/src/testdir/test_backspace_opt.vim
@@ -86,7 +86,7 @@
 
   set cpo-=<
   inoremap <c-u> <left><c-u>
-  exe "normal Avim3\<C-U>\<Esc>\<CR>"
+  exe "normal Avim3\{C-U}\<Esc>\<CR>"
   iunmap <c-u>
   exe "normal Avim4\<C-U>\<C-U>\<Esc>\<CR>"
 
@@ -96,7 +96,7 @@
   exe "normal A vim6\<Esc>Azwei\<C-G>u\<C-U>\<Esc>\<CR>"
 
   inoremap <c-u> <left><c-u>
-  exe "normal A vim7\<C-U>\<C-U>\<Esc>\<CR>"
+  exe "normal A vim7\{C-U}\{C-U}\<Esc>\<CR>"
 
   call assert_equal([
         \ "1 this shouldn't be deleted",
diff --git a/src/testdir/test_mapping.vim b/src/testdir/test_mapping.vim
index f6e7124..7eb6e34 100644
--- a/src/testdir/test_mapping.vim
+++ b/src/testdir/test_mapping.vim
@@ -76,7 +76,7 @@
   inoremap <c-c> <ctrl-c>
   cnoremap <c-c> dummy
   cunmap <c-c>
-  call feedkeys("GoTEST2: CTRL-C |\<C-C>A|\<Esc>", "xt")
+  call feedkeys("GoTEST2: CTRL-C |\{C-C}A|\<Esc>", "xt")
   call assert_equal('TEST2: CTRL-C |<ctrl-c>A|', getline('$'))
   unmap! <c-c>
   set nomodified
@@ -85,7 +85,7 @@
 func Test_map_ctrl_c_visual()
   " mapping of ctrl-c in Visual mode
   vnoremap <c-c> :<C-u>$put ='vmap works'
-  call feedkeys("GV\<C-C>\<CR>", "xt")
+  call feedkeys("GV\{C-C}\<CR>", "xt")
   call assert_equal('vmap works', getline('$'))
   vunmap <c-c>
   set nomodified
@@ -235,7 +235,7 @@
 
 func Test_map_meta_quotes()
   imap <M-"> foo
-  call feedkeys("Go-\<M-\">-\<Esc>", "xt")
+  call feedkeys("Go-\{M-\"}-\<Esc>", "xt")
   call assert_equal("-foo-", getline('$'))
   set nomodified
   iunmap <M-">
diff --git a/src/testdir/test_messages.vim b/src/testdir/test_messages.vim
index b74ad2c..832762a 100644
--- a/src/testdir/test_messages.vim
+++ b/src/testdir/test_messages.vim
@@ -309,7 +309,7 @@
 func Test_mapping_at_hit_return_prompt()
   nnoremap <C-B> :echo "hit ctrl-b"<CR>
   call feedkeys(":ls\<CR>", "xt")
-  call feedkeys("\<C-B>", "xt")
+  call feedkeys("\{C-B}", "xt")
   call assert_match('hit ctrl-b', Screenline(&lines - 1))
   nunmap <C-B>
 endfunc
diff --git a/src/typval.c b/src/typval.c
index cd2a862..95b2792 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -1285,15 +1285,24 @@
 			  ++name;
 			  break;
 
-			    // Special key, e.g.: "\<C-W>"
-		case '<': extra = trans_special(&p, name, TRUE, TRUE,
-								   TRUE, NULL);
-			  if (extra != 0)
+			  // Special key, e.g.: "\<C-W>" or "\{C-W}"
+		case '<':
+		case '{':
 			  {
-			      name += extra;
-			      if (name >= rettv->vval.v_string + len)
-				  iemsg("get_string_tv() used more space than allocated");
-			      break;
+			      int flags = FSK_KEYCODE | FSK_IN_STRING;
+
+			      if (*p == '<')
+				  flags |= FSK_SIMPLIFY;
+			      else
+				  flags |= FSK_CURLY;
+			      extra = trans_special(&p, name, flags, NULL);
+			      if (extra != 0)
+			      {
+				  name += extra;
+				  if (name >= rettv->vval.v_string + len)
+				      iemsg("get_string_tv() used more space than allocated");
+				  break;
+			      }
 			  }
 			  // FALLTHROUGH
 
diff --git a/src/version.c b/src/version.c
index 6fe96a3..b3aa840 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,6 +747,8 @@
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    855,
+/**/
     854,
 /**/
     853,
diff --git a/src/vim.h b/src/vim.h
index 68cf943..4fc982a 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -2661,4 +2661,11 @@
 #define EVAL_EVALUATE	    1	    // when missing don't actually evaluate
 #define EVAL_CONSTANT	    2	    // when not a constant return FAIL
 
+// Flags for find_special_key()
+#define FSK_KEYCODE	0x01	// prefer key code, e.g. K_DEL instead of DEL
+#define FSK_KEEP_X_KEY	0x02	// don't translate xHome to Home key
+#define FSK_IN_STRING	0x04	// TRUE in string, double quote is escaped
+#define FSK_SIMPLIFY	0x08	// simplify <C-H> and <A-x>
+#define FSK_CURLY	0x10	// {C-x} instead of <C-x>
+
 #endif // VIM__H