diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-03-06 06:56:24 +0800 |
---|---|---|
committer | zeertzjq <zeertzjq@outlook.com> | 2022-03-15 18:15:18 +0800 |
commit | 2601e0873ff50ed804487dff00bd27e233709beb (patch) | |
tree | b91bad241e69b129a5289178c89189a698c5b301 | |
parent | 9b1e1fbc9f795921afd25ba38be5c79dec8b04d2 (diff) | |
download | rneovim-2601e0873ff50ed804487dff00bd27e233709beb.tar.gz rneovim-2601e0873ff50ed804487dff00bd27e233709beb.tar.bz2 rneovim-2601e0873ff50ed804487dff00bd27e233709beb.zip |
fix(paste): don't move cursor past the end of pasted text in Normal mode
-rw-r--r-- | runtime/lua/vim/_editor.lua | 27 | ||||
-rw-r--r-- | test/functional/api/vim_spec.lua | 37 | ||||
-rw-r--r-- | test/functional/terminal/tui_spec.lua | 14 |
3 files changed, 61 insertions, 17 deletions
diff --git a/runtime/lua/vim/_editor.lua b/runtime/lua/vim/_editor.lua index 8000730795..8e49b51cec 100644 --- a/runtime/lua/vim/_editor.lua +++ b/runtime/lua/vim/_editor.lua @@ -171,27 +171,34 @@ do vim.api.nvim_input(line1) vim.api.nvim_set_option('paste', false) elseif not is_cmdline then - if phase < 2 and mode:find('^[vV\22sS\19]') then - vim.api.nvim_command([[exe "normal! \<Del>"]]) + if mode:find('^i') or mode:find('^n?t') then -- Insert mode or Terminal buffer vim.api.nvim_put(lines, 'c', false, true) - elseif phase < 2 and not mode:find('^[iRt]') then - vim.api.nvim_put(lines, 'c', true, true) - -- XXX: Normal-mode: workaround bad cursor-placement after first chunk. - vim.api.nvim_command('normal! a') - elseif phase < 2 and mode:find('^R') then + elseif phase < 2 and mode:find('^R') and not mode:find('^Rv') then -- Replace mode + -- TODO: implement Replace mode streamed pasting + -- TODO: support Virtual Replace mode local nchars = 0 for _, line in ipairs(lines) do - nchars = nchars + line:len() + nchars = nchars + line:len() end local row, col = unpack(vim.api.nvim_win_get_cursor(0)) local bufline = vim.api.nvim_buf_get_lines(0, row-1, row, true)[1] local firstline = lines[1] firstline = bufline:sub(1, col)..firstline lines[1] = firstline + -- FIXME: #lines can be 0 lines[#lines] = lines[#lines]..bufline:sub(col + nchars + 1, bufline:len()) vim.api.nvim_buf_set_lines(0, row-1, row, false, lines) - else - vim.api.nvim_put(lines, 'c', false, true) + 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) + else -- Visual or Select mode + vim.api.nvim_command([[exe "normal! \<Del>"]]) + vim.api.nvim_put(lines, 'c', false, false) + end + -- put cursor at the end of the text instead of one character after it + vim.fn.setpos('.', vim.fn.getpos("']")) + else -- Don't know what to do in other modes + return false end end if phase ~= -1 and (now - tdots >= 100) then diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index 384e8d11f2..3d57953a11 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -665,6 +665,43 @@ describe('API', function() feed('u') -- Undo. expect(expected1) end) + it('stream: Insert mode', function() + feed('i') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('aaaaaabbbbbbccccccdddddd') + end) + it('stream: Normal mode on empty line', function() + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('aaaaaabbbbbbccccccdddddd') + 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) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('|aaaaaabbbbbbccccccdddddd|') + feed('u') + expect('||') + end) + it('stream: Normal mode at the end of a line', function() + feed('i||<Esc>') + nvim('paste', 'aaaaaa', false, 1) + nvim('paste', 'bbbbbb', false, 2) + nvim('paste', 'cccccc', false, 2) + nvim('paste', 'dddddd', false, 3) + expect('||aaaaaabbbbbbccccccdddddd') + feed('u') + expect('||') + end) it('non-streaming', function() -- With final "\n". nvim('paste', 'line 1\nline 2\nline 3\n', true, -1) diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index faf44fa01d..c37cde06ab 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -323,7 +323,7 @@ describe('TUI', function() feed_data('just paste it™') feed_data('\027[201~') screen:expect{grid=[[ - thisjust paste it™{1:3} is here | + thisjust paste it{1:™}3 is here | | {4:~ }| {4:~ }| @@ -379,7 +379,7 @@ describe('TUI', function() end) it('paste: normal-mode (+CRLF #10872)', function() - feed_data(':set ruler') + feed_data(':set ruler | echo') wait_for_mode('c') feed_data('\n') wait_for_mode('n') @@ -423,13 +423,13 @@ describe('TUI', function() expect_child_buf_lines(expected_crlf) feed_data('u') expect_child_buf_lines({''}) + feed_data(':echo') + wait_for_mode('c') + feed_data('\n') + wait_for_mode('n') -- CRLF input feed_data('\027[200~'..table.concat(expected_lf,'\r\n')..'\027[201~') - screen:expect{ - grid=expected_grid1:gsub( - ':set ruler *', - '3 fewer lines; before #1 0 seconds ago '), - attr_ids=expected_attr} + screen:expect{grid=expected_grid1, attr_ids=expected_attr} expect_child_buf_lines(expected_crlf) end) |