forked from aniani/vim
patch 9.0.1220: termcap/terminfo entries do not indicate possible modifiers
Problem: Termcap/terminfo entries do not indicate where modifiers might appear. Solution: Add ";*" for function keys where modifiers are likely to be used.
This commit is contained in:
82
src/term.c
82
src/term.c
@@ -65,6 +65,7 @@ static void del_termcode_idx(int idx);
|
|||||||
static int find_term_bykeys(char_u *src);
|
static int find_term_bykeys(char_u *src);
|
||||||
static int term_is_builtin(char_u *name);
|
static int term_is_builtin(char_u *name);
|
||||||
static int term_7to8bit(char_u *p);
|
static int term_7to8bit(char_u *p);
|
||||||
|
static void accept_modifiers_for_function_keys(void);
|
||||||
|
|
||||||
// Change this to "if 1" to debug what happens with termresponse.
|
// Change this to "if 1" to debug what happens with termresponse.
|
||||||
# if 0
|
# if 0
|
||||||
@@ -2097,6 +2098,11 @@ set_termname(char_u *term)
|
|||||||
&& term_strings_not_set(KS_8U))
|
&& term_strings_not_set(KS_8U))
|
||||||
apply_builtin_tcap(term, builtin_rgb, TRUE);
|
apply_builtin_tcap(term, builtin_rgb, TRUE);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (kpc != KEYPROTOCOL_NONE)
|
||||||
|
// Some function keys may accept modifiers even though the
|
||||||
|
// terminfo/termcap entry does not indicate this.
|
||||||
|
accept_modifiers_for_function_keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -2212,6 +2218,9 @@ set_termname(char_u *term)
|
|||||||
|
|
||||||
#ifdef FEAT_MOUSE_XTERM
|
#ifdef FEAT_MOUSE_XTERM
|
||||||
// Focus reporting is supported by xterm compatible terminals and tmux.
|
// Focus reporting is supported by xterm compatible terminals and tmux.
|
||||||
|
// We hard-code the received escape sequences here. There are the terminfo
|
||||||
|
// entries kxIN and kxOUT, but they are rarely used and do hot have a
|
||||||
|
// two-letter termcap name.
|
||||||
if (use_xterm_like_mouse(term))
|
if (use_xterm_like_mouse(term))
|
||||||
{
|
{
|
||||||
char_u name[3];
|
char_u name[3];
|
||||||
@@ -4470,6 +4479,25 @@ clear_termcodes(void)
|
|||||||
|
|
||||||
#define ATC_FROM_TERM 55
|
#define ATC_FROM_TERM 55
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For xterm we recognize special codes like "ESC[42;*X" and "ESC O*X" that
|
||||||
|
* accept modifiers.
|
||||||
|
* Set "termcodes[idx].modlen".
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
adjust_modlen(int idx)
|
||||||
|
{
|
||||||
|
termcodes[idx].modlen = 0;
|
||||||
|
int j = termcode_star(termcodes[idx].code, termcodes[idx].len);
|
||||||
|
if (j <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
termcodes[idx].modlen = termcodes[idx].len - 1 - j;
|
||||||
|
// For "CSI[@;X" the "@" is not included in "modlen".
|
||||||
|
if (termcodes[idx].code[termcodes[idx].modlen - 1] == '@')
|
||||||
|
--termcodes[idx].modlen;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add a new entry for "name[2]" to the list of terminal codes.
|
* Add a new entry for "name[2]" to the list of terminal codes.
|
||||||
* Note that "name" may not have a terminating NUL.
|
* Note that "name" may not have a terminating NUL.
|
||||||
@@ -4618,21 +4646,53 @@ add_termcode(char_u *name, char_u *string, int flags)
|
|||||||
termcodes[i].name[1] = name[1];
|
termcodes[i].name[1] = name[1];
|
||||||
termcodes[i].code = s;
|
termcodes[i].code = s;
|
||||||
termcodes[i].len = len;
|
termcodes[i].len = len;
|
||||||
|
adjust_modlen(i);
|
||||||
|
|
||||||
// For xterm we recognize special codes like "ESC[42;*X" and "ESC O*X" that
|
|
||||||
// accept modifiers.
|
|
||||||
termcodes[i].modlen = 0;
|
|
||||||
j = termcode_star(s, len);
|
|
||||||
if (j > 0)
|
|
||||||
{
|
|
||||||
termcodes[i].modlen = len - 1 - j;
|
|
||||||
// For "CSI[@;X" the "@" is not included in "modlen".
|
|
||||||
if (termcodes[i].code[termcodes[i].modlen - 1] == '@')
|
|
||||||
--termcodes[i].modlen;
|
|
||||||
}
|
|
||||||
++tc_len;
|
++tc_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some function keys may include modifiers, but the terminfo/termcap entries
|
||||||
|
* do not indicate that. Insert ";*" where we expect modifiers might appear.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
accept_modifiers_for_function_keys(void)
|
||||||
|
{
|
||||||
|
regmatch_T regmatch;
|
||||||
|
CLEAR_FIELD(regmatch);
|
||||||
|
regmatch.rm_ic = TRUE;
|
||||||
|
regmatch.regprog = vim_regcomp((char_u *)"^\033[\\d\\+\\~$", RE_MAGIC);
|
||||||
|
|
||||||
|
for (int i = 0; i < tc_len; ++i)
|
||||||
|
{
|
||||||
|
if (regmatch.regprog == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// skip PasteStart and PasteEnd
|
||||||
|
if (termcodes[i].name[0] == 'P'
|
||||||
|
&& (termcodes[i].name[1] == 'S' || termcodes[i].name[1] == 'E'))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
char_u *s = termcodes[i].code;
|
||||||
|
if (s != NULL && vim_regexec(®match, s, (colnr_T)0))
|
||||||
|
{
|
||||||
|
size_t len = STRLEN(s);
|
||||||
|
char_u *ns = alloc(len + 3);
|
||||||
|
if (ns != NULL)
|
||||||
|
{
|
||||||
|
mch_memmove(ns, s, len - 1);
|
||||||
|
mch_memmove(ns + len - 1, ";*~", 4);
|
||||||
|
vim_free(s);
|
||||||
|
termcodes[i].code = ns;
|
||||||
|
termcodes[i].len += 2;
|
||||||
|
adjust_modlen(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vim_regfree(regmatch.regprog);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check termcode "code[len]" for ending in ;*X or *X.
|
* Check termcode "code[len]" for ending in ;*X or *X.
|
||||||
* The "X" can be any character.
|
* The "X" can be any character.
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
1220,
|
||||||
/**/
|
/**/
|
||||||
1219,
|
1219,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user