mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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:
commit
d95bb85024
@ -284,9 +284,19 @@ static void add_buff(buffheader_T *const buf, const char *const s, ptrdiff_t sle
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Delete "slen" bytes from the end of "buf".
|
||||||
* Add number "n" to buffer "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)
|
static void add_num_buff(buffheader_T *buf, long n)
|
||||||
{
|
{
|
||||||
char number[32];
|
char number[32];
|
||||||
@ -967,31 +977,31 @@ int ins_typebuf(char_u *str, int noremap, int offset, bool nottyped, bool silent
|
|||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Put character "c" back into the typeahead buffer.
|
||||||
* Put character "c" back into the typeahead buffer.
|
/// Can be used for a character obtained by vgetc() that needs to be put back.
|
||||||
* 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
|
||||||
* Uses cmd_silent, KeyTyped and KeyNoremap to restore the flags belonging to
|
/// the char.
|
||||||
* the char.
|
/// @return the length of what was inserted
|
||||||
*/
|
int ins_char_typebuf(int c, int modifier)
|
||||||
void ins_char_typebuf(int c, int modifier)
|
|
||||||
{
|
{
|
||||||
char_u buf[MB_MAXBYTES + 4];
|
char_u buf[MB_MAXBYTES * 3 + 4];
|
||||||
int idx = 0;
|
int len = 0;
|
||||||
if (modifier != 0) {
|
if (modifier != 0) {
|
||||||
buf[0] = K_SPECIAL;
|
buf[0] = K_SPECIAL;
|
||||||
buf[1] = KS_MODIFIER;
|
buf[1] = KS_MODIFIER;
|
||||||
buf[2] = (char_u)modifier;
|
buf[2] = (char_u)modifier;
|
||||||
buf[3] = NUL;
|
buf[3] = NUL;
|
||||||
idx = 3;
|
len = 3;
|
||||||
}
|
}
|
||||||
if (IS_SPECIAL(c)) {
|
if (IS_SPECIAL(c)) {
|
||||||
buf[idx] = K_SPECIAL;
|
buf[len] = K_SPECIAL;
|
||||||
buf[idx + 1] = (char_u)K_SECOND(c);
|
buf[len + 1] = (char_u)K_SECOND(c);
|
||||||
buf[idx + 2] = (char_u)K_THIRD(c);
|
buf[len + 2] = (char_u)K_THIRD(c);
|
||||||
buf[idx + 3] = NUL;
|
buf[len + 3] = NUL;
|
||||||
} else {
|
} else {
|
||||||
char_u *p = buf + idx;
|
char_u *p = buf + len;
|
||||||
int char_len = utf_char2bytes(c, p);
|
int char_len = utf_char2bytes(c, p);
|
||||||
|
len += char_len;
|
||||||
// If the character contains K_SPECIAL bytes they need escaping.
|
// If the character contains K_SPECIAL bytes they need escaping.
|
||||||
for (int i = char_len; --i >= 0; p++) {
|
for (int i = char_len; --i >= 0; p++) {
|
||||||
if ((uint8_t)(*p) == K_SPECIAL) {
|
if ((uint8_t)(*p) == K_SPECIAL) {
|
||||||
@ -999,11 +1009,13 @@ void ins_char_typebuf(int c, int modifier)
|
|||||||
*p++ = K_SPECIAL;
|
*p++ = K_SPECIAL;
|
||||||
*p++ = KS_SPECIAL;
|
*p++ = KS_SPECIAL;
|
||||||
*p = KE_FILLER;
|
*p = KE_FILLER;
|
||||||
|
len += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*p = NUL;
|
*p = NUL;
|
||||||
}
|
}
|
||||||
(void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
|
(void)ins_typebuf(buf, KeyNoremap, 0, !KeyTyped, cmd_silent);
|
||||||
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return TRUE if the typeahead buffer was changed (while waiting for a
|
/// 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++;
|
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
|
* Sync undo. Called when typed characters are obtained from the typeahead
|
||||||
* buffer, or when a menu is used.
|
* buffer, or when a menu is used.
|
||||||
|
@ -1011,7 +1011,12 @@ static int normal_execute(VimState *state, int key)
|
|||||||
// restart automatically.
|
// restart automatically.
|
||||||
// Insert the typed character in the typeahead buffer, so that it can
|
// Insert the typed character in the typeahead buffer, so that it can
|
||||||
// be mapped in Insert mode. Required for ":lmap" to work.
|
// 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) {
|
if (restart_edit != 0) {
|
||||||
s->c = 'd';
|
s->c = 'd';
|
||||||
} else {
|
} else {
|
||||||
|
@ -121,6 +121,17 @@ func Test_recording_esc_sequence()
|
|||||||
endif
|
endif
|
||||||
endfunc
|
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 (@)
|
" Test for executing the last used register (@)
|
||||||
func Test_last_used_exec_reg()
|
func Test_last_used_exec_reg()
|
||||||
" Test for the @: command
|
" Test for the @: command
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
" Tests for Unicode manipulations
|
" Tests for Unicode manipulations
|
||||||
|
|
||||||
|
source check.vim
|
||||||
source view_util.vim
|
source view_util.vim
|
||||||
|
|
||||||
" Visual block Insert adjusts for multi-byte char
|
" Visual block Insert adjusts for multi-byte char
|
||||||
@ -148,4 +149,55 @@ func Test_print_overlong()
|
|||||||
bwipe!
|
bwipe!
|
||||||
endfunc
|
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
|
" vim: shiftwidth=2 sts=2 expandtab
|
||||||
|
Loading…
Reference in New Issue
Block a user