changeset 31281:cab7d8accab7 v9.0.0974

patch 9.0.0974: even when Esc is encoded a timeout is used Commit: https://github.com/vim/vim/commit/dffa6ea85c82bbcb60368f38f7437c6cd89c9e55 Author: Bram Moolenaar <Bram@vim.org> Date: Tue Nov 29 20:33:20 2022 +0000 patch 9.0.0974: even when Esc is encoded a timeout is used Problem: Even when Esc is encoded a timeout is used. Solution: Use K_ESC when an encoded Esc is found.
author Bram Moolenaar <Bram@vim.org>
date Tue, 29 Nov 2022 21:45:04 +0100
parents 9642e1e4f0b8
children 89c8a30a5407
files src/getchar.c src/keymap.h src/term.c src/version.c
diffstat 4 files changed, 33 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1765,6 +1765,12 @@ vgetc(void)
 		}
 		c = TO_SPECIAL(c2, c);
 
+		// K_ESC is used to avoid ambiguity with the single Esc
+		// character that might be the start of an escape sequence.
+		// Convert it back to a single Esc here.
+		if (c == K_ESC)
+		    c = ESC;
+
 #if defined(FEAT_GUI_MSWIN) && defined(FEAT_MENU) && defined(FEAT_TEAROFF)
 		// Handle K_TEAROFF here, the caller of vgetc() doesn't need to
 		// know that a menu was torn off
@@ -3913,6 +3919,12 @@ getcmdkeycmd(
 		continue;
 	    }
 	    c1 = TO_SPECIAL(c1, c2);
+
+	    // K_ESC is used to avoid ambiguity with the single Esc character
+	    // that might be the start of an escape sequence.  Convert it back
+	    // to a single Esc here.
+	    if (c1 == K_ESC)
+		c1 = ESC;
 	}
 	if (c1 == Ctrl_V)
 	{
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -278,13 +278,16 @@ enum key_extra
     , KE_SCRIPT_COMMAND = 104	// <ScriptCmd> special key
     , KE_S_BS = 105		// shift + <BS>
     , KE_SID = 106		// <SID> special key, followed by {nr};
+    , KE_ESC = 107		// used for K_ESC
 };
 
 /*
- * the three byte codes are replaced with the following int when using vgetc()
+ * The three-byte codes are replaced with a negative number when using vgetc().
  */
 #define K_ZERO		TERMCAP2KEY(KS_ZERO, KE_FILLER)
 
+#define K_ESC		TERMCAP2KEY(KS_EXTRA, KE_ESC)
+
 #define K_UP		TERMCAP2KEY('k', 'u')
 #define K_DOWN		TERMCAP2KEY('k', 'd')
 #define K_LEFT		TERMCAP2KEY('k', 'l')
@@ -295,10 +298,12 @@ enum key_extra
 #define K_C_LEFT	TERMCAP2KEY(KS_EXTRA, KE_C_LEFT)
 #define K_S_RIGHT	TERMCAP2KEY('%', 'i')
 #define K_C_RIGHT	TERMCAP2KEY(KS_EXTRA, KE_C_RIGHT)
+
 #define K_S_HOME	TERMCAP2KEY('#', '2')
 #define K_C_HOME	TERMCAP2KEY(KS_EXTRA, KE_C_HOME)
 #define K_S_END		TERMCAP2KEY('*', '7')
 #define K_C_END		TERMCAP2KEY(KS_EXTRA, KE_C_END)
+
 #define K_TAB		TERMCAP2KEY(KS_EXTRA, KE_TAB)
 #define K_S_TAB		TERMCAP2KEY('k', 'B')
 #define K_S_BS		TERMCAP2KEY(KS_EXTRA, KE_S_BS)
--- a/src/term.c
+++ b/src/term.c
@@ -5121,7 +5121,19 @@ handle_key_without_modifier(
 	int	*buflen)
 {
     char_u  string[MAX_KEY_CODE_LEN + 1];
-    int	    new_slen = add_key_to_buf(arg[0], string);
+    int	    new_slen;
+
+    if (arg[0] == ESC)
+    {
+	// Putting Esc in the buffer creates ambiguity, it can be the start of
+	// an escape sequence.  Use K_ESC to avoid that.
+	string[0] = K_SPECIAL;
+	string[1] = KS_EXTRA;
+	string[2] = KE_ESC;
+	new_slen = 3;
+    }
+    else
+	new_slen = add_key_to_buf(arg[0], string);
 
     if (put_string_in_typebuf(offset, csi_len, string, new_slen,
 						 buf, bufsize, buflen) == FAIL)
--- 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 */
 /**/
+    974,
+/**/
     973,
 /**/
     972,