diff options
author | bfredl <bjorn.linse@gmail.com> | 2024-02-10 13:13:52 +0100 |
---|---|---|
committer | bfredl <bjorn.linse@gmail.com> | 2024-02-11 11:37:55 +0100 |
commit | 930d6e38d4eb61adbb4f0d7328f55b31408b7cd1 (patch) | |
tree | 3467ab61eded7dc613ee9ba7b83198088e659870 /src/nvim/buffer_updates.c | |
parent | ca258db15668242c50a0529111398f53e4e01619 (diff) | |
download | rneovim-930d6e38d4eb61adbb4f0d7328f55b31408b7cd1.tar.gz rneovim-930d6e38d4eb61adbb4f0d7328f55b31408b7cd1.tar.bz2 rneovim-930d6e38d4eb61adbb4f0d7328f55b31408b7cd1.zip |
refactor(api): use an arena for nvim_buf_get_lines and buffer updates
Refactor some earlier "temporary Array" code in buffer_updates.c to use
the modern style of MAXSIZE_TEMP_ARRAY and ADD_C
Diffstat (limited to 'src/nvim/buffer_updates.c')
-rw-r--r-- | src/nvim/buffer_updates.c | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/src/nvim/buffer_updates.c b/src/nvim/buffer_updates.c index a91a890d0e..1a02ac78d7 100644 --- a/src/nvim/buffer_updates.c +++ b/src/nvim/buffer_updates.c @@ -55,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); } @@ -176,13 +173,10 @@ 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); @@ -219,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 @@ -268,38 +260,37 @@ 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; |