refactor(api): use arena for nvim_put and nvim_paste

This commit is contained in:
bfredl
2024-02-19 12:07:16 +01:00
parent d14eefaee9
commit 404707c760
3 changed files with 17 additions and 25 deletions

View File

@@ -456,9 +456,10 @@ String ga_take_string(garray_T *ga)
/// @param input Binary string /// @param input Binary string
/// @param crlf Also break lines at CR and CRLF. /// @param crlf Also break lines at CR and CRLF.
/// @return [allocated] String array /// @return [allocated] String array
Array string_to_array(const String input, bool crlf) Array string_to_array(const String input, bool crlf, Arena *arena)
{ {
Array ret = ARRAY_DICT_INIT; ArrayBuilder ret = ARRAY_DICT_INIT;
kvi_init(ret);
for (size_t i = 0; i < input.size; i++) { for (size_t i = 0; i < input.size; i++) {
const char *start = input.data + i; const char *start = input.data + i;
const char *end = start; const char *end = start;
@@ -473,20 +474,17 @@ Array string_to_array(const String input, bool crlf)
if (crlf && *end == CAR && i + 1 < input.size && *(end + 1) == NL) { if (crlf && *end == CAR && i + 1 < input.size && *(end + 1) == NL) {
i += 1; // Advance past CRLF. i += 1; // Advance past CRLF.
} }
String s = { String s = CBUF_TO_ARENA_STR(arena, start, line_len);
.size = line_len,
.data = xmemdupz(start, line_len),
};
memchrsub(s.data, NUL, NL, line_len); memchrsub(s.data, NUL, NL, line_len);
ADD(ret, STRING_OBJ(s)); kvi_push(ret, STRING_OBJ(s));
// If line ends at end-of-buffer, add empty final item. // If line ends at end-of-buffer, add empty final item.
// This is "readfile()-style", see also ":help channel-lines". // This is "readfile()-style", see also ":help channel-lines".
if (i + 1 == input.size && (*end == NL || (crlf && *end == CAR))) { if (i + 1 == input.size && (*end == NL || (crlf && *end == CAR))) {
ADD(ret, STRING_OBJ(STRING_INIT)); kvi_push(ret, STRING_OBJ(STRING_INIT));
} }
} }
return ret; return arena_take_arraybuilder(arena, &ret);
} }
/// Normalizes 0-based indexes to buffer line numbers. /// Normalizes 0-based indexes to buffer line numbers.

View File

@@ -1205,14 +1205,13 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error
VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, { VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, {
return false; return false;
}); });
Array lines = ARRAY_DICT_INIT;
if (phase == -1 || phase == 1) { // Start of paste-stream. if (phase == -1 || phase == 1) { // Start of paste-stream.
draining = false; draining = false;
} else if (draining) { } else if (draining) {
// Skip remaining chunks. Report error only once per "stream". // Skip remaining chunks. Report error only once per "stream".
goto theend; goto theend;
} }
lines = string_to_array(data, crlf); Array lines = string_to_array(data, crlf, arena);
MAXSIZE_TEMP_ARRAY(args, 2); MAXSIZE_TEMP_ARRAY(args, 2);
ADD_C(args, ARRAY_OBJ(lines)); ADD_C(args, ARRAY_OBJ(lines));
ADD_C(args, INTEGER_OBJ(phase)); ADD_C(args, INTEGER_OBJ(phase));
@@ -1243,7 +1242,6 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error
AppendCharToRedobuff(ESC); // Dot-repeat. AppendCharToRedobuff(ESC); // Dot-repeat.
} }
theend: theend:
api_free_array(lines);
if (cancel || phase == -1 || phase == 3) { // End of paste-stream. if (cancel || phase == -1 || phase == 3) { // End of paste-stream.
draining = false; draining = false;
} }
@@ -1264,24 +1262,27 @@ theend:
/// @param after If true insert after cursor (like |p|), or before (like |P|). /// @param after If true insert after cursor (like |p|), or before (like |P|).
/// @param follow If true place cursor at end of inserted text. /// @param follow If true place cursor at end of inserted text.
/// @param[out] err Error details, if any /// @param[out] err Error details, if any
void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Error *err) void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow, Arena *arena,
Error *err)
FUNC_API_SINCE(6) FUNC_API_SINCE(6)
FUNC_API_TEXTLOCK_ALLOW_CMDWIN FUNC_API_TEXTLOCK_ALLOW_CMDWIN
{ {
yankreg_T *reg = xcalloc(1, sizeof(yankreg_T)); yankreg_T reg[1] = { 0 };
VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, { VALIDATE_S((prepare_yankreg_from_object(reg, type, lines.size)), "type", type.data, {
goto cleanup; return;
}); });
if (lines.size == 0) { if (lines.size == 0) {
goto cleanup; // Nothing to do. return; // Nothing to do.
} }
reg->y_array = arena_alloc(arena, lines.size * sizeof(uint8_t *), true);
reg->y_size = lines.size;
for (size_t i = 0; i < lines.size; i++) { for (size_t i = 0; i < lines.size; i++) {
VALIDATE_T("line", kObjectTypeString, lines.items[i].type, { VALIDATE_T("line", kObjectTypeString, lines.items[i].type, {
goto cleanup; return;
}); });
String line = lines.items[i].data.string; String line = lines.items[i].data.string;
reg->y_array[i] = xmemdupz(line.data, line.size); reg->y_array[i] = arena_memdupz(arena, line.data, line.size);
memchrsub(reg->y_array[i], NUL, NL, line.size); memchrsub(reg->y_array[i], NUL, NL, line.size);
} }
@@ -1294,10 +1295,6 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow,
msg_silent--; msg_silent--;
VIsual_active = VIsual_was_active; VIsual_active = VIsual_was_active;
}); });
cleanup:
free_register(reg);
xfree(reg);
} }
/// Subscribes to event broadcasts. /// Subscribes to event broadcasts.

View File

@@ -6499,8 +6499,6 @@ bool prepare_yankreg_from_object(yankreg_T *reg, String regtype, size_t lines)
} }
} }
reg->y_array = xcalloc(lines, sizeof(uint8_t *));
reg->y_size = lines;
reg->additional_data = NULL; reg->additional_data = NULL;
reg->timestamp = 0; reg->timestamp = 0;
return true; return true;
@@ -6513,7 +6511,6 @@ void finish_yankreg_from_object(yankreg_T *reg, bool clipboard_adjust)
// but otherwise there is no line after the final newline // but otherwise there is no line after the final newline
if (reg->y_type != kMTCharWise) { if (reg->y_type != kMTCharWise) {
if (reg->y_type == kMTUnknown || clipboard_adjust) { if (reg->y_type == kMTUnknown || clipboard_adjust) {
xfree(reg->y_array[reg->y_size - 1]);
reg->y_size--; reg->y_size--;
} }
if (reg->y_type == kMTUnknown) { if (reg->y_type == kMTUnknown) {