mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
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
This commit is contained in:
parent
ca258db156
commit
930d6e38d4
@ -264,6 +264,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
|
|||||||
Integer start,
|
Integer start,
|
||||||
Integer end,
|
Integer end,
|
||||||
Boolean strict_indexing,
|
Boolean strict_indexing,
|
||||||
|
Arena *arena,
|
||||||
lua_State *lstate,
|
lua_State *lstate,
|
||||||
Error *err)
|
Error *err)
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
@ -295,18 +296,10 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id,
|
|||||||
|
|
||||||
size_t size = (size_t)(end - start);
|
size_t size = (size_t)(end - start);
|
||||||
|
|
||||||
init_line_array(lstate, &rv, size);
|
init_line_array(lstate, &rv, size, arena);
|
||||||
|
|
||||||
if (!buf_collect_lines(buf, size, (linenr_T)start, 0, (channel_id != VIML_INTERNAL_CALL), &rv,
|
buf_collect_lines(buf, size, (linenr_T)start, 0, (channel_id != VIML_INTERNAL_CALL), &rv,
|
||||||
lstate, err)) {
|
lstate, arena);
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
end:
|
|
||||||
if (ERROR_SET(err)) {
|
|
||||||
api_free_array(rv);
|
|
||||||
rv.items = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -763,8 +756,8 @@ early_end:
|
|||||||
ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer,
|
ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer,
|
||||||
Integer start_row, Integer start_col,
|
Integer start_row, Integer start_col,
|
||||||
Integer end_row, Integer end_col,
|
Integer end_row, Integer end_col,
|
||||||
Dict(empty) *opts, lua_State *lstate,
|
Dict(empty) *opts,
|
||||||
Error *err)
|
Arena *arena, lua_State *lstate, Error *err)
|
||||||
FUNC_API_SINCE(9)
|
FUNC_API_SINCE(9)
|
||||||
{
|
{
|
||||||
Array rv = ARRAY_DICT_INIT;
|
Array rv = ARRAY_DICT_INIT;
|
||||||
@ -799,44 +792,38 @@ ArrayOf(String) nvim_buf_get_text(uint64_t channel_id, Buffer buffer,
|
|||||||
|
|
||||||
size_t size = (size_t)(end_row - start_row) + 1;
|
size_t size = (size_t)(end_row - start_row) + 1;
|
||||||
|
|
||||||
init_line_array(lstate, &rv, size);
|
init_line_array(lstate, &rv, size, arena);
|
||||||
|
|
||||||
if (start_row == end_row) {
|
if (start_row == end_row) {
|
||||||
String line = buf_get_text(buf, start_row, start_col, end_col, err);
|
String line = buf_get_text(buf, start_row, start_col, end_col, err);
|
||||||
if (ERROR_SET(err)) {
|
if (ERROR_SET(err)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
push_linestr(lstate, &rv, line.data, line.size, 0, replace_nl);
|
push_linestr(lstate, &rv, line.data, line.size, 0, replace_nl, arena);
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
String str = buf_get_text(buf, start_row, start_col, MAXCOL - 1, err);
|
String str = buf_get_text(buf, start_row, start_col, MAXCOL - 1, err);
|
||||||
|
|
||||||
push_linestr(lstate, &rv, str.data, str.size, 0, replace_nl);
|
|
||||||
|
|
||||||
if (ERROR_SET(err)) {
|
if (ERROR_SET(err)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
push_linestr(lstate, &rv, str.data, str.size, 0, replace_nl, arena);
|
||||||
|
|
||||||
if (size > 2) {
|
if (size > 2) {
|
||||||
if (!buf_collect_lines(buf, size - 2, (linenr_T)start_row + 1, 1, replace_nl, &rv, lstate,
|
buf_collect_lines(buf, size - 2, (linenr_T)start_row + 1, 1, replace_nl, &rv, lstate, arena);
|
||||||
err)) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
str = buf_get_text(buf, end_row, 0, end_col, err);
|
str = buf_get_text(buf, end_row, 0, end_col, err);
|
||||||
push_linestr(lstate, &rv, str.data, str.size, (int)(size - 1), replace_nl);
|
|
||||||
|
|
||||||
if (ERROR_SET(err)) {
|
if (ERROR_SET(err)) {
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
push_linestr(lstate, &rv, str.data, str.size, (int)(size - 1), replace_nl, arena);
|
||||||
|
|
||||||
end:
|
end:
|
||||||
if (ERROR_SET(err)) {
|
if (ERROR_SET(err)) {
|
||||||
api_free_array(rv);
|
return (Array)ARRAY_DICT_INIT;
|
||||||
rv.size = 0;
|
|
||||||
rv.items = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
@ -1394,13 +1381,12 @@ static void fix_cursor_cols(win_T *win, linenr_T start_row, colnr_T start_col, l
|
|||||||
/// @param lstate Lua state. When NULL the Array is initialized instead.
|
/// @param lstate Lua state. When NULL the Array is initialized instead.
|
||||||
/// @param a Array to initialize
|
/// @param a Array to initialize
|
||||||
/// @param size Size of array
|
/// @param size Size of array
|
||||||
static inline void init_line_array(lua_State *lstate, Array *a, size_t size)
|
static inline void init_line_array(lua_State *lstate, Array *a, size_t size, Arena *arena)
|
||||||
{
|
{
|
||||||
if (lstate) {
|
if (lstate) {
|
||||||
lua_createtable(lstate, (int)size, 0);
|
lua_createtable(lstate, (int)size, 0);
|
||||||
} else {
|
} else {
|
||||||
a->size = size;
|
*a = arena_array(arena, size);
|
||||||
a->items = xcalloc(a->size, sizeof(Object));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1413,14 +1399,15 @@ static inline void init_line_array(lua_State *lstate, Array *a, size_t size)
|
|||||||
/// @param a Array to push onto when not using Lua
|
/// @param a Array to push onto when not using Lua
|
||||||
/// @param s String to push
|
/// @param s String to push
|
||||||
/// @param len Size of string
|
/// @param len Size of string
|
||||||
/// @param idx 0-based index to place s
|
/// @param idx 0-based index to place s (only used for Lua)
|
||||||
/// @param replace_nl Replace newlines ('\n') with null ('\0')
|
/// @param replace_nl Replace newlines ('\n') with null ('\0')
|
||||||
static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len, int idx,
|
static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len, int idx,
|
||||||
bool replace_nl)
|
bool replace_nl, Arena *arena)
|
||||||
{
|
{
|
||||||
if (lstate) {
|
if (lstate) {
|
||||||
// Vim represents NULs as NLs
|
// Vim represents NULs as NLs
|
||||||
if (s && replace_nl && strchr(s, '\n')) {
|
if (s && replace_nl && strchr(s, '\n')) {
|
||||||
|
// TODO(bfredl): could manage scratch space in the arena, for the NUL case
|
||||||
char *tmp = xmemdupz(s, len);
|
char *tmp = xmemdupz(s, len);
|
||||||
strchrsub(tmp, '\n', '\0');
|
strchrsub(tmp, '\n', '\0');
|
||||||
lua_pushlstring(lstate, tmp, len);
|
lua_pushlstring(lstate, tmp, len);
|
||||||
@ -1431,15 +1418,15 @@ static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len,
|
|||||||
lua_rawseti(lstate, -2, idx + 1);
|
lua_rawseti(lstate, -2, idx + 1);
|
||||||
} else {
|
} else {
|
||||||
String str = STRING_INIT;
|
String str = STRING_INIT;
|
||||||
if (s) {
|
if (len > 0) {
|
||||||
str = cbuf_to_string(s, len);
|
str = arena_string(arena, cbuf_as_string((char *)s, len));
|
||||||
if (replace_nl) {
|
if (replace_nl) {
|
||||||
// Vim represents NULs as NLs, but this may confuse clients.
|
// Vim represents NULs as NLs, but this may confuse clients.
|
||||||
strchrsub(str.data, '\n', '\0');
|
strchrsub(str.data, '\n', '\0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a->items[idx] = STRING_OBJ(str);
|
ADD_C(*a, STRING_OBJ(str));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1450,27 +1437,17 @@ static void push_linestr(lua_State *lstate, Array *a, const char *s, size_t len,
|
|||||||
/// @param n Number of lines to collect
|
/// @param n Number of lines to collect
|
||||||
/// @param replace_nl Replace newlines ("\n") with NUL
|
/// @param replace_nl Replace newlines ("\n") with NUL
|
||||||
/// @param start Line number to start from
|
/// @param start Line number to start from
|
||||||
/// @param start_idx First index to push to
|
/// @param start_idx First index to push to (only used for Lua)
|
||||||
/// @param[out] l If not NULL, Lines are copied here
|
/// @param[out] l If not NULL, Lines are copied here
|
||||||
/// @param[out] lstate If not NULL, Lines are pushed into a table onto the stack
|
/// @param[out] lstate If not NULL, Lines are pushed into a table onto the stack
|
||||||
/// @param err[out] Error, if any
|
/// @param err[out] Error, if any
|
||||||
/// @return true unless `err` was set
|
/// @return true unless `err` was set
|
||||||
bool buf_collect_lines(buf_T *buf, size_t n, linenr_T start, int start_idx, bool replace_nl,
|
void buf_collect_lines(buf_T *buf, size_t n, linenr_T start, int start_idx, bool replace_nl,
|
||||||
Array *l, lua_State *lstate, Error *err)
|
Array *l, lua_State *lstate, Arena *arena)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < n; i++) {
|
for (size_t i = 0; i < n; i++) {
|
||||||
linenr_T lnum = start + (linenr_T)i;
|
linenr_T lnum = start + (linenr_T)i;
|
||||||
|
|
||||||
if (lnum >= MAXLNUM) {
|
|
||||||
if (err != NULL) {
|
|
||||||
api_set_error(err, kErrorTypeValidation, "Line index is too high");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *bufstr = ml_get_buf(buf, lnum);
|
char *bufstr = ml_get_buf(buf, lnum);
|
||||||
push_linestr(lstate, l, bufstr, strlen(bufstr), start_idx + (int)i, replace_nl);
|
push_linestr(lstate, l, bufstr, strlen(bufstr), start_idx + (int)i, replace_nl, arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
@ -245,20 +245,18 @@ void buffer_insert(Buffer buffer, Integer lnum, ArrayOf(String) lines, Error *er
|
|||||||
/// @param index Line index
|
/// @param index Line index
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return Line string
|
/// @return Line string
|
||||||
String buffer_get_line(Buffer buffer, Integer index, Error *err)
|
String buffer_get_line(Buffer buffer, Integer index, Arena *arena, Error *err)
|
||||||
FUNC_API_DEPRECATED_SINCE(1)
|
FUNC_API_DEPRECATED_SINCE(1)
|
||||||
{
|
{
|
||||||
String rv = { .size = 0 };
|
String rv = { .size = 0 };
|
||||||
|
|
||||||
index = convert_index(index);
|
index = convert_index(index);
|
||||||
Array slice = nvim_buf_get_lines(0, buffer, index, index + 1, true, NULL, err);
|
Array slice = nvim_buf_get_lines(0, buffer, index, index + 1, true, arena, NULL, err);
|
||||||
|
|
||||||
if (!ERROR_SET(err) && slice.size) {
|
if (!ERROR_SET(err) && slice.size) {
|
||||||
rv = slice.items[0].data.string;
|
rv = slice.items[0].data.string;
|
||||||
}
|
}
|
||||||
|
|
||||||
xfree(slice.items);
|
|
||||||
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -319,12 +317,13 @@ ArrayOf(String) buffer_get_line_slice(Buffer buffer,
|
|||||||
Integer end,
|
Integer end,
|
||||||
Boolean include_start,
|
Boolean include_start,
|
||||||
Boolean include_end,
|
Boolean include_end,
|
||||||
|
Arena *arena,
|
||||||
Error *err)
|
Error *err)
|
||||||
FUNC_API_DEPRECATED_SINCE(1)
|
FUNC_API_DEPRECATED_SINCE(1)
|
||||||
{
|
{
|
||||||
start = convert_index(start) + !include_start;
|
start = convert_index(start) + !include_start;
|
||||||
end = convert_index(end) + include_end;
|
end = convert_index(end) + include_end;
|
||||||
return nvim_buf_get_lines(0, buffer, start, end, false, NULL, err);
|
return nvim_buf_get_lines(0, buffer, start, end, false, arena, NULL, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Replaces a line range on the buffer
|
/// Replaces a line range on the buffer
|
||||||
|
@ -656,10 +656,10 @@ void nvim_set_current_dir(String dir, Error *err)
|
|||||||
///
|
///
|
||||||
/// @param[out] err Error details, if any
|
/// @param[out] err Error details, if any
|
||||||
/// @return Current line string
|
/// @return Current line string
|
||||||
String nvim_get_current_line(Error *err)
|
String nvim_get_current_line(Arena *arena, Error *err)
|
||||||
FUNC_API_SINCE(1)
|
FUNC_API_SINCE(1)
|
||||||
{
|
{
|
||||||
return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, err);
|
return buffer_get_line(curbuf->handle, curwin->w_cursor.lnum - 1, arena, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Sets the current line.
|
/// Sets the current line.
|
||||||
|
@ -55,36 +55,33 @@ bool buf_updates_register(buf_T *buf, uint64_t channel_id, BufUpdateCallbacks cb
|
|||||||
kv_push(buf->update_channels, channel_id);
|
kv_push(buf->update_channels, channel_id);
|
||||||
|
|
||||||
if (send_buffer) {
|
if (send_buffer) {
|
||||||
Array args = ARRAY_DICT_INIT;
|
MAXSIZE_TEMP_ARRAY(args, 6);
|
||||||
args.size = 6;
|
|
||||||
args.items = xcalloc(args.size, sizeof(Object));
|
|
||||||
|
|
||||||
// the first argument is always the buffer handle
|
// the first argument is always the buffer handle
|
||||||
args.items[0] = BUFFER_OBJ(buf->handle);
|
ADD_C(args, BUFFER_OBJ(buf->handle));
|
||||||
args.items[1] = INTEGER_OBJ(buf_get_changedtick(buf));
|
ADD_C(args, INTEGER_OBJ(buf_get_changedtick(buf)));
|
||||||
// the first line that changed (zero-indexed)
|
// 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
|
// the last line that was changed
|
||||||
args.items[3] = INTEGER_OBJ(-1);
|
ADD_C(args, INTEGER_OBJ(-1));
|
||||||
Array linedata = ARRAY_DICT_INIT;
|
|
||||||
|
|
||||||
// collect buffer contents
|
// collect buffer contents
|
||||||
|
|
||||||
STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
|
STATIC_ASSERT(SIZE_MAX >= MAXLNUM, "size_t smaller than MAXLNUM");
|
||||||
size_t line_count = (size_t)buf->b_ml.ml_line_count;
|
size_t line_count = (size_t)buf->b_ml.ml_line_count;
|
||||||
|
|
||||||
if (line_count >= 1) {
|
Array linedata = ARRAY_DICT_INIT;
|
||||||
linedata.size = line_count;
|
Arena arena = ARENA_EMPTY;
|
||||||
linedata.items = xcalloc(line_count, sizeof(Object));
|
if (line_count > 0) {
|
||||||
|
linedata = arena_array(&arena, line_count);
|
||||||
buf_collect_lines(buf, line_count, 1, 0, true, &linedata, NULL, NULL);
|
buf_collect_lines(buf, line_count, 1, 0, true, &linedata, NULL, &arena);
|
||||||
}
|
}
|
||||||
|
|
||||||
args.items[4] = ARRAY_OBJ(linedata);
|
ADD_C(args, ARRAY_OBJ(linedata));
|
||||||
args.items[5] = BOOLEAN_OBJ(false);
|
ADD_C(args, BOOLEAN_OBJ(false));
|
||||||
|
|
||||||
rpc_send_event(channel_id, "nvim_buf_lines_event", args);
|
rpc_send_event(channel_id, "nvim_buf_lines_event", args);
|
||||||
api_free_array(args); // TODO(bfredl): no
|
arena_mem_free(arena_finish(&arena));
|
||||||
} else {
|
} else {
|
||||||
buf_updates_changedtick_single(buf, channel_id);
|
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) {
|
if (thecb != LUA_NOREF) {
|
||||||
Array args = ARRAY_DICT_INIT;
|
MAXSIZE_TEMP_ARRAY(args, 1);
|
||||||
Object items[1];
|
|
||||||
args.size = 1;
|
|
||||||
args.items = items;
|
|
||||||
|
|
||||||
// the first argument is always the buffer handle
|
// the first argument is always the buffer handle
|
||||||
args.items[0] = BUFFER_OBJ(buf->handle);
|
ADD_C(args, BUFFER_OBJ(buf->handle));
|
||||||
|
|
||||||
TEXTLOCK_WRAP({
|
TEXTLOCK_WRAP({
|
||||||
nlua_call_ref(thecb, keep ? "reload" : "detach", args, false, NULL);
|
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
|
// if one the channels doesn't work, put its ID here so we can remove it later
|
||||||
uint64_t badchannelid = 0;
|
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
|
// notify each of the active channels
|
||||||
for (size_t i = 0; i < kv_size(buf->update_channels); i++) {
|
for (size_t i = 0; i < kv_size(buf->update_channels); i++) {
|
||||||
uint64_t channelid = kv_A(buf->update_channels, i);
|
uint64_t channelid = kv_A(buf->update_channels, i);
|
||||||
|
|
||||||
// send through the changes now channel contents now
|
// send through the changes now channel contents now
|
||||||
Array args = ARRAY_DICT_INIT;
|
MAXSIZE_TEMP_ARRAY(args, 6);
|
||||||
args.size = 6;
|
|
||||||
args.items = xcalloc(args.size, sizeof(Object));
|
|
||||||
|
|
||||||
// the first argument is always the buffer handle
|
// 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
|
// 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)
|
// 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
|
// 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
|
// linedata of lines being swapped in
|
||||||
Array linedata = ARRAY_DICT_INIT;
|
ADD_C(args, ARRAY_OBJ(linedata));
|
||||||
if (num_added > 0) {
|
ADD_C(args, BOOLEAN_OBJ(false));
|
||||||
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);
|
|
||||||
if (!rpc_send_event(channelid, "nvim_buf_lines_event", args)) {
|
if (!rpc_send_event(channelid, "nvim_buf_lines_event", args)) {
|
||||||
// We can't unregister the channel while we're iterating over the
|
// We can't unregister the channel while we're iterating over the
|
||||||
// update_channels array, so we remember its ID to unregister it at
|
// update_channels array, so we remember its ID to unregister it at
|
||||||
// the end.
|
// the end.
|
||||||
badchannelid = channelid;
|
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
|
// 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);
|
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;
|
size_t j = 0;
|
||||||
for (size_t i = 0; i < kv_size(buf->update_callbacks); i++) {
|
for (size_t i = 0; i < kv_size(buf->update_callbacks); i++) {
|
||||||
BufUpdateCallbacks cb = kv_A(buf->update_callbacks, i);
|
BufUpdateCallbacks cb = kv_A(buf->update_callbacks, i);
|
||||||
bool keep = true;
|
bool keep = true;
|
||||||
if (cb.on_lines != LUA_NOREF && (cb.preview || !cmdpreview)) {
|
if (cb.on_lines != LUA_NOREF && (cb.preview || !cmdpreview)) {
|
||||||
Array args = ARRAY_DICT_INIT;
|
MAXSIZE_TEMP_ARRAY(args, 8); // 6 or 8 used
|
||||||
Object items[8];
|
|
||||||
args.size = 6; // may be increased to 8 below
|
|
||||||
args.items = items;
|
|
||||||
|
|
||||||
// the first argument is always the buffer handle
|
// 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
|
// 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)
|
// 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
|
// 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
|
// 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
|
// 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) {
|
if (cb.utf_sizes) {
|
||||||
args.size = 8;
|
ADD_C(args, INTEGER_OBJ((Integer)deleted_codepoints));
|
||||||
args.items[6] = INTEGER_OBJ((Integer)deleted_codepoints);
|
ADD_C(args, INTEGER_OBJ((Integer)deleted_codeunits));
|
||||||
args.items[7] = INTEGER_OBJ((Integer)deleted_codeunits);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Object res;
|
Object res;
|
||||||
|
@ -55,15 +55,15 @@ local function add_function(fn)
|
|||||||
-- for specifying errors
|
-- for specifying errors
|
||||||
fn.parameters[#fn.parameters] = nil
|
fn.parameters[#fn.parameters] = nil
|
||||||
end
|
end
|
||||||
|
if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then
|
||||||
|
fn.has_lua_imp = true
|
||||||
|
fn.parameters[#fn.parameters] = nil
|
||||||
|
end
|
||||||
if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then
|
if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'arena' then
|
||||||
-- return value is allocated in an arena
|
-- return value is allocated in an arena
|
||||||
fn.arena_return = true
|
fn.arena_return = true
|
||||||
fn.parameters[#fn.parameters] = nil
|
fn.parameters[#fn.parameters] = nil
|
||||||
end
|
end
|
||||||
if #fn.parameters ~= 0 and fn.parameters[#fn.parameters][1] == 'lstate' then
|
|
||||||
fn.has_lua_imp = true
|
|
||||||
fn.parameters[#fn.parameters] = nil
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -1672,10 +1672,7 @@ Dictionary ns_get_hl_defs(NS ns_id, Dict(get_highlight) *opts, Arena *arena, Err
|
|||||||
return rv;
|
return rv;
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
api_free_integer(id);
|
return (Dictionary)ARRAY_DICT_INIT;
|
||||||
api_free_boolean(link);
|
|
||||||
Dictionary empty = ARRAY_DICT_INIT;
|
|
||||||
return empty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Outputs a highlight when doing ":hi MyHighlight"
|
/// Outputs a highlight when doing ":hi MyHighlight"
|
||||||
|
Loading…
Reference in New Issue
Block a user