/* * Check if if there is a special key code for "key" that includes the * modifiers specified. */ int simplify_key(int key, int *modifiers) { int i; int key0; int key1; if (*modifiers & (MOD_MASK_SHIFT | MOD_MASK_CTRL | MOD_MASK_ALT)) { /* TAB is a special case */ if (key == TAB && (*modifiers & MOD_MASK_SHIFT)) { *modifiers &= ~MOD_MASK_SHIFT; return K_S_TAB; } key0 = KEY2TERMCAP0(key); key1 = KEY2TERMCAP1(key); for (i = 0; modifier_keys_table[i] != NUL; i += MOD_KEYS_ENTRY_SIZE) if (key0 == modifier_keys_table[i + 3] && key1 == modifier_keys_table[i + 4] && (*modifiers & modifier_keys_table[i])) { *modifiers &= ~modifier_keys_table[i]; return TERMCAP2KEY(modifier_keys_table[i + 1], modifier_keys_table[i + 2]); } } return key; }
/* * Try translating a <> name at (*srcp)[] to dst[]. * Return the number of characters added to dst[], zero for no match. * If there is a match, srcp is advanced to after the <> name. * dst[] must be big enough to hold the result (up to six characters)! */ int trans_special ( char_u **srcp, char_u *dst, int keycode /* prefer key code, e.g. K_DEL instead of DEL */ ) { int modifiers = 0; int key; int dlen = 0; key = find_special_key(srcp, &modifiers, keycode, FALSE); if (key == 0) return 0; /* Put the appropriate modifier in a string */ if (modifiers != 0) { dst[dlen++] = K_SPECIAL; dst[dlen++] = KS_MODIFIER; dst[dlen++] = modifiers; } if (IS_SPECIAL(key)) { dst[dlen++] = K_SPECIAL; dst[dlen++] = KEY2TERMCAP0(key); dst[dlen++] = KEY2TERMCAP1(key); } else if (has_mbyte && !keycode) dlen += (*mb_char2bytes)(key, dst + dlen); else if (keycode) dlen = (int)(add_char2buf(key, dst + dlen) - dst); else dst[dlen++] = key; return dlen; }
/* * Try translating a <> name at (*srcp)[] to dst[]. * Return the number of characters added to dst[], zero for no match. * If there is a match, srcp is advanced to after the <> name. * dst[] must be big enough to hold the result (up to six characters)! */ unsigned int trans_special ( char_u **srcp, char_u *dst, int keycode /* prefer key code, e.g. K_DEL instead of DEL */ ) { int modifiers = 0; int key; unsigned int dlen = 0; key = find_special_key(srcp, &modifiers, keycode, FALSE); if (key == 0) return 0; /* Put the appropriate modifier in a string */ if (modifiers != 0) { dst[dlen++] = K_SPECIAL; dst[dlen++] = KS_MODIFIER; dst[dlen++] = (char_u)modifiers; } if (IS_SPECIAL(key)) { dst[dlen++] = K_SPECIAL; dst[dlen++] = (char_u)KEY2TERMCAP0(key); dst[dlen++] = KEY2TERMCAP1(key); } else if (has_mbyte && !keycode) dlen += (unsigned int)(*mb_char2bytes)(key, dst + dlen); else if (keycode) { char_u *after = add_char2buf(key, dst + dlen); assert(after >= dst && (uintmax_t)(after - dst) <= UINT_MAX); dlen = (unsigned int)(after - dst); } else dst[dlen++] = (char_u)key; return dlen; }
unsigned int trans_special(const char_u **srcp, const size_t src_len, char_u *const dst, const bool keycode, const bool in_string) { int modifiers = 0; int key; unsigned int dlen = 0; key = find_special_key(srcp, src_len, &modifiers, keycode, false, in_string); if (key == 0) { return 0; } // Put the appropriate modifier in a string. if (modifiers != 0) { dst[dlen++] = K_SPECIAL; dst[dlen++] = KS_MODIFIER; dst[dlen++] = (char_u)modifiers; } if (IS_SPECIAL(key)) { dst[dlen++] = K_SPECIAL; dst[dlen++] = (char_u)KEY2TERMCAP0(key); dst[dlen++] = KEY2TERMCAP1(key); } else if (has_mbyte && !keycode) { dlen += (unsigned int)(*mb_char2bytes)(key, dst + dlen); } else if (keycode) { char_u *after = add_char2buf(key, dst + dlen); assert(after >= dst && (uintmax_t)(after - dst) <= UINT_MAX); dlen = (unsigned int)(after - dst); } else { dst[dlen++] = (char_u)key; } return dlen; }
/* * Return a string which contains the name of the given key when the given * modifiers are down. */ char_u *get_special_key_name(int c, int modifiers) { static char_u string[MAX_KEY_NAME_LEN + 1]; int i, idx; int table_idx; char_u *s; string[0] = '<'; idx = 1; /* Key that stands for a normal character. */ if (IS_SPECIAL(c) && KEY2TERMCAP0(c) == KS_KEY) c = KEY2TERMCAP1(c); /* * Translate shifted special keys into unshifted keys and set modifier. * Same for CTRL and ALT modifiers. */ if (IS_SPECIAL(c)) { for (i = 0; modifier_keys_table[i] != 0; i += MOD_KEYS_ENTRY_SIZE) if ( KEY2TERMCAP0(c) == (int)modifier_keys_table[i + 1] && (int)KEY2TERMCAP1(c) == (int)modifier_keys_table[i + 2]) { modifiers |= modifier_keys_table[i]; c = TERMCAP2KEY(modifier_keys_table[i + 3], modifier_keys_table[i + 4]); break; } } /* try to find the key in the special key table */ table_idx = find_special_key_in_table(c); /* * When not a known special key, and not a printable character, try to * extract modifiers. */ if (c > 0 && (*mb_char2len)(c) == 1 ) { if (table_idx < 0 && (!vim_isprintc(c) || (c & 0x7f) == ' ') && (c & 0x80)) { c &= 0x7f; modifiers |= MOD_MASK_ALT; /* try again, to find the un-alted key in the special key table */ table_idx = find_special_key_in_table(c); } if (table_idx < 0 && !vim_isprintc(c) && c < ' ') { c += '@'; modifiers |= MOD_MASK_CTRL; } } /* translate the modifier into a string */ for (i = 0; mod_mask_table[i].name != 'A'; i++) if ((modifiers & mod_mask_table[i].mod_mask) == mod_mask_table[i].mod_flag) { string[idx++] = mod_mask_table[i].name; string[idx++] = (char_u)'-'; } if (table_idx < 0) { /* unknown special key, may output t_xx */ if (IS_SPECIAL(c)) { string[idx++] = 't'; string[idx++] = '_'; string[idx++] = (char_u)KEY2TERMCAP0(c); string[idx++] = KEY2TERMCAP1(c); } /* Not a special key, only modifiers, output directly */ else { if (has_mbyte && (*mb_char2len)(c) > 1) idx += (*mb_char2bytes)(c, string + idx); else if (vim_isprintc(c)) string[idx++] = (char_u)c; else { s = transchar(c); while (*s) string[idx++] = *s++; } } } else { /* use name of special key */ STRCPY(string + idx, key_names_table[table_idx].name); idx = (int)STRLEN(string); } string[idx++] = '>'; string[idx] = NUL; return string; }