aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/buffer_updates.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/buffer_updates.c')
-rw-r--r--src/nvim/buffer_updates.c114
1 files changed, 52 insertions, 62 deletions
diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c
index 01bcb9d7be..e725678937 100644
--- a/src/nvim/buffer_updates.c
+++ b/src/nvim/buffer_updates.c
@@ -11,7 +11,6 @@
#include "nvim/buffer.h"
#include "nvim/buffer_defs.h"
#include "nvim/buffer_updates.h"
-#include "nvim/func_attr.h"
#include "nvim/globals.h"
#include "nvim/log.h"
#include "nvim/lua/executor.h"
@@ -22,7 +21,7 @@
#include "nvim/types_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
-# include "buffer_updates.c.generated.h" // IWYU pragma: export
+# include "buffer_updates.c.generated.h"
#endif
// Register a channel. Return True if the channel was added, or already added.
@@ -56,36 +55,33 @@ bool buf_updates_register(buf_T *buf, uint64_t channel_id, BufUpdateCallbacks cb
kv_push(buf->update_channels, channel_id);
if (send_buffer) {
- Array args = ARRAY_DICT_INIT;
- args.size = 6;
- args.items = xcalloc(args.size, sizeof(Object));
+ MAXSIZE_TEMP_ARRAY(args, 6);
// the first argument is always the buffer handle
- args.items[0] = BUFFER_OBJ(buf->handle);
- args.items[1] = INTEGER_OBJ(buf_get_changedtick(buf));
+ ADD_C(args, BUFFER_OBJ(buf->handle));
+ ADD_C(args, INTEGER_OBJ(buf_get_changedtick(buf)));
// the first line that changed (zero-indexed)
- args.items[2] = INTEGER_OBJ(0);
+ ADD_C(args, INTEGER_OBJ(0));
// the last line that was changed
- args.items[3] = INTEGER_OBJ(-1);
- Array linedata = ARRAY_DICT_INIT;
+ ADD_C(args, INTEGER_OBJ(-1));
// collect buffer contents
STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
size_t line_count = (size_t)buf->b_ml.ml_line_count;
- if (line_count >= 1) {
- linedata.size = line_count;
- linedata.items = xcalloc(line_count, sizeof(Object));
-
- buf_collect_lines(buf, line_count, 1, 0, true, &linedata, NULL, NULL);
+ Array linedata = ARRAY_DICT_INIT;
+ Arena arena = ARENA_EMPTY;
+ if (line_count > 0) {
+ linedata = arena_array(&arena, line_count);
+ buf_collect_lines(buf, line_count, 1, 0, true, &linedata, NULL, &arena);
}
- args.items[4] = ARRAY_OBJ(linedata);
- args.items[5] = BOOLEAN_OBJ(false);
+ ADD_C(args, ARRAY_OBJ(linedata));
+ ADD_C(args, BOOLEAN_OBJ(false));
rpc_send_event(channel_id, "nvim_buf_lines_event", args);
- api_free_array(args); // TODO(bfredl): no
+ arena_mem_free(arena_finish(&arena));
} else {
buf_updates_changedtick_single(buf, channel_id);
}
@@ -177,16 +173,13 @@ void buf_updates_unload(buf_T *buf, bool can_reload)
}
if (thecb != LUA_NOREF) {
- Array args = ARRAY_DICT_INIT;
- Object items[1];
- args.size = 1;
- args.items = items;
+ MAXSIZE_TEMP_ARRAY(args, 1);
// the first argument is always the buffer handle
- args.items[0] = BUFFER_OBJ(buf->handle);
+ ADD_C(args, BUFFER_OBJ(buf->handle));
TEXTLOCK_WRAP({
- nlua_call_ref(thecb, keep ? "reload" : "detach", args, false, NULL);
+ nlua_call_ref(thecb, keep ? "reload" : "detach", args, false, NULL, NULL);
});
}
@@ -220,45 +213,43 @@ void buf_updates_send_changes(buf_T *buf, linenr_T firstline, int64_t num_added,
// if one the channels doesn't work, put its ID here so we can remove it later
uint64_t badchannelid = 0;
+ Arena arena = ARENA_EMPTY;
+ Array linedata = ARRAY_DICT_INIT;
+ if (num_added > 0 && kv_size(buf->update_channels)) {
+ STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
+ linedata = arena_array(&arena, (size_t)num_added);
+ buf_collect_lines(buf, (size_t)num_added, firstline, 0, true, &linedata,
+ NULL, &arena);
+ }
+
// notify each of the active channels
for (size_t i = 0; i < kv_size(buf->update_channels); i++) {
uint64_t channelid = kv_A(buf->update_channels, i);
// send through the changes now channel contents now
- Array args = ARRAY_DICT_INIT;
- args.size = 6;
- args.items = xcalloc(args.size, sizeof(Object));
+ MAXSIZE_TEMP_ARRAY(args, 6);
// the first argument is always the buffer handle
- args.items[0] = BUFFER_OBJ(buf->handle);
+ ADD_C(args, BUFFER_OBJ(buf->handle));
// next argument is b:changedtick
- args.items[1] = send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL;
+ ADD_C(args, send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL);
// the first line that changed (zero-indexed)
- args.items[2] = INTEGER_OBJ(firstline - 1);
+ ADD_C(args, INTEGER_OBJ(firstline - 1));
// the last line that was changed
- args.items[3] = INTEGER_OBJ(firstline - 1 + num_removed);
+ ADD_C(args, INTEGER_OBJ(firstline - 1 + num_removed));
// linedata of lines being swapped in
- Array linedata = ARRAY_DICT_INIT;
- if (num_added > 0) {
- STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
- linedata.size = (size_t)num_added;
- linedata.items = xcalloc((size_t)num_added, sizeof(Object));
- buf_collect_lines(buf, (size_t)num_added, firstline, 0, true, &linedata,
- NULL, NULL);
- }
- args.items[4] = ARRAY_OBJ(linedata);
- args.items[5] = BOOLEAN_OBJ(false);
+ ADD_C(args, ARRAY_OBJ(linedata));
+ ADD_C(args, BOOLEAN_OBJ(false));
if (!rpc_send_event(channelid, "nvim_buf_lines_event", args)) {
// We can't unregister the channel while we're iterating over the
// update_channels array, so we remember its ID to unregister it at
// the end.
badchannelid = channelid;
}
- api_free_array(args); // TODO(bfredl): no
}
// We can only ever remove one dead channel at a time. This is OK because the
@@ -269,46 +260,45 @@ void buf_updates_send_changes(buf_T *buf, linenr_T firstline, int64_t num_added,
buf_updates_unregister(buf, badchannelid);
}
- // notify each of the active channels
+ // callbacks don't use linedata
+ arena_mem_free(arena_finish(&arena));
+
+ // notify each of the active callbacks
size_t j = 0;
for (size_t i = 0; i < kv_size(buf->update_callbacks); i++) {
BufUpdateCallbacks cb = kv_A(buf->update_callbacks, i);
bool keep = true;
if (cb.on_lines != LUA_NOREF && (cb.preview || !cmdpreview)) {
- Array args = ARRAY_DICT_INIT;
- Object items[8];
- args.size = 6; // may be increased to 8 below
- args.items = items;
+ MAXSIZE_TEMP_ARRAY(args, 8); // 6 or 8 used
// the first argument is always the buffer handle
- args.items[0] = BUFFER_OBJ(buf->handle);
+ ADD_C(args, BUFFER_OBJ(buf->handle));
// next argument is b:changedtick
- args.items[1] = send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL;
+ ADD_C(args, send_tick ? INTEGER_OBJ(buf_get_changedtick(buf)) : NIL);
// the first line that changed (zero-indexed)
- args.items[2] = INTEGER_OBJ(firstline - 1);
+ ADD_C(args, INTEGER_OBJ(firstline - 1));
// the last line that was changed
- args.items[3] = INTEGER_OBJ(firstline - 1 + num_removed);
+ ADD_C(args, INTEGER_OBJ(firstline - 1 + num_removed));
// the last line in the updated range
- args.items[4] = INTEGER_OBJ(firstline - 1 + num_added);
+ ADD_C(args, INTEGER_OBJ(firstline - 1 + num_added));
// byte count of previous contents
- args.items[5] = INTEGER_OBJ((Integer)deleted_bytes);
+ ADD_C(args, INTEGER_OBJ((Integer)deleted_bytes));
if (cb.utf_sizes) {
- args.size = 8;
- args.items[6] = INTEGER_OBJ((Integer)deleted_codepoints);
- args.items[7] = INTEGER_OBJ((Integer)deleted_codeunits);
+ ADD_C(args, INTEGER_OBJ((Integer)deleted_codepoints));
+ ADD_C(args, INTEGER_OBJ((Integer)deleted_codeunits));
}
Object res;
TEXTLOCK_WRAP({
- res = nlua_call_ref(cb.on_lines, "lines", args, false, NULL);
+ res = nlua_call_ref(cb.on_lines, "lines", args, kRetNilBool, NULL, NULL);
});
- if (res.type == kObjectTypeBoolean && res.data.boolean == true) {
+ if (LUARET_TRUTHY(res)) {
buffer_update_callbacks_free(cb);
keep = false;
}
@@ -355,10 +345,10 @@ void buf_updates_send_splice(buf_T *buf, int start_row, colnr_T start_col, bcoun
Object res;
TEXTLOCK_WRAP({
- res = nlua_call_ref(cb.on_bytes, "bytes", args, false, NULL);
+ res = nlua_call_ref(cb.on_bytes, "bytes", args, kRetNilBool, NULL, NULL);
});
- if (res.type == kObjectTypeBoolean && res.data.boolean == true) {
+ if (LUARET_TRUTHY(res)) {
buffer_update_callbacks_free(cb);
keep = false;
}
@@ -391,10 +381,10 @@ void buf_updates_changedtick(buf_T *buf)
Object res;
TEXTLOCK_WRAP({
- res = nlua_call_ref(cb.on_changedtick, "changedtick", args, false, NULL);
+ res = nlua_call_ref(cb.on_changedtick, "changedtick", args, kRetNilBool, NULL, NULL);
});
- if (res.type == kObjectTypeBoolean && res.data.boolean == true) {
+ if (LUARET_TRUTHY(res)) {
buffer_update_callbacks_free(cb);
keep = false;
}