summaryrefslogtreecommitdiff
path: root/src/getchar.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/getchar.c')
-rw-r--r--src/getchar.c36
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;
}