From c88e977862ba6477a3b5b28706c45f96069a3073 Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Mon, 3 Jan 2022 13:47:50 +0000 Subject: patch 8.2.3993: when recording a change in Select mode char appears twice 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) --- src/getchar.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 9 deletions(-) (limited to 'src/getchar.c') diff --git a/src/getchar.c b/src/getchar.c index d9b55c0814..c8fad1430c 100644 --- a/src/getchar.c +++ b/src/getchar.c @@ -241,6 +241,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". */ @@ -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; } /* @@ -1301,6 +1322,22 @@ gotchars(char_u *chars, int len) ++maptick; } +/* + * 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. -- cgit v1.2.3