changeset 11557:7e5e76d8d451 v8.0.0661

patch 8.0.0661: recognizing urxvt mouse codes does not work well commit https://github.com/vim/vim/commit/a529ce068ba84d53343f3732b6a1ed4ad1fe3a68 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jun 22 22:37:57 2017 +0200 patch 8.0.0661: recognizing urxvt mouse codes does not work well Problem: Recognizing urxvt mouse codes does not work well. Solution: Recognize "Esc[*M" and "Esc[*m". (Maurice Bos, closes https://github.com/vim/vim/issues/1486)
author Christian Brabandt <cb@256bit.org>
date Thu, 22 Jun 2017 22:45:04 +0200
parents 92e04864687e
children 094d9d2996d3
files src/keymap.h src/misc2.c src/os_unix.c src/term.c src/version.c
diffstat 5 files changed, 43 insertions(+), 53 deletions(-) [+]
line wrap: on
line diff
--- a/src/keymap.h
+++ b/src/keymap.h
@@ -112,6 +112,7 @@
 
 /* Used for the sgr mouse. */
 #define KS_SGR_MOUSE		237
+#define KS_SGR_MOUSE_RELEASE		236 /* Release */
 
 /*
  * Filler used after KS_SPECIAL and others
@@ -416,6 +417,7 @@ enum key_extra
 #define K_PTERM_MOUSE	TERMCAP2KEY(KS_PTERM_MOUSE, KE_FILLER)
 #define K_URXVT_MOUSE	TERMCAP2KEY(KS_URXVT_MOUSE, KE_FILLER)
 #define K_SGR_MOUSE	TERMCAP2KEY(KS_SGR_MOUSE, KE_FILLER)
+#define K_SGR_MOUSERELEASE TERMCAP2KEY(KS_SGR_MOUSE_RELEASE, KE_FILLER)
 
 #define K_SELECT	TERMCAP2KEY(KS_SELECT, KE_FILLER)
 #define K_TEAROFF	TERMCAP2KEY(KS_TEAROFF, KE_FILLER)
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -2438,6 +2438,7 @@ static struct key_name_entry
 #endif
 #ifdef FEAT_MOUSE_SGR
     {K_SGR_MOUSE,	(char_u *)"SgrMouse"},
+    {K_SGR_MOUSERELEASE, (char_u *)"SgrMouseRelelase"},
 #endif
     {K_LEFTMOUSE,	(char_u *)"LeftMouse"},
     {K_LEFTMOUSE_NM,	(char_u *)"LeftMouseNM"},
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3771,7 +3771,6 @@ check_mouse_termcode(void)
 	del_mouse_termcode(KS_PTERM_MOUSE);
 # endif
 # ifdef FEAT_MOUSE_URXVT
-    /* same conflict as the dec mouse */
     if (use_xterm_mouse() == 3
 #  ifdef FEAT_GUI
 	    && !gui.in_use
@@ -3779,8 +3778,8 @@ check_mouse_termcode(void)
 	    )
     {
 	set_mouse_termcode(KS_URXVT_MOUSE, (char_u *)(term_is_8bit(T_NAME)
-		    ? IF_EB("\233", CSI_STR)
-		    : IF_EB("\033[", ESC_STR "[")));
+		    ? IF_EB("\233*M", CSI_STR "*M")
+		    : IF_EB("\033[*M", ESC_STR "[*M")));
 
 	if (*p_mouse != NUL)
 	{
@@ -3792,7 +3791,6 @@ check_mouse_termcode(void)
 	del_mouse_termcode(KS_URXVT_MOUSE);
 # endif
 # ifdef FEAT_MOUSE_SGR
-    /* There is no conflict with xterm mouse */
     if (use_xterm_mouse() == 4
 #  ifdef FEAT_GUI
 	    && !gui.in_use
@@ -3800,8 +3798,12 @@ check_mouse_termcode(void)
 	    )
     {
 	set_mouse_termcode(KS_SGR_MOUSE, (char_u *)(term_is_8bit(T_NAME)
-		    ? IF_EB("\233<", CSI_STR "<")
-		    : IF_EB("\033[<", ESC_STR "[<")));
+		    ? IF_EB("\233<*M", CSI_STR "<*M")
+		    : IF_EB("\033[<*M", ESC_STR "[<*M")));
+
+	set_mouse_termcode(KS_SGR_MOUSE_RELEASE, (char_u *)(term_is_8bit(T_NAME)
+		    ? IF_EB("\233<*m", CSI_STR "<*m")
+		    : IF_EB("\033[<*m", ESC_STR "[<*m")));
 
 	if (*p_mouse != NUL)
 	{
@@ -3810,7 +3812,10 @@ check_mouse_termcode(void)
 	}
     }
     else
