Merge pull request #17185 from zeertzjq/vim-8.2.3993

vim-patch:8.2.{3993,4002}: when recording a change in Select mode char appears twice
This commit is contained in:
bfredl 2022-01-27 13:45:34 +01:00 committed by GitHub
commit d95bb85024
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 111 additions and 19 deletions

View File

@ -284,9 +284,19 @@ static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t sle
}
}
/*
* Add number "n" to buffer "buf".
*/
/// 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 += (size_t)slen;
}
}
/// Add number "n" to buffer "buf".
static void add_num_buff(buffheader_T *buf, long n)
{
char number[32];
@ -967,31 +977,31 @@ int ins_typebuf(char_u *str, int noremap, int offset, bool nottyped, bool silent
return OK;
}
/*
* Put character "c" back into the typeahead buffer.
* 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.
*/
void ins_char_typebuf(int c, int modifier)
/// Put character "c" back into the typeahead buffer.
/// 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.
/// @return the length of what was inserted
int ins_char_typebuf(int c, int modifier)
{
char_u buf[MB_MAXBYTES + 4];
int idx = 0;
char_u buf[MB_MAXBYTES * 3 + 4];
int len = 0;
if (modifier != 0) {
buf[0] = K_SPECIAL;
buf[1] = KS_MODIFIER;
buf[2] = (char_u)modifier;
buf[3] = NUL;
idx = 3;
len = 3;
}
if (IS_SPECIAL(c)) {
buf[idx] = K_SPECIAL;
buf[idx + 1] = (char_u)K_SECOND(c);
buf[idx + 2] = (char_u)K_THIRD(c);
buf[idx + 3] = NUL;
buf[len] = K_SPECIAL;
buf[len + 1] = (char_u)K_SECOND(c);
buf[len + 2] = (char_u)K_THIRD(c);
buf[len + 3] = NUL;
} else {
char_u *p = buf + idx;
char_u *p = buf + len;
int char_len = utf_char2bytes(c, p);
len += char_len;
// If the character contains K_SPECIAL bytes they need escaping.
for (int i = char_len; --i >= 0; p++) {
if ((uint8_t)(*p) == K_SPECIAL) {
@ -999,11 +1009,13 @@ void ins_char_typebuf(int c, int modifier)
*p++ = K_SPECIAL;
*p++ = KS_SPECIAL;
*p = KE_FILLER;
len += 2;
}
}
*p = NUL;
}
(void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
return len;
}
/// Return TRUE if the typeahead buffer was changed (while waiting for a
@ -1163,6 +1175,18 @@ static void gotchars(const char_u *chars, size_t 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 -= (size_t)len;
}
}
/*
* Sync undo. Called when typed characters are obtained from the typeahead
* buffer, or when a menu is used.

View File

@ -1011,7 +1011,12 @@ static int normal_execute(VimState *state, int key)
// restart automatically.
// Insert the typed character in the typeahead buffer, so that it can
// be mapped in Insert mode. Required for ":lmap" to work.
ins_char_typebuf(s->c, mod_mask);
int len = ins_char_typebuf(s->c, mod_mask);
// When recording the character will be recorded again, remove the
// previously recording.
ungetchars(len);
if (restart_edit != 0) {
s->c = 'd';
} else {

View File

@ -121,6 +121,17 @@ func Test_recording_esc_sequence()
endif
endfunc
func Test_recording_with_select_mode()
new
call feedkeys("qacc12345\<Esc>gH98765\<Esc>q", "tx")
call assert_equal("98765", getline(1))
call assert_equal("cc12345\<Esc>gH98765\<Esc>", @a)
call setline(1, 'asdf')
normal! @a
call assert_equal("98765", getline(1))
bwipe!
endfunc
" Test for executing the last used register (@)
func Test_last_used_exec_reg()
" Test for the @: command

View File

@ -1,5 +1,6 @@
" Tests for Unicode manipulations
source check.vim
source view_util.vim
" Visual block Insert adjusts for multi-byte char
@ -148,4 +149,55 @@ func Test_print_overlong()
bwipe!
endfunc
func Test_recording_with_select_mode_utf8()
call Run_test_recording_with_select_mode_utf8()
endfunc
func Run_test_recording_with_select_mode_utf8()
new
" No escaping
call feedkeys("qacc12345\<Esc>gH哦\<Esc>q", "tx")
call assert_equal("哦", getline(1))
call assert_equal("cc12345\<Esc>gH哦\<Esc>", @a)
call setline(1, 'asdf')
normal! @a
call assert_equal("哦", getline(1))
" 固 is 0xE5 0x9B 0xBA where 0x9B is CSI
call feedkeys("qacc12345\<Esc>gH固\<Esc>q", "tx")
call assert_equal("固", getline(1))
call assert_equal("cc12345\<Esc>gH固\<Esc>", @a)
call setline(1, 'asdf')
normal! @a
call assert_equal("固", getline(1))
" 四 is 0xE5 0x9B 0x9B where 0x9B is CSI
call feedkeys("qacc12345\<Esc>gH四\<Esc>q", "tx")
call assert_equal("四", getline(1))
call assert_equal("cc12345\<Esc>gH四\<Esc>", @a)
call setline(1, 'asdf')
normal! @a
call assert_equal("四", getline(1))
" 倒 is 0xE5 0x80 0x92 where 0x80 is K_SPECIAL
call feedkeys("qacc12345\<Esc>gH倒\<Esc>q", "tx")
call assert_equal("倒", getline(1))
call assert_equal("cc12345\<Esc>gH倒\<Esc>", @a)
call setline(1, 'asdf')
normal! @a
call assert_equal("倒", getline(1))
bwipe!
endfunc
" This must be done as one of the last tests, because it starts the GUI, which
" cannot be undone.
func Test_zz_recording_with_select_mode_utf8_gui()
CheckCanRunGui
gui -f
call Run_test_recording_with_select_mode_utf8()
endfunc
" vim: shiftwidth=2 sts=2 expandtab