mirror of
https://github.com/neovim/neovim.git
synced 2025-09-28 05:58:33 +00:00
refactor(api): use arena for nvim_put and nvim_paste
This commit is contained in:
@@ -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.
|
||||||
|
@@ -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.
|
||||||
|
@@ -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) {
|
||||||
|
Reference in New Issue
Block a user