Mercurial > vim
diff src/getchar.c @ 26929:9975bd408d6c v8.2.3993
patch 8.2.3993: when recording a change in Select mode char appears twice
Commit: https://github.com/vim/vim/commit/c88e977862ba6477a3b5b28706c45f96069a3073
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Jan 3 13:47:50 2022 +0000
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)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 03 Jan 2022 15:00:05 +0100 |
parents | 06a137af96f8 |
children | 8dbdd68627bd |
line wrap: on
line diff
--- 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: