diff options
-rw-r--r-- | runtime/lua/vim/_editor.lua | 10 | ||||
-rw-r--r-- | test/functional/api/vim_spec.lua | 41 |
2 files changed, 48 insertions, 3 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 42adda6e7f..26b9693189 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -128,7 +128,7 @@ local function inspect(object, options) -- luacheck: no unused end 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 --- (such as the |TUI|) pastes text into the editor. @@ -160,7 +160,7 @@ do local is_first_chunk = phase < 2 local is_last_chunk = phase == -1 or phase == 3 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 if #lines == 0 then lines = {''} @@ -203,7 +203,10 @@ do 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 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 vim.api.nvim_command([[exe "silent normal! \<Del>"]]) local del_start = vim.fn.getpos("'[") @@ -221,6 +224,7 @@ do end -- put cursor at the end of the text instead of one character after it vim.fn.setpos('.', vim.fn.getpos("']")) + trailing_nl = lines[#lines] == '' else -- Don't know what to do in other modes return false end diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 761cbb4036..9818746251 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -686,6 +686,19 @@ describe('API', function() feed('u') expect('') 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() feed('i||<Esc>0') nvim('paste', 'aaaaaa', false, 1) @@ -696,6 +709,20 @@ describe('API', function() feed('u') expect('||') 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() feed('i||<Esc>') nvim('paste', 'aaaaaa', false, 1) @@ -706,6 +733,20 @@ describe('API', function() feed('u') expect('||') 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() feed('i|xxx<CR>xxx|<Esc>hvhk') nvim('paste', 'aaaaaa', false, 1) |