fix(paste): deal with trailing new line in chunk

This commit is contained in:
zeertzjq 2022-03-06 06:56:24 +08:00
parent fcc6f66cf2
commit a6eafc77ce
2 changed files with 48 additions and 3 deletions

View File

@ -128,7 +128,7 @@ local function inspect(object, options) -- luacheck: no unused
end end
do do
local tdots, tick, got_line1, undo_started = 0, 0, false, false local tdots, tick, got_line1, undo_started, trailing_nl = 0, 0, false, false, false
--- Paste handler, invoked by |nvim_paste()| when a conforming UI --- Paste handler, invoked by |nvim_paste()| when a conforming UI
--- (such as the |TUI|) pastes text into the editor. --- (such as the |TUI|) pastes text into the editor.
@ -160,7 +160,7 @@ do
local is_first_chunk = phase < 2 local is_first_chunk = phase < 2
local is_last_chunk = phase == -1 or phase == 3 local is_last_chunk = phase == -1 or phase == 3
if is_first_chunk then -- Reset flags. if is_first_chunk then -- Reset flags.
tdots, tick, got_line1, undo_started = now, 0, false, false tdots, tick, got_line1, undo_started, trailing_nl = now, 0, false, false, false
end end
if #lines == 0 then if #lines == 0 then
lines = {''} lines = {''}
@ -203,7 +203,10 @@ do
vim.api.nvim_buf_set_lines(0, row-1, row, false, lines) vim.api.nvim_buf_set_lines(0, row-1, row, false, lines)
elseif mode:find('^[nvV\22sS\19]') then -- Normal or Visual or Select mode elseif mode:find('^[nvV\22sS\19]') then -- Normal or Visual or Select mode
if mode:find('^n') then -- Normal mode if mode:find('^n') then -- Normal mode
vim.api.nvim_put(lines, 'c', true, false) -- When there was a trailing new line in the previous chunk,
-- the cursor is on the first character of the next line,
-- so paste before the cursor instead of after it.
vim.api.nvim_put(lines, 'c', not trailing_nl, false)
else -- Visual or Select mode else -- Visual or Select mode
vim.api.nvim_command([[exe "silent normal! \<Del>"]]) vim.api.nvim_command([[exe "silent normal! \<Del>"]])
local del_start = vim.fn.getpos("'[") local del_start = vim.fn.getpos("'[")
@ -221,6 +224,7 @@ do
end end
-- put cursor at the end of the text instead of one character after it -- put cursor at the end of the text instead of one character after it
vim.fn.setpos('.', vim.fn.getpos("']")) vim.fn.setpos('.', vim.fn.getpos("']"))
trailing_nl = lines[#lines] == ''
else -- Don't know what to do in other modes else -- Don't know what to do in other modes
return false return false
end end

View File

@ -686,6 +686,19 @@ describe('API', function()
feed('u') feed('u')
expect('') expect('')
end) end)
it('stream: Normal mode on empty line pasting multiple lines', function()
nvim('paste', 'aaaaaa\n', false, 1)
nvim('paste', 'bbbbbb\n', false, 2)
nvim('paste', 'cccccc\n', false, 2)
nvim('paste', 'dddddd', false, 3)
expect([[
aaaaaa
bbbbbb
cccccc
dddddd]])
feed('u')
expect('')
end)
it('stream: Normal mode not at the end of a line', function() it('stream: Normal mode not at the end of a line', function()
feed('i||<Esc>0') feed('i||<Esc>0')
nvim('paste', 'aaaaaa', false, 1) nvim('paste', 'aaaaaa', false, 1)
@ -696,6 +709,20 @@ describe('API', function()
feed('u') feed('u')
expect('||') expect('||')
end) end)
it('stream: Normal mode not at the end of a line pasting multiple lines', function()
feed('i||<Esc>0')
nvim('paste', 'aaaaaa\n', false, 1)
nvim('paste', 'bbbbbb\n', false, 2)
nvim('paste', 'cccccc\n', false, 2)
nvim('paste', 'dddddd', false, 3)
expect([[
|aaaaaa
bbbbbb
cccccc
dddddd|]])
feed('u')
expect('||')
end)
it('stream: Normal mode at the end of a line', function() it('stream: Normal mode at the end of a line', function()
feed('i||<Esc>') feed('i||<Esc>')
nvim('paste', 'aaaaaa', false, 1) nvim('paste', 'aaaaaa', false, 1)
@ -706,6 +733,20 @@ describe('API', function()
feed('u') feed('u')
expect('||') expect('||')
end) end)
it('stream: Normal mode at the end of a line pasting multiple lines', function()
feed('i||<Esc>')
nvim('paste', 'aaaaaa\n', false, 1)
nvim('paste', 'bbbbbb\n', false, 2)
nvim('paste', 'cccccc\n', false, 2)
nvim('paste', 'dddddd', false, 3)
expect([[
||aaaaaa
bbbbbb
cccccc
dddddd]])
feed('u')
expect('||')
end)
it('stream: Visual mode neither end at the end of a line', function() it('stream: Visual mode neither end at the end of a line', function()
feed('i|xxx<CR>xxx|<Esc>hvhk') feed('i|xxx<CR>xxx|<Esc>hvhk')
nvim('paste', 'aaaaaa', false, 1) nvim('paste', 'aaaaaa', false, 1)