diff options
author | zeertzjq <zeertzjq@outlook.com> | 2024-09-24 07:14:14 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-24 07:14:14 +0800 |
commit | d831392b156087ddc38eb75b0260c03f955dd23c (patch) | |
tree | 639ce790cf91b592e7d331f0c7759c76d0e095e3 /test/functional/api/vim_spec.lua | |
parent | 032e024f8ab9048286859be6b83349c5f1ece868 (diff) | |
download | rneovim-d831392b156087ddc38eb75b0260c03f955dd23c.tar.gz rneovim-d831392b156087ddc38eb75b0260c03f955dd23c.tar.bz2 rneovim-d831392b156087ddc38eb75b0260c03f955dd23c.zip |
feat(paste): unify cancel and error behavior (#30476)
Before this PR, the behavior of nvim_paste is:
- When vim.paste() returns false, return false to the client, but treat
following chunks normally (i.e. rely on the client cancelling the
paste as expected).
- When vim.paste() throws an error, still return true to the client, but
drain the following chunks in the stream without calling vim.paste().
There are two problems with such behavior:
- When vim.paste() errors, the client is still supposed to send the
remaining chunks of the stream, even though they do nothing.
- Having different code paths for two uncommon but similar situations
complicates maintenance.
This PR makes both the cancel case and the error case return false to
the client and drain the remaining chunks of the stream, which, apart
from sharing the same code path, is beneficial whether the client checks
the return value of nvim_paste or not:
- If the client checks the return value, it can avoid sending the
following chunks needlessly after an error.
- If the client doesn't check the return value, chunks following a
cancelled chunk won't be pasted on the server regardless, which leads
to less confusing behavior.
Diffstat (limited to 'test/functional/api/vim_spec.lua')
-rw-r--r-- | test/functional/api/vim_spec.lua | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index b35ccb0c40..1b34945f13 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -1358,9 +1358,72 @@ describe('API', function() test_paste_repeat_visual_select(true) end) end) - it('vim.paste() failure', function() - api.nvim_exec_lua('vim.paste = (function(lines, phase) error("fake fail") end)', {}) - eq('fake fail', pcall_err(request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1)) + local function test_paste_cancel_error(is_error) + before_each(function() + exec_lua(([[ + vim.paste = (function(overridden) + return function(lines, phase) + for i, line in ipairs(lines) do + if line == 'CANCEL' then + %s + end + end + return overridden(lines, phase) + end + end)(vim.paste) + ]]):format(is_error and 'error("fake fail")' or 'return false')) + end) + local function check_paste_cancel_error(data, crlf, phase) + if is_error then + eq('fake fail', pcall_err(api.nvim_paste, data, crlf, phase)) + else + eq(false, api.nvim_paste(data, crlf, phase)) + end + end + it('in phase -1', function() + feed('A') + check_paste_cancel_error('CANCEL', true, -1) + feed('<Esc>') + expect('') + feed('.') + expect('') + end) + it('in phase 1', function() + feed('A') + check_paste_cancel_error('CANCEL', true, 1) + feed('<Esc>') + expect('') + feed('.') + expect('') + end) + it('in phase 2', function() + feed('A') + eq(true, api.nvim_paste('aaa', true, 1)) + expect('aaa') + check_paste_cancel_error('CANCEL', true, 2) + feed('<Esc>') + expect('aaa') + feed('.') + expect('aaaaaa') + end) + it('in phase 3', function() + feed('A') + eq(true, api.nvim_paste('aaa', true, 1)) + expect('aaa') + eq(true, api.nvim_paste('bbb', true, 2)) + expect('aaabbb') + check_paste_cancel_error('CANCEL', true, 3) + feed('<Esc>') + expect('aaabbb') + feed('.') + expect('aaabbbaaabbb') + end) + end + describe('vim.paste() cancel', function() + test_paste_cancel_error(false) + end) + describe('vim.paste() error', function() + test_paste_cancel_error(true) end) end) |