aboutsummaryrefslogtreecommitdiff
path: root/test/functional/terminal/tui_spec.lua
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-09-24 07:14:14 +0800
committerGitHub <noreply@github.com>2024-09-24 07:14:14 +0800
commitd831392b156087ddc38eb75b0260c03f955dd23c (patch)
tree639ce790cf91b592e7d331f0c7759c76d0e095e3 /test/functional/terminal/tui_spec.lua
parent032e024f8ab9048286859be6b83349c5f1ece868 (diff)
downloadrneovim-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/terminal/tui_spec.lua')
-rw-r--r--test/functional/terminal/tui_spec.lua35
1 files changed, 35 insertions, 0 deletions
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index b85ddec0f0..a7d87bb231 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -1298,6 +1298,41 @@ describe('TUI', function()
expect_child_buf_lines({ 'foo', '' })
end)
+ it('paste: vim.paste() cancel (retval=false) with streaming #30462', function()
+ child_session:request(
+ 'nvim_exec_lua',
+ [[
+ vim.paste = (function(overridden)
+ return function(lines, phase)
+ for i, line in ipairs(lines) do
+ if line:find('!') then
+ return false
+ end
+ end
+ return overridden(lines, phase)
+ end
+ end)(vim.paste)
+ ]],
+ {}
+ )
+ feed_data('A')
+ wait_for_mode('i')
+ feed_data('\027[200~aaa')
+ expect_child_buf_lines({ 'aaa' })
+ feed_data('bbb')
+ expect_child_buf_lines({ 'aaabbb' })
+ feed_data('ccc!') -- This chunk is cancelled.
+ expect_child_buf_lines({ 'aaabbb' })
+ feed_data('ddd\027[201~') -- This chunk is ignored.
+ expect_child_buf_lines({ 'aaabbb' })
+ feed_data('\027[27u')
+ wait_for_mode('n')
+ feed_data('.') -- Dot-repeat only includes chunks actually pasted.
+ expect_child_buf_lines({ 'aaabbbaaabbb' })
+ feed_data('$\027[200~eee\027[201~') -- A following paste works normally.
+ expect_child_buf_lines({ 'aaabbbaaabbbeee' })
+ end)
+
it("paste: 'nomodifiable' buffer", function()
child_session:request('nvim_command', 'set nomodifiable')
child_session:request(