+    {
 	del_mouse_termcode(KS_SGR_MOUSE);
+	del_mouse_termcode(KS_SGR_MOUSE_RELEASE);
+    }
 # endif
 }
 #endif
--- a/src/term.c
+++ b/src/term.c
@@ -3786,9 +3786,9 @@ add_termcode(char_u *name, char_u *strin
 }
 
 /*
- * Check termcode "code[len]" for ending in ;*X, <Esc>O*X or <M-O>*X.
+ * Check termcode "code[len]" for ending in ;*X or *X.
  * The "X" can be any character.
- * Return 0 if not found, 2 for ;*X and 1 for O*X and <M-O>*X.
+ * Return 0 if not found, 2 for ;*X and 1 for *X.
  */
     static int
 termcode_star(char_u *code, int len)
@@ -3798,7 +3798,7 @@ termcode_star(char_u *code, int len)
     {
 	if (len >= 5 && code[len - 3] == ';')
 	    return 2;
-	if ((len >= 4 && code[len - 3] == 'O') || code[len - 3] == 'O' + 128)
+	else
 	    return 1;
     }
     return 0;
@@ -3940,6 +3940,7 @@ check_termcode(
     int		offset;
     char_u	key_name[2];
     int		modifiers;
+    char_u	*modifiers_start;
     int		key;
     int		new_slen;
     int		extra;
@@ -4065,6 +4066,7 @@ check_termcode(
 		 * But only when the 'K' flag is in 'cpoptions'.
 		 */
 		slen = termcodes[idx].len;
+		modifiers_start = NULL;
 		if (cpo_koffset && offset && len < slen)
 		    continue;
 		if (STRNCMP(termcodes[idx].code, tp,
@@ -4125,7 +4127,7 @@ check_termcode(
 			{
 			    /* Skip over the digits, the final char must
 			     * follow. */
-			    for (j = slen - 2; j < len && isdigit(tp[j]); ++j)
+			    for (j = slen - 2; j < len && (isdigit(tp[j]) || tp[j] == ';'); ++j)
 				;
 			    ++j;
 			    if (len < j)	/* got a partial sequence */
@@ -4133,8 +4135,10 @@ check_termcode(
 			    if (tp[j - 1] != termcodes[idx].code[slen - 1])
 				continue;	/* no match */
 
+			    modifiers_start = tp + slen - 2;
+
 			    /* Match!  Convert modifier bits. */
-			    n = atoi((char *)tp + slen - 2) - 1;
+			    n = atoi((char *)modifiers_start) - 1;
 			    if (n & 1)
 				modifiers |= MOD_MASK_SHIFT;
 			    if (n & 2)
@@ -4156,7 +4160,7 @@ check_termcode(
 
 #ifdef FEAT_TERMRESPONSE
 	if (key_name[0] == NUL
-	    /* Mouse codes of DEC, pterm, and URXVT start with <ESC>[.  When
+	    /* Mouse codes of DEC and pterm start with <ESC>[.  When
 	     * detecting the start of these mouse codes they might as well be
 	     * another key code or terminal response. */
 # ifdef FEAT_MOUSE_DEC
@@ -4165,9 +4169,6 @@ check_termcode(
 # ifdef FEAT_MOUSE_PTERM
 	    || key_name[0] == KS_PTERM_MOUSE
 # endif
-# ifdef FEAT_MOUSE_URXVT
-	    || key_name[0] == KS_URXVT_MOUSE
-# endif
 	   )
 	{
 	    /* Check for some responses from the terminal starting with
@@ -4509,6 +4510,7 @@ check_termcode(
 # endif
 # ifdef FEAT_MOUSE_SGR
 		|| key_name[0] == KS_SGR_MOUSE
+		|| key_name[0] == KS_SGR_MOUSE_RELEASE
 # endif
 		)
 	{
@@ -4592,7 +4594,8 @@ check_termcode(
 
 # if defined(FEAT_MOUSE_URXVT) || defined(FEAT_MOUSE_SGR)
 	    if (key_name[0] == KS_URXVT_MOUSE
-		|| key_name[0] == KS_SGR_MOUSE)
+		|| key_name[0] == KS_SGR_MOUSE
+		|| key_name[0] == KS_SGR_MOUSE_RELEASE)
 	    {
 		for (;;)
 		{
@@ -4619,56 +4622,32 @@ check_termcode(
 		     *	        ^----- column
 		     *	     ^-------- code
 		     */
-		    p = tp + slen;
+		    p = modifiers_start;
+		    if (p == NULL)
+			return -1;
 
 		    mouse_code = getdigits(&p);
 		    if (*p++ != ';')
 			return -1;
 
 		    /* when mouse reporting is SGR, add 32 to mouse code */
-		    if (key_name[0] == KS_SGR_MOUSE)
+		    if (key_name[0] == KS_SGR_MOUSE
+					|| key_name[0] == KS_SGR_MOUSE_RELEASE)
 			mouse_code += 32;
 
+		    if (key_name[0] == KS_SGR_MOUSE_RELEASE)
+			mouse_code |= MOUSE_RELEASE;
+
 		    mouse_col = getdigits(&p) - 1;
 		    if (*p++ != ';')
 			return -1;
 
 		    mouse_row = getdigits(&p) - 1;
-		    if (key_name[0] == KS_SGR_MOUSE && *p == 'm')
-			mouse_code |= MOUSE_RELEASE;
-		    else if (*p != 'M')
-			return -1;
-		    p++;
-
-		    slen += (int)(p - (tp + slen));
-
-		    /* skip this one if next one has same code (like xterm
-		     * case) */
-		    j = termcodes[idx].len;
-		    if (STRNCMP(tp, tp + slen, (size_t)j) == 0)
-		    {
-			int slen2;
-			int cmd_complete = 0;
-
-			/* check if the command is complete by looking for the
-			 * 'M' */
-			for (slen2 = slen; slen2 < len; slen2++)
-			{
-			    if (tp[slen2] == 'M'
-				    || (key_name[0] == KS_SGR_MOUSE
-							 && tp[slen2] == 'm'))
-			    {
-				cmd_complete = 1;
-				break;
-			    }
-			}
-			p += j;
-			if (cmd_complete && getdigits(&p) == mouse_code)
-			{
-			    slen += j; /* skip the \033[ */
-			    continue;
-			}
-		    }
+
+		    /* The modifiers were the mouse coordinates, not the
+		     * modifier keys (alt/shift/ctrl/meta) state. */
+		    modifiers = 0;
+
 		    break;
 		}
 	    }
@@ -4680,6 +4659,7 @@ check_termcode(
 #endif
 #ifdef FEAT_MOUSE_SGR
 	    || key_name[0] == KS_SGR_MOUSE
+	    || key_name[0] == KS_SGR_MOUSE_RELEASE
 #endif
 	    )
 	{
--- a/src/version.c
+++ b/src/version.c
@@ -765,6 +765,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    661,
+/**/
     660,
 /**/
     659,