mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:9.1.0227: Recording may still be wrong in Select mode (#28092)
Problem: Recording may still be wrong in Select mode (after 8.2.3993).
Solution: Make sure a character isn't split between two buffer blocks.
(zeertzjq)
closes: vim/vim#14326
ea95f1a5ad
This commit is contained in:
parent
d223a7cbd2
commit
fc19ee01ac
@ -1102,26 +1102,58 @@ void del_typebuf(int len, int offset)
|
||||
}
|
||||
|
||||
/// Write typed characters to script file.
|
||||
/// If recording is on put the character in the recordbuffer.
|
||||
/// If recording is on put the character in the record buffer.
|
||||
static void gotchars(const uint8_t *chars, size_t len)
|
||||
FUNC_ATTR_NONNULL_ALL
|
||||
{
|
||||
const uint8_t *s = chars;
|
||||
static uint8_t buf[4] = { 0 };
|
||||
int c = NUL;
|
||||
static int prev_c = NUL;
|
||||
static uint8_t buf[MB_MAXBYTES * 3 + 4] = { 0 };
|
||||
static size_t buflen = 0;
|
||||
static unsigned pending = 0;
|
||||
static bool in_special = false;
|
||||
static bool in_mbyte = false;
|
||||
size_t todo = len;
|
||||
|
||||
while (todo--) {
|
||||
buf[buflen++] = *s++;
|
||||
for (; todo--; prev_c = c) {
|
||||
c = buf[buflen++] = *s++;
|
||||
if (pending > 0) {
|
||||
pending--;
|
||||
}
|
||||
|
||||
// When receiving a special key sequence, store it until we have all
|
||||
// the bytes and we can decide what to do with it.
|
||||
if (buflen == 1 && buf[0] == K_SPECIAL) {
|
||||
if ((pending == 0 || in_mbyte) && c == K_SPECIAL) {
|
||||
pending += 2;
|
||||
if (!in_mbyte) {
|
||||
in_special = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (pending > 0) {
|
||||
continue;
|
||||
}
|
||||
if (buflen == 2) {
|
||||
|
||||
if (!in_mbyte) {
|
||||
if (in_special) {
|
||||
in_special = false;
|
||||
if (prev_c == KS_MODIFIER) {
|
||||
// When receiving a modifier, wait for the modified key.
|
||||
continue;
|
||||
}
|
||||
c = TO_SPECIAL(prev_c, c);
|
||||
}
|
||||
// When receiving a multibyte character, store it until we have all
|
||||
// the bytes, so that it won't be split between two buffer blocks,
|
||||
// and delete_buff_tail() will work properly.
|
||||
pending = MB_BYTE2LEN_CHECK(c) - 1;
|
||||
if (pending > 0) {
|
||||
in_mbyte = true;
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Stored all bytes of a multibyte character.
|
||||
in_mbyte = false;
|
||||
}
|
||||
|
||||
// Handle one byte at a time; no translation to be done.
|
||||
for (size_t i = 0; i < buflen; i++) {
|
||||
|
@ -214,6 +214,58 @@ func Test_recording_with_select_mode()
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Run_test_recording_with_select_mode_utf8()
|
||||
new
|
||||
|
||||
" Test with different text lengths: 5, 7, 9, 11, 13, 15, to check that
|
||||
" a character isn't split between two buffer blocks.
|
||||
for s in ['12345', '口=口', '口口口', '口=口=口', '口口=口口', '口口口口口']
|
||||
" 0x80 is K_SPECIAL
|
||||
" 0x9B is CSI
|
||||
" 哦: 0xE5 0x93 0xA6
|
||||
" 洛: 0xE6 0xB4 0x9B
|
||||
" 固: 0xE5 0x9B 0xBA
|
||||
" 四: 0xE5 0x9B 0x9B
|
||||
" 最: 0xE6 0x9C 0x80
|
||||
" 倒: 0xE5 0x80 0x92
|
||||
" 倀: 0xE5 0x80 0x80
|
||||
for c in ['哦', '洛', '固', '四', '最', '倒', '倀']
|
||||
call setline(1, 'asdf')
|
||||
call feedkeys($"qacc{s}\<Esc>gH{c}\<Esc>q", "tx")
|
||||
call assert_equal(c, getline(1))
|
||||
call assert_equal($"cc{s}\<Esc>gH{c}\<Esc>", @a)
|
||||
call setline(1, 'asdf')
|
||||
normal! @a
|
||||
call assert_equal(c, getline(1))
|
||||
|
||||
" Test with Shift modifier.
|
||||
let shift_c = eval($'"\<S-{c}>"')
|
||||
call setline(1, 'asdf')
|
||||
call feedkeys($"qacc{s}\<Esc>gH{shift_c}\<Esc>q", "tx")
|
||||
call assert_equal(c, getline(1))
|
||||
call assert_equal($"cc{s}\<Esc>gH{shift_c}\<Esc>", @a)
|
||||
call setline(1, 'asdf')
|
||||
normal! @a
|
||||
call assert_equal(c, getline(1))
|
||||
endfor
|
||||
endfor
|
||||
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_recording_with_select_mode_utf8()
|
||||
call Run_test_recording_with_select_mode_utf8()
|
||||
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
|
||||
|
||||
" Test for executing the last used register (@)
|
||||
func Test_last_used_exec_reg()
|
||||
" Test for the @: command
|
||||
|
@ -292,55 +292,4 @@ 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
|
||||
|
Loading…
Reference in New Issue
Block a user