aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2019-08-29 23:45:02 +0200
committerGitHub <noreply@github.com>2019-08-29 23:45:02 +0200
commit9f81acc076779f891160423657cc35e6ac37c3e6 (patch)
tree025dff4b1cfa364061b88d24ec5152725132453c /src
parent00d46f63286461eec4d7b2d7cae15fbe0d9cabdb (diff)
downloadrneovim-9f81acc076779f891160423657cc35e6ac37c3e6.tar.gz
rneovim-9f81acc076779f891160423657cc35e6ac37c3e6.tar.bz2
rneovim-9f81acc076779f891160423657cc35e6ac37c3e6.zip
paste: break lines at CR, CRLF #10877
Some terminals helpfully translate \n to \r. fix #10872 ref #10223
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/private/helpers.c31
-rw-r--r--src/nvim/api/vim.c2
2 files changed, 23 insertions, 10 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 3443f85e20..2e4874d7c6 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -745,19 +745,32 @@ String ga_take_string(garray_T *ga)
return str;
}
-/// Creates "readfile()-style" ArrayOf(String).
+/// Creates "readfile()-style" ArrayOf(String) from a binary string.
///
-/// - NUL bytes are replaced with NL (form-feed).
-/// - If last line ends with NL an extra empty list item is added.
-Array string_to_array(const String input)
+/// - Lines break at \n (NL/LF/line-feed).
+/// - NUL bytes are replaced with NL.
+/// - If the last byte is a linebreak an extra empty list item is added.
+///
+/// @param input Binary string
+/// @param crlf Also break lines at CR and CRLF.
+/// @return [allocated] String array
+Array string_to_array(const String input, bool crlf)
{
Array ret = ARRAY_DICT_INIT;
for (size_t i = 0; i < input.size; i++) {
const char *start = input.data + i;
- const char *end = xmemscan(start, NL, input.size - i);
- const size_t line_len = (size_t)(end - start);
+ const char *end = start;
+ size_t line_len = 0;
+ for (; line_len < input.size - i; line_len++) {
+ end = start + line_len;
+ if (*end == NL || (crlf && *end == CAR)) {
+ break;
+ }
+ }
i += line_len;
-
+ if (crlf && *end == CAR && i + 1 < input.size && *(end + 1) == NL) {
+ i += 1; // Advance past CRLF.
+ }
String s = {
.size = line_len,
.data = xmemdupz(start, line_len),
@@ -766,8 +779,8 @@ Array string_to_array(const String input)
ADD(ret, STRING_OBJ(s));
// If line ends at end-of-buffer, add empty final item.
// This is "readfile()-style", see also ":help channel-lines".
- if (i + 1 == input.size && end[0] == NL) {
- ADD(ret, STRING_OBJ(cchar_to_string(NUL)));
+ if (i + 1 == input.size && (*end == NL || (crlf && *end == CAR))) {
+ ADD(ret, STRING_OBJ(STRING_INIT));
}
}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 1ca0d8789d..8063a6f1fd 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -1247,7 +1247,7 @@ Boolean nvim_paste(String data, Integer phase, Error *err)
// Skip remaining chunks. Report error only once per "stream".
goto theend;
}
- Array lines = string_to_array(data);
+ Array lines = string_to_array(data, true);
ADD(args, ARRAY_OBJ(lines));
ADD(args, INTEGER_OBJ(phase));
rv = nvim_execute_lua(STATIC_CSTR_AS_STRING("return vim.paste(...)"), args,