# HG changeset patch # User Christian Brabandt # Date 1498164304 -7200 # Node ID 7e5e76d8d451d9ca6402f9e2726a5a9042ce3f98 # Parent 92e04864687e1cd0db425fac12803304f0f80d66 patch 8.0.0661: recognizing urxvt mouse codes does not work well commit https://github.com/vim/vim/commit/a529ce068ba84d53343f3732b6a1ed4ad1fe3a68 Author: Bram Moolenaar 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) diff --git a/src/keymap.h b/src/keymap.h --- 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) diff --git a/src/misc2.c b/src/misc2.c --- 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"}, diff --git a/src/os_unix.c b/src/os_unix.c --- 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 diff --git a/src/term.c b/src/term.c --- 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, O*X or *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 *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 [. When + /* Mouse codes of DEC and pterm start with [. 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 ) { diff --git a/src/version.c b/src/version.c --- 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,