Merge #10884 'API: nvim_paste: add crlf parameter'

This commit is contained in:
Justin M. Keyes 2019-08-30 09:15:43 +02:00 committed by GitHub
commit 06e693cdc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 14 deletions

View File

@ -793,11 +793,12 @@ nvim_get_namespaces() *nvim_get_namespaces()*
Return: ~ Return: ~
dict that maps from names to namespace ids. dict that maps from names to namespace ids.
nvim_paste({data}, {phase}) *nvim_paste()* nvim_paste({data}, {crlf}, {phase}) *nvim_paste()*
Pastes at cursor, in any mode. Pastes at cursor, in any mode.
Invokes the `vim.paste` handler, which handles each mode Invokes the `vim.paste` handler, which handles each mode
appropriately. Sets redo/undo. Faster than |nvim_input()|. appropriately. Sets redo/undo. Faster than |nvim_input()|.
Lines break at LF ("\n").
Errors ('nomodifiable', `vim.paste()` failure, …) are Errors ('nomodifiable', `vim.paste()` failure, …) are
reflected in `err` but do not affect the return value (which reflected in `err` but do not affect the return value (which
@ -808,6 +809,7 @@ nvim_paste({data}, {phase}) *nvim_paste()*
Parameters: ~ Parameters: ~
{data} Multiline input. May be binary (containing NUL {data} Multiline input. May be binary (containing NUL
bytes). bytes).
{crlf} Also break lines at CR and CRLF.
{phase} -1: paste in a single call (i.e. without {phase} -1: paste in a single call (i.e. without
streaming). To "stream" a paste, call `nvim_paste` sequentially with these `phase` values: streaming). To "stream" a paste, call `nvim_paste` sequentially with these `phase` values:
• 1: starts the paste (exactly once) • 1: starts the paste (exactly once)

View File

@ -1211,7 +1211,7 @@ Dictionary nvim_get_namespaces(void)
/// Pastes at cursor, in any mode. /// Pastes at cursor, in any mode.
/// ///
/// Invokes the `vim.paste` handler, which handles each mode appropriately. /// Invokes the `vim.paste` handler, which handles each mode appropriately.
/// Sets redo/undo. Faster than |nvim_input()|. /// Sets redo/undo. Faster than |nvim_input()|. Lines break at LF ("\n").
/// ///
/// Errors ('nomodifiable', `vim.paste()` failure, …) are reflected in `err` /// Errors ('nomodifiable', `vim.paste()` failure, …) are reflected in `err`
/// but do not affect the return value (which is strictly decided by /// but do not affect the return value (which is strictly decided by
@ -1219,6 +1219,7 @@ Dictionary nvim_get_namespaces(void)
/// the next paste is initiated (phase 1 or -1). /// the next paste is initiated (phase 1 or -1).
/// ///
/// @param data Multiline input. May be binary (containing NUL bytes). /// @param data Multiline input. May be binary (containing NUL bytes).
/// @param crlf Also break lines at CR and CRLF.
/// @param phase -1: paste in a single call (i.e. without streaming). /// @param phase -1: paste in a single call (i.e. without streaming).
/// To "stream" a paste, call `nvim_paste` sequentially with /// To "stream" a paste, call `nvim_paste` sequentially with
/// these `phase` values: /// these `phase` values:
@ -1229,7 +1230,7 @@ Dictionary nvim_get_namespaces(void)
/// @return /// @return
/// - true: Client may continue pasting. /// - true: Client may continue pasting.
/// - false: Client must cancel the paste. /// - false: Client must cancel the paste.
Boolean nvim_paste(String data, Integer phase, Error *err) Boolean nvim_paste(String data, Boolean crlf, Integer phase, Error *err)
FUNC_API_SINCE(6) FUNC_API_SINCE(6)
{ {
static bool draining = false; static bool draining = false;
@ -1247,7 +1248,7 @@ Boolean nvim_paste(String data, Integer phase, Error *err)
// Skip remaining chunks. Report error only once per "stream". // Skip remaining chunks. Report error only once per "stream".
goto theend; goto theend;
} }
Array lines = string_to_array(data, true); Array lines = string_to_array(data, crlf);
ADD(args, ARRAY_OBJ(lines)); ADD(args, ARRAY_OBJ(lines));
ADD(args, INTEGER_OBJ(phase)); ADD(args, INTEGER_OBJ(phase));
rv = nvim_execute_lua(STATIC_CSTR_AS_STRING("return vim.paste(...)"), args, rv = nvim_execute_lua(STATIC_CSTR_AS_STRING("return vim.paste(...)"), args,

View File

@ -108,7 +108,7 @@ static void tinput_wait_enqueue(void **argv)
if (input->paste) { if (input->paste) {
Error err = ERROR_INIT; Error err = ERROR_INIT;
// Paste phase: "continue" (unless handler canceled). // Paste phase: "continue" (unless handler canceled).
input->paste = !nvim_paste(keys, input->paste, &err) input->paste = !nvim_paste(keys, true, input->paste, &err)
? 0 : (1 == input->paste ? 2 : input->paste); ? 0 : (1 == input->paste ? 2 : input->paste);
rbuffer_consumed(input->key_buffer, len); rbuffer_consumed(input->key_buffer, len);
rbuffer_reset(input->key_buffer); rbuffer_reset(input->key_buffer);

View File

@ -369,13 +369,13 @@ describe('API', function()
describe('nvim_paste', function() describe('nvim_paste', function()
it('validates args', function() it('validates args', function()
expect_err('Invalid phase: %-2', request, expect_err('Invalid phase: %-2', request,
'nvim_paste', 'foo', -2) 'nvim_paste', 'foo', true, -2)
expect_err('Invalid phase: 4', request, expect_err('Invalid phase: 4', request,
'nvim_paste', 'foo', 4) 'nvim_paste', 'foo', true, 4)
end) end)
it('non-streaming', function() it('non-streaming', function()
-- With final "\n". -- With final "\n".
nvim('paste', 'line 1\nline 2\nline 3\n', -1) nvim('paste', 'line 1\nline 2\nline 3\n', true, -1)
expect([[ expect([[
line 1 line 1
line 2 line 2
@ -385,7 +385,7 @@ describe('API', function()
eq(false, nvim('get_option', 'paste')) eq(false, nvim('get_option', 'paste'))
command('%delete _') command('%delete _')
-- Without final "\n". -- Without final "\n".
nvim('paste', 'line 1\nline 2\nline 3', -1) nvim('paste', 'line 1\nline 2\nline 3', true, -1)
expect([[ expect([[
line 1 line 1
line 2 line 2
@ -393,7 +393,7 @@ describe('API', function()
eq({0,3,6,0}, funcs.getpos('.')) eq({0,3,6,0}, funcs.getpos('.'))
command('%delete _') command('%delete _')
-- CRLF #10872 -- CRLF #10872
nvim('paste', 'line 1\r\nline 2\r\nline 3\r\n', -1) nvim('paste', 'line 1\r\nline 2\r\nline 3\r\n', true, -1)
expect([[ expect([[
line 1 line 1
line 2 line 2
@ -402,7 +402,7 @@ describe('API', function()
eq({0,4,1,0}, funcs.getpos('.')) eq({0,4,1,0}, funcs.getpos('.'))
command('%delete _') command('%delete _')
-- CRLF without final "\n". -- CRLF without final "\n".
nvim('paste', 'line 1\r\nline 2\r\nline 3\r', -1) nvim('paste', 'line 1\r\nline 2\r\nline 3\r', true, -1)
expect([[ expect([[
line 1 line 1
line 2 line 2
@ -411,7 +411,7 @@ describe('API', function()
eq({0,4,1,0}, funcs.getpos('.')) eq({0,4,1,0}, funcs.getpos('.'))
command('%delete _') command('%delete _')
-- CRLF without final "\r\n". -- CRLF without final "\r\n".
nvim('paste', 'line 1\r\nline 2\r\nline 3', -1) nvim('paste', 'line 1\r\nline 2\r\nline 3', true, -1)
expect([[ expect([[
line 1 line 1
line 2 line 2
@ -419,15 +419,20 @@ describe('API', function()
eq({0,3,6,0}, funcs.getpos('.')) eq({0,3,6,0}, funcs.getpos('.'))
command('%delete _') command('%delete _')
-- Various other junk. -- Various other junk.
nvim('paste', 'line 1\r\n\r\rline 2\nline 3\rline 4\r', -1) nvim('paste', 'line 1\r\n\r\rline 2\nline 3\rline 4\r', true, -1)
expect('line 1\n\n\nline 2\nline 3\nline 4\n') expect('line 1\n\n\nline 2\nline 3\nline 4\n')
eq({0,7,1,0}, funcs.getpos('.')) eq({0,7,1,0}, funcs.getpos('.'))
eq(false, nvim('get_option', 'paste')) eq(false, nvim('get_option', 'paste'))
end) end)
it('crlf=false does not break lines at CR, CRLF', function()
nvim('paste', 'line 1\r\n\r\rline 2\nline 3\rline 4\r', false, -1)
expect('line 1\r\n\r\rline 2\nline 3\rline 4\r')
eq({0,3,14,0}, funcs.getpos('.'))
end)
it('vim.paste() failure', function() it('vim.paste() failure', function()
nvim('execute_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {}) nvim('execute_lua', 'vim.paste = (function(lines, phase) error("fake fail") end)', {})
expect_err([[Error executing lua: %[string "%<nvim>"]:1: fake fail]], expect_err([[Error executing lua: %[string "%<nvim>"]:1: fake fail]],
request, 'nvim_paste', 'line 1\nline 2\nline 3', 1) request, 'nvim_paste', 'line 1\nline 2\nline 3', false, 1)
end) end)
end) end)

View File

@ -400,6 +400,17 @@ describe('TUI', function()
]]} ]]}
end) end)
it('paste: vim.paste() cancel (retval=false) #10865', function()
-- This test only exercises the "cancel" case. Use-case would be "dangling
-- paste", but that is not implemented yet. #10865
child_session:request('nvim_execute_lua', [[
vim.paste = function(lines, phase) return false end
]], {})
feed_data('\027[200~line A\nline B\n\027[201~')
feed_data('ifoo\n\027\000')
expect_child_buf_lines({'foo',''})
end)
it("paste: 'nomodifiable' buffer", function() it("paste: 'nomodifiable' buffer", function()
child_session:request('nvim_command', 'set nomodifiable') child_session:request('nvim_command', 'set nomodifiable')
feed_data('\027[200~fail 1\nfail 2\n\027[201~') feed_data('\027[200~fail 1\nfail 2\n\027[201~')