diff options
author | Bram Moolenaar <Bram@vim.org> | 2022-01-03 13:47:50 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-01-03 13:47:50 +0000 |
commit | c88e977862ba6477a3b5b28706c45f96069a3073 (patch) | |
tree | 3b9a83f34e3b737ab583a5a11059724c7feb6a4c /src/getchar.c | |
parent | 0e2508d9e63e63414de2c06b3c8a446fdfe4470b (diff) |
patch 8.2.3993: when recording a change in Select mode char appears twicev8.2.3993
Problem: When recording a change in Select mode the first typed character
appears twice.
Solution: When putting the character back into typeahead remove it from
recorded characters. (closes #9462)
Diffstat (limited to 'src/getchar.c')
-rw-r--r-- | src/getchar.c | 55 |
1 files changed, 46 insertions, 9 deletions
diff --git a/src/getchar.c b/src/getchar.c index d9b55c0814..c8fad1430c 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -242,6 +242,22 @@ add_buff( } /* + * Delete "slen" bytes from the end of "buf". + * Only works when it was just added. + */ + static void +delete_buff_tail(buffheader_T *buf, int slen) +{ + int len = (int)STRLEN(buf->bh_curr->b_str); + + if (len >= slen) + { + buf->bh_curr->b_str[len - slen] = NUL; + buf->bh_space += slen; + } +} + +/* * Add number "n" to buffer "buf". */ static void @@ -1100,12 +1116,13 @@ ins_typebuf( * Can be used for a character obtained by vgetc() that needs to be put back. * Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to * the char. + * Returns the length of what was inserted. */ - void + int ins_char_typebuf(int c, int modifier) { char_u buf[MB_MAXBYTES + 4]; - int idx = 0; + int len = 0; if (modifier != 0) { @@ -1113,19 +1130,23 @@ ins_char_typebuf(int c, int modifier) buf[1] = KS_MODIFIER; buf[2] = modifier; buf[3] = NUL; - idx = 3; + len = 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; + buf[len] = K_SPECIAL; + buf[len + 1] = K_SECOND(c); + buf[len + 2] = K_THIRD(c); + buf[len + 3] = NUL; + len += 3; } else - buf[(*mb_char2bytes)(c, buf + idx) + idx] = NUL; + { + len += (*mb_char2bytes)(c, buf + len); + buf[len] = NUL; + } (void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent); + return len; } /* @@ -1302,6 +1323,22 @@ gotchars(char_u *chars, int len) } /* + * Undo the last gotchars() for "len" bytes. To be used when putting a typed + * character back into the typeahead buffer, thus gotchars() will be called + * again. + * Only affects recorded characters. + */ + void +ungetchars(int len) +{ + if (reg_recording != 0) + { + delete_buff_tail(&recordbuff, len); + last_recorded_len -= len; + } +} + +/* * Sync undo. Called when typed characters are obtained from the typeahead * buffer, or when a menu is used. * Do not sync: |