diff options
Diffstat (limited to 'src/getchar.c')
-rw-r--r-- | src/getchar.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/src/getchar.c b/src/getchar.c index e9eef25ad..312f3c1db 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -1101,18 +1101,29 @@ ins_typebuf( * the char. */ void -ins_char_typebuf(int c) +ins_char_typebuf(int c, int modifier) { - char_u buf[MB_MAXBYTES + 1]; - if (IS_SPECIAL(c)) + char_u buf[MB_MAXBYTES + 4]; + int idx = 0; + + if (modifier != 0) { buf[0] = K_SPECIAL; - buf[1] = K_SECOND(c); - buf[2] = K_THIRD(c); + buf[1] = KS_MODIFIER; + buf[2] = modifier; buf[3] = NUL; + idx = 3; + } + if (IS_SPECIAL(c)) + { + buf[idx] = K_SPECIAL; + buf[idx + 1] = K_SECOND(c); + buf[idx + 2] = K_THIRD(c); + buf[idx + 3] = NUL; + idx += 3; } else - buf[(*mb_char2bytes)(c, buf)] = NUL; + buf[(*mb_char2bytes)(c, buf + idx) + idx] = NUL; (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent); } @@ -1640,8 +1651,11 @@ vgetc(void) } else { - mod_mask = 0x0; + mod_mask = 0; + vgetc_mod_mask = 0; + vgetc_char = 0; last_recorded_len = 0; + for (;;) // this is done twice if there are modifiers { int did_inc = FALSE; @@ -1835,9 +1849,15 @@ vgetc(void) } if (!no_reduce_keys) + { // A modifier was not used for a mapping, apply it to ASCII // keys. Shift would already have been applied. + // Remember the character and mod_mask from before, in some + // cases they are put back in the typeahead buffer. + vgetc_mod_mask = mod_mask; + vgetc_char = c; c = merge_modifyOtherKeys(c); + } break; } @@ -2192,7 +2212,7 @@ parse_queued_messages(void) // If the current window or buffer changed we need to bail out of the // waiting loop. E.g. when a job exit callback closes the terminal window. if (curwin->w_id != old_curwin_id || curbuf->b_fnum != old_curbuf_fnum) - ins_char_typebuf(K_IGNORE); + ins_char_typebuf(K_IGNORE, 0); --entered; } |