Mercurial > vim
comparison src/getchar.c @ 20727:5ffe112b1afd v8.2.0916
patch 8.2.0916: mapping with partly modifyOtherKeys code does not work
Commit: https://github.com/vim/vim/commit/975a880a1389e8ce6dea8d66a7c109140b2f94ec
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Jun 6 22:36:24 2020 +0200
patch 8.2.0916: mapping with partly modifyOtherKeys code does not work
Problem: Mapping with partly modifyOtherKeys code does not work.
Solution: If there is no mapping with a separate modifier include the
modifier in the key and then try mapping again. (closes #6200)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 06 Jun 2020 22:45:04 +0200 |
parents | fbee68c6aab1 |
children | e3078150144d |
comparison
equal
deleted
inserted
replaced
20726:ac788439fa5a | 20727:5ffe112b1afd |
---|---|
1580 count = 0; | 1580 count = 0; |
1581 } | 1581 } |
1582 } | 1582 } |
1583 | 1583 |
1584 /* | 1584 /* |
1585 * Convert "c" plus "mod_mask" to merge the effect of modifyOtherKeys into the | 1585 * Convert "c" plus "modifiers" to merge the effect of modifyOtherKeys into the |
1586 * character. | 1586 * character. |
1587 */ | 1587 */ |
1588 int | 1588 int |
1589 merge_modifyOtherKeys(int c_arg) | 1589 merge_modifyOtherKeys(int c_arg, int *modifiers) |
1590 { | 1590 { |
1591 int c = c_arg; | 1591 int c = c_arg; |
1592 | 1592 |
1593 if (mod_mask & MOD_MASK_CTRL) | 1593 if (*modifiers & MOD_MASK_CTRL) |
1594 { | 1594 { |
1595 if ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_')) | 1595 if ((c >= '`' && c <= 0x7f) || (c >= '@' && c <= '_')) |
1596 c &= 0x1f; | 1596 c &= 0x1f; |
1597 else if (c == '6') | 1597 else if (c == '6') |
1598 // CTRL-6 is equivalent to CTRL-^ | 1598 // CTRL-6 is equivalent to CTRL-^ |
1610 c = BS; | 1610 c = BS; |
1611 else if (c == '?') | 1611 else if (c == '?') |
1612 c = DEL; | 1612 c = DEL; |
1613 #endif | 1613 #endif |
1614 if (c != c_arg) | 1614 if (c != c_arg) |
1615 mod_mask &= ~MOD_MASK_CTRL; | 1615 *modifiers &= ~MOD_MASK_CTRL; |
1616 } | 1616 } |
1617 if ((mod_mask & (MOD_MASK_META | MOD_MASK_ALT)) | 1617 if ((*modifiers & (MOD_MASK_META | MOD_MASK_ALT)) |
1618 && c >= 0 && c <= 127) | 1618 && c >= 0 && c <= 127) |
1619 { | 1619 { |
1620 c += 0x80; | 1620 c += 0x80; |
1621 mod_mask &= ~(MOD_MASK_META|MOD_MASK_ALT); | 1621 *modifiers &= ~(MOD_MASK_META|MOD_MASK_ALT); |
1622 } | 1622 } |
1623 return c; | 1623 return c; |
1624 } | 1624 } |
1625 | 1625 |
1626 /* | 1626 /* |
1864 // keys. Shift would already have been applied. | 1864 // keys. Shift would already have been applied. |
1865 // Remember the character and mod_mask from before, in some | 1865 // Remember the character and mod_mask from before, in some |
1866 // cases they are put back in the typeahead buffer. | 1866 // cases they are put back in the typeahead buffer. |
1867 vgetc_mod_mask = mod_mask; | 1867 vgetc_mod_mask = mod_mask; |
1868 vgetc_char = c; | 1868 vgetc_char = c; |
1869 c = merge_modifyOtherKeys(c); | 1869 c = merge_modifyOtherKeys(c, &mod_mask); |
1870 } | 1870 } |
1871 | 1871 |
1872 break; | 1872 break; |
1873 } | 1873 } |
1874 } | 1874 } |
2250 && c == K_SPECIAL | 2250 && c == K_SPECIAL |
2251 && p[1] == KS_MODIFIER | 2251 && p[1] == KS_MODIFIER |
2252 && (p[2] & MOD_MASK_CTRL)) | 2252 && (p[2] & MOD_MASK_CTRL)) |
2253 c = p[3] & 0x1f; | 2253 c = p[3] & 0x1f; |
2254 return vim_is_ctrl_x_key(c); | 2254 return vim_is_ctrl_x_key(c); |
2255 } | |
2256 | |
2257 /* | |
2258 * Check if typebuf.tb_buf[] contains a modifer plus key that can be changed | |
2259 * into just a key, apply that. | |
2260 * Check from typebuf.tb_buf[typebuf.tb_off] to typebuf.tb_buf[typebuf.tb_off | |
2261 * + "max_offset"]. | |
2262 * Return the length of the replaced bytes, zero if nothing changed. | |
2263 */ | |
2264 static int | |
2265 check_simplify_modifier(int max_offset) | |
2266 { | |
2267 int offset; | |
2268 char_u *tp; | |
2269 | |
2270 for (offset = 0; offset < max_offset; ++offset) | |
2271 { | |
2272 if (offset + 3 >= typebuf.tb_len) | |
2273 break; | |
2274 tp = typebuf.tb_buf + typebuf.tb_off + offset; | |
2275 if (tp[0] == K_SPECIAL && tp[1] == KS_MODIFIER) | |
2276 { | |
2277 int modifier = tp[2]; | |
2278 int new_c = merge_modifyOtherKeys(tp[3], &modifier); | |
2279 | |
2280 if (new_c != tp[3] && modifier == 0) | |
2281 { | |
2282 char_u new_string[MB_MAXBYTES]; | |
2283 int len = mb_char2bytes(new_c, new_string); | |
2284 | |
2285 if (put_string_in_typebuf(offset, 4, new_string, len, | |
2286 NULL, 0, 0) == FAIL) | |
2287 return -1; | |
2288 return len; | |
2289 } | |
2290 } | |
2291 } | |
2292 return 0; | |
2255 } | 2293 } |
2256 | 2294 |
2257 /* | 2295 /* |
2258 * Handle mappings in the typeahead buffer. | 2296 * Handle mappings in the typeahead buffer. |
2259 * - When something was mapped, return map_result_retry for recursive mappings. | 2297 * - When something was mapped, return map_result_retry for recursive mappings. |
2516 | 2554 |
2517 // If no termcode matched but 'pastetoggle' matched partially it's | 2555 // If no termcode matched but 'pastetoggle' matched partially it's |
2518 // like an incomplete key sequence. | 2556 // like an incomplete key sequence. |
2519 if (keylen == 0 && save_keylen == KEYLEN_PART_KEY) | 2557 if (keylen == 0 && save_keylen == KEYLEN_PART_KEY) |
2520 keylen = KEYLEN_PART_KEY; | 2558 keylen = KEYLEN_PART_KEY; |
2559 | |
2560 // If no termcode matched, try to include the modifier into the | |
2561 // key. This for when modifyOtherKeys is working. | |
2562 if (keylen == 0) | |
2563 keylen = check_simplify_modifier(max_mlen + 1); | |
2521 | 2564 |
2522 // When getting a partial match, but the last characters were not | 2565 // When getting a partial match, but the last characters were not |
2523 // typed, don't wait for a typed character to complete the | 2566 // typed, don't wait for a typed character to complete the |
2524 // termcode. This helps a lot when a ":normal" command ends in an | 2567 // termcode. This helps a lot when a ":normal" command ends in an |
2525 // ESC. | 2568 // ESC. |