diff options
Diffstat (limited to 'src/nvim/getchar.c')
-rw-r--r-- | src/nvim/getchar.c | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/nvim/getchar.c b/src/nvim/getchar.c index b12b99b7ee..299385cb17 100644 --- a/src/nvim/getchar.c +++ b/src/nvim/getchar.c @@ -1253,7 +1253,14 @@ static int old_mod_mask; // mod_mask for ungotten character static int old_mouse_grid; // mouse_grid related to old_char static int old_mouse_row; // mouse_row related to old_char static int old_mouse_col; // mouse_col related to old_char +static int old_KeyStuffed; // whether old_char was stuffed +static bool can_get_old_char(void) +{ + // If the old character was not stuffed and characters have been added to + // the stuff buffer, need to first get the stuffed characters instead. + return old_char != -1 && (old_KeyStuffed || stuff_empty()); +} /* * Save all three kinds of typeahead, so that the user must type at a prompt. @@ -1454,7 +1461,7 @@ int vgetc(void) * If a character was put back with vungetc, it was already processed. * Return it directly. */ - if (old_char != -1) { + if (can_get_old_char()) { c = old_char; old_char = -1; mod_mask = old_mod_mask; @@ -1660,7 +1667,7 @@ int plain_vgetc(void) */ int vpeekc(void) { - if (old_char != -1) { + if (can_get_old_char()) { return old_char; } return vgetorpeek(false); @@ -2052,7 +2059,9 @@ static int handle_mapping(int *keylenp, bool *timedout, int *mapdepth) return map_result_nomatch; } -// unget one character (can only be done once!) +/// unget one character (can only be done once!) +/// If the character was stuffed, vgetc() will get it next time it is called. +/// Otherwise vgetc() will only get it when the stuff buffer is empty. void vungetc(int c) { old_char = c; @@ -2060,6 +2069,21 @@ void vungetc(int c) old_mouse_grid = mouse_grid; old_mouse_row = mouse_row; old_mouse_col = mouse_col; + old_KeyStuffed = KeyStuffed; +} + +/// When peeking and not getting a character, reg_executing cannot be cleared +/// yet, so set a flag to clear it later. +void check_end_reg_executing(bool advance) +{ + if (reg_executing != 0 && (typebuf.tb_maplen == 0 || pending_end_reg_executing)) { + if (advance) { + reg_executing = 0; + pending_end_reg_executing = false; + } else { + pending_end_reg_executing = true; + } + } } /// Gets a byte: @@ -2116,9 +2140,7 @@ static int vgetorpeek(bool advance) init_typebuf(); start_stuff(); - if (advance && typebuf.tb_maplen == 0) { - reg_executing = 0; - } + check_end_reg_executing(advance); do { // get a character: 1. from the stuffbuffer if (typeahead_char != 0) { @@ -2145,6 +2167,7 @@ static int vgetorpeek(bool advance) // If a mapped key sequence is found we go back to the start to // try re-mapping. for (;;) { + check_end_reg_executing(advance); // os_breakcheck() is slow, don't use it too often when // inside a mapping. But call it each time for typed // characters. @@ -2330,8 +2353,6 @@ static int vgetorpeek(bool advance) // cmdline window. if (p_im && (State & INSERT)) { c = Ctrl_L; - } else if (exmode_active) { - c = '\n'; } else if ((State & CMDLINE) || (cmdwin_type > 0 && tc == ESC)) { c = Ctrl_C; } else { @@ -2573,7 +2594,7 @@ int inchar(char_u *buf, int maxlen, long wait_time) // Don't use buf[] here, closescript() may have freed typebuf.tb_buf[] // and buf may be pointing inside typebuf.tb_buf[]. if (got_int) { -#define DUM_LEN MAXMAPLEN * 3 + 3 +#define DUM_LEN (MAXMAPLEN * 3 + 3) char_u dum[DUM_LEN + 1]; for (;;) { |