aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api
diff options
context:
space:
mode:
authorbfredl <bjorn.linse@gmail.com>2024-02-19 21:21:05 +0100
committerGitHub <noreply@github.com>2024-02-19 21:21:05 +0100
commit8952a89db588db10a9dba16356f9bbd35ca5fabb (patch)
treeac34d55b77303deadef6a7ed3f4202259324a249 /src/nvim/api
parent8fdc84d0aaec63d57203bdef4b88047479ad4fc1 (diff)
parent404707c7606389ccb6c6062bfe9e2ff30a2552af (diff)
downloadrneovim-8952a89db588db10a9dba16356f9bbd35ca5fabb.tar.gz
rneovim-8952a89db588db10a9dba16356f9bbd35ca5fabb.tar.bz2
rneovim-8952a89db588db10a9dba16356f9bbd35ca5fabb.zip
Merge pull request #27534 from bfredl/userarena
refactor(api): next PR to make use of the arena
Diffstat (limited to 'src/nvim/api')
-rw-r--r--src/nvim/api/command.c10
-rw-r--r--src/nvim/api/private/helpers.c16
-rw-r--r--src/nvim/api/tabpage.c10
-rw-r--r--src/nvim/api/vim.c110
4 files changed, 75 insertions, 71 deletions
diff --git a/src/nvim/api/command.c b/src/nvim/api/command.c
index a21c9e70a7..f2d5342a5f 100644
--- a/src/nvim/api/command.c
+++ b/src/nvim/api/command.c
@@ -1166,10 +1166,10 @@ err:
/// @param[out] err Error details, if any.
///
/// @returns Map of maps describing commands.
-Dictionary nvim_get_commands(Dict(get_commands) *opts, Error *err)
+Dictionary nvim_get_commands(Dict(get_commands) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(4)
{
- return nvim_buf_get_commands(-1, opts, err);
+ return nvim_buf_get_commands(-1, opts, arena, err);
}
/// Gets a map of buffer-local |user-commands|.
@@ -1179,7 +1179,7 @@ Dictionary nvim_get_commands(Dict(get_commands) *opts, Error *err)
/// @param[out] err Error details, if any.
///
/// @returns Map of maps describing commands.
-Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Error *err)
+Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(4)
{
bool global = (buffer == -1);
@@ -1192,12 +1192,12 @@ Dictionary nvim_buf_get_commands(Buffer buffer, Dict(get_commands) *opts, Error
api_set_error(err, kErrorTypeValidation, "builtin=true not implemented");
return (Dictionary)ARRAY_DICT_INIT;
}
- return commands_array(NULL);
+ return commands_array(NULL, arena);
}
buf_T *buf = find_buffer_by_handle(buffer, err);
if (opts->builtin || !buf) {
return (Dictionary)ARRAY_DICT_INIT;
}
- return commands_array(buf);
+ return commands_array(buf, arena);
}
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index 63c5689109..14f4046a56 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -456,9 +456,10 @@ String ga_take_string(garray_T *ga)
/// @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 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++) {
const char *start = input.data + i;
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) {
i += 1; // Advance past CRLF.
}
- String s = {
- .size = line_len,
- .data = xmemdupz(start, line_len),
- };
+ String s = CBUF_TO_ARENA_STR(arena, start, 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.
// This is "readfile()-style", see also ":help channel-lines".
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.
diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c
index 109075df8e..040abb1e3f 100644
--- a/src/nvim/api/tabpage.c
+++ b/src/nvim/api/tabpage.c
@@ -19,7 +19,7 @@
/// @param tabpage Tabpage handle, or 0 for current tabpage
/// @param[out] err Error details, if any
/// @return List of windows in `tabpage`
-ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err)
+ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Arena *arena, Error *err)
FUNC_API_SINCE(1)
{
Array rv = ARRAY_DICT_INIT;
@@ -29,15 +29,15 @@ ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err)
return rv;
}
+ size_t n = 0;
FOR_ALL_WINDOWS_IN_TAB(wp, tab) {
- rv.size++;
+ n++;
}
- rv.items = xmalloc(sizeof(Object) * rv.size);
- size_t i = 0;
+ rv = arena_array(arena, n);
FOR_ALL_WINDOWS_IN_TAB(wp, tab) {
- rv.items[i++] = WINDOW_OBJ(wp->handle);
+ ADD_C(rv, WINDOW_OBJ(wp->handle));
}
return rv;
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index d161dca050..e472f5d160 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -543,17 +543,22 @@ Integer nvim_strwidth(String text, Error *err)
/// Gets the paths contained in |runtime-search-path|.
///
/// @return List of paths
-ArrayOf(String) nvim_list_runtime_paths(Error *err)
+ArrayOf(String) nvim_list_runtime_paths(Arena *arena, Error *err)
FUNC_API_SINCE(1)
{
- return nvim_get_runtime_file(NULL_STRING, true, err);
+ return nvim_get_runtime_file(NULL_STRING, true, arena, err);
}
-Array nvim__runtime_inspect(void)
+Array nvim__runtime_inspect(Arena *arena)
{
- return runtime_inspect();
+ return runtime_inspect(arena);
}
+typedef struct {
+ ArrayBuilder rv;
+ Arena *arena;
+} RuntimeCookie;
+
/// Find files in runtime directories
///
/// "name" can contain wildcards. For example
@@ -566,25 +571,27 @@ Array nvim__runtime_inspect(void)
/// @param name pattern of files to search for
/// @param all whether to return all matches or only the first
/// @return list of absolute paths to the found files
-ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Error *err)
+ArrayOf(String) nvim_get_runtime_file(String name, Boolean all, Arena *arena, Error *err)
FUNC_API_SINCE(7)
FUNC_API_FAST
{
- Array rv = ARRAY_DICT_INIT;
+ RuntimeCookie cookie = { .rv = ARRAY_DICT_INIT, .arena = arena, };
+ kvi_init(cookie.rv);
int flags = DIP_DIRFILE | (all ? DIP_ALL : 0);
TRY_WRAP(err, {
- do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &rv);
+ do_in_runtimepath((name.size ? name.data : ""), flags, find_runtime_cb, &cookie);
});
- return rv;
+ return arena_take_arraybuilder(arena, &cookie.rv);
}
-static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *cookie)
+static bool find_runtime_cb(int num_fnames, char **fnames, bool all, void *c)
{
- Array *rv = (Array *)cookie;
+ RuntimeCookie *cookie = (RuntimeCookie *)c;
for (int i = 0; i < num_fnames; i++) {
- ADD(*rv, CSTR_TO_OBJ(fnames[i]));
+ // TODO(bfredl): consider memory management of gen_expand_wildcards() itself
+ kvi_push(cookie->rv, CSTR_TO_ARENA_OBJ(cookie->arena, fnames[i]));
if (!all) {
return true;
}
@@ -825,20 +832,19 @@ void nvim_err_writeln(String str)
/// Use |nvim_buf_is_loaded()| to check if a buffer is loaded.
///
/// @return List of buffer handles
-ArrayOf(Buffer) nvim_list_bufs(void)
+ArrayOf(Buffer) nvim_list_bufs(Arena *arena)
FUNC_API_SINCE(1)
{
- Array rv = ARRAY_DICT_INIT;
+ size_t n = 0;
FOR_ALL_BUFFERS(b) {
- rv.size++;
+ n++;
}
- rv.items = xmalloc(sizeof(Object) * rv.size);
- size_t i = 0;
+ Array rv = arena_array(arena, n);
FOR_ALL_BUFFERS(b) {
- rv.items[i++] = BUFFER_OBJ(b->handle);
+ ADD_C(rv, BUFFER_OBJ(b->handle));
}
return rv;
@@ -880,20 +886,19 @@ void nvim_set_current_buf(Buffer buffer, Error *err)
/// Gets the current list of window handles.
///
/// @return List of window handles
-ArrayOf(Window) nvim_list_wins(void)
+ArrayOf(Window) nvim_list_wins(Arena *arena)
FUNC_API_SINCE(1)
{
- Array rv = ARRAY_DICT_INIT;
+ size_t n = 0;
FOR_ALL_TAB_WINDOWS(tp, wp) {
- rv.size++;
+ n++;
}
- rv.items = xmalloc(sizeof(Object) * rv.size);
- size_t i = 0;
+ Array rv = arena_array(arena, n);
FOR_ALL_TAB_WINDOWS(tp, wp) {
- rv.items[i++] = WINDOW_OBJ(wp->handle);
+ ADD_C(rv, WINDOW_OBJ(wp->handle));
}
return rv;
@@ -1117,20 +1122,19 @@ void nvim_chan_send(Integer chan, String data, Error *err)
/// Gets the current list of tabpage handles.
///
/// @return List of tabpage handles
-ArrayOf(Tabpage) nvim_list_tabpages(void)
+ArrayOf(Tabpage) nvim_list_tabpages(Arena *arena)
FUNC_API_SINCE(1)
{
- Array rv = ARRAY_DICT_INIT;
+ size_t n = 0;
FOR_ALL_TABS(tp) {
- rv.size++;
+ n++;
}
- rv.items = xmalloc(sizeof(Object) * rv.size);
- size_t i = 0;
+ Array rv = arena_array(arena, n);
FOR_ALL_TABS(tp) {
- rv.items[i++] = TABPAGE_OBJ(tp->handle);
+ ADD_C(rv, TABPAGE_OBJ(tp->handle));
}
return rv;
@@ -1201,14 +1205,13 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error
VALIDATE_INT((phase >= -1 && phase <= 3), "phase", phase, {
return false;
});
- Array lines = ARRAY_DICT_INIT;
if (phase == -1 || phase == 1) { // Start of paste-stream.
draining = false;
} else if (draining) {
// Skip remaining chunks. Report error only once per "stream".
goto theend;
}
- lines = string_to_array(data, crlf);
+ Array lines = string_to_array(data, crlf, arena);
MAXSIZE_TEMP_ARRAY(args, 2);
ADD_C(args, ARRAY_OBJ(lines));
ADD_C(args, INTEGER_OBJ(phase));
@@ -1239,7 +1242,6 @@ Boolean nvim_paste(String data, Boolean crlf, Integer phase, Arena *arena, Error
AppendCharToRedobuff(ESC); // Dot-repeat.
}
theend:
- api_free_array(lines);
if (cancel || phase == -1 || phase == 3) { // End of paste-stream.
draining = false;
}
@@ -1260,24 +1262,27 @@ theend:
/// @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[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_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, {
- goto cleanup;
+ return;
});
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++) {
VALIDATE_T("line", kObjectTypeString, lines.items[i].type, {
- goto cleanup;
+ return;
});
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);
}
@@ -1290,10 +1295,6 @@ void nvim_put(ArrayOf(String) lines, String type, Boolean after, Boolean follow,
msg_silent--;
VIsual_active = VIsual_was_active;
});
-
-cleanup:
- free_register(reg);
- xfree(reg);
}
/// Subscribes to event broadcasts.
@@ -1583,13 +1584,12 @@ Array nvim_get_api_info(uint64_t channel_id, Arena *arena)
///
/// @param[out] err Error details, if any
void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version, String type,
- Dictionary methods, Dictionary attributes, Error *err)
+ Dictionary methods, Dictionary attributes, Arena *arena, Error *err)
FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY
{
- Dictionary info = ARRAY_DICT_INIT;
- PUT(info, "name", copy_object(STRING_OBJ(name), NULL));
+ MAXSIZE_TEMP_DICT(info, 5);
+ PUT_C(info, "name", STRING_OBJ(name));
- version = copy_dictionary(version, NULL);
bool has_major = false;
for (size_t i = 0; i < version.size; i++) {
if (strequal(version.items[i].key.data, "major")) {
@@ -1598,15 +1598,21 @@ void nvim_set_client_info(uint64_t channel_id, String name, Dictionary version,
}
}
if (!has_major) {
- PUT(version, "major", INTEGER_OBJ(0));
+ Dictionary v = arena_dict(arena, version.size + 1);
+ if (version.size) {
+ memcpy(v.items, version.items, version.size * sizeof(v.items[0]));
+ v.size = version.size;
+ }
+ PUT_C(v, "major", INTEGER_OBJ(0));
+ version = v;
}
- PUT(info, "version", DICTIONARY_OBJ(version));
+ PUT_C(info, "version", DICTIONARY_OBJ(version));
- PUT(info, "type", copy_object(STRING_OBJ(type), NULL));
- PUT(info, "methods", DICTIONARY_OBJ(copy_dictionary(methods, NULL)));
- PUT(info, "attributes", DICTIONARY_OBJ(copy_dictionary(attributes, NULL)));
+ PUT_C(info, "type", STRING_OBJ(type));
+ PUT_C(info, "methods", DICTIONARY_OBJ(methods));
+ PUT_C(info, "attributes", DICTIONARY_OBJ(attributes));
- rpc_set_client_info(channel_id, info);
+ rpc_set_client_info(channel_id, copy_dictionary(info, NULL));
}
/// Gets information about a channel.