diff options
author | Bram Moolenaar <Bram@vim.org> | 2019-11-26 19:33:22 +0100 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2019-11-26 19:33:22 +0100 |
commit | fc4ea2a72d36de1196a3ce17352e72f8fe90f4bb (patch) | |
tree | d5d681840040dc4e36b94bb94cef2cb972c052b0 /src/edit.c | |
parent | cc4423ae13d78367a3d0b5756783523d3b3a1d31 (diff) | |
download | vim-git-fc4ea2a72d36de1196a3ce17352e72f8fe90f4bb.tar.gz |
patch 8.1.2350: other text for CTRL-V in Insert mode with modifyOtherKeysv8.1.2350
Problem: Other text for CTRL-V in Insert mode with modifyOtherKeys.
Solution: Convert the Escape sequence back to key as if modifyOtherKeys is
not set, and use CTRL-SHIFT-V to get the Escape sequence itself.
(closes #5254)
Diffstat (limited to 'src/edit.c')
-rw-r--r-- | src/edit.c | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/src/edit.c b/src/edit.c index c74f1bb36..e1bf63db9 100644 --- a/src/edit.c +++ b/src/edit.c @@ -1531,6 +1531,7 @@ ins_ctrl_v(void) { int c; int did_putchar = FALSE; + int prev_mod_mask = mod_mask; /* may need to redraw when no more chars available now */ ins_redraw(FALSE); @@ -1554,6 +1555,12 @@ ins_ctrl_v(void) #ifdef FEAT_CMDL_INFO clear_showcmd(); #endif + + if ((c == ESC || c == CSI) && !(prev_mod_mask & MOD_MASK_SHIFT)) + // Using CTRL-V: Change any modifyOtherKeys ESC sequence to a normal + // key. Don't do this for CTRL-SHIFT-V. + c = decodeModifyOtherKeys(c); + insert_special(c, FALSE, TRUE); #ifdef FEAT_RIGHTLEFT revins_chars++; @@ -1562,6 +1569,59 @@ ins_ctrl_v(void) } /* + * After getting an ESC or CSI for a literal key: If the typeahead buffer + * contains a modifyOtherKeys sequence then decode it and return the result. + * Otherwise return "c". + * Note that this doesn't wait for characters, they must be in the typeahead + * buffer already. + */ + int +decodeModifyOtherKeys(int c) +{ + char_u *p = typebuf.tb_buf + typebuf.tb_off; + int idx; + int form = 0; + int argidx = 0; + int arg[2] = {0, 0}; + + // Recognize: + // form 0: {lead}{key};{modifier}u + // form 1: {lead}27;{modifier};{key}~ + if ((c == CSI || (c == ESC && *p == '[')) && typebuf.tb_len >= 4) + { + idx = (*p == '['); + if (p[idx] == '2' && p[idx + 1] == '7' && p[idx + 2] == ';') + { + form = 1; + idx += 3; + } + while (idx < typebuf.tb_len && argidx < 2) + { + if (p[idx] == ';') + ++argidx; + else if (VIM_ISDIGIT(p[idx])) + arg[argidx] = arg[argidx] * 10 + (p[idx] - '0'); + else + break; + ++idx; + } + if (idx < typebuf.tb_len + && p[idx] == (form == 1 ? '~' : 'u') + && argidx == 1) + { + // Match, consume the code. + typebuf.tb_off += idx + 1; + typebuf.tb_len -= idx + 1; + + mod_mask = decode_modifiers(arg[!form]); + c = merge_modifyOtherKeys(arg[form]); + } + } + + return c; +} + +/* * Put a character directly onto the screen. It's not stored in a buffer. * Used while handling CTRL-K, CTRL-V, etc. in Insert mode. */ |