Merge pull request #27391 from bfredl/arenarock

refactor(api): refactor more api functions to use arena return
This commit is contained in:
bfredl 2024-02-08 18:54:00 +01:00 committed by GitHub
commit 52b6a9a93b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 83 additions and 97 deletions

View File

@ -1262,28 +1262,27 @@ Object nvim_buf_call(Buffer buffer, LuaRef fun, Error *err)
return res;
}
Dictionary nvim__buf_stats(Buffer buffer, Error *err)
Dictionary nvim__buf_stats(Buffer buffer, Arena *arena, Error *err)
{
Dictionary rv = ARRAY_DICT_INIT;
buf_T *buf = find_buffer_by_handle(buffer, err);
if (!buf) {
return rv;
return (Dictionary)ARRAY_DICT_INIT;
}
Dictionary rv = arena_dict(arena, 7);
// Number of times the cached line was flushed.
// This should generally not increase while editing the same
// line in the same mode.
PUT(rv, "flush_count", INTEGER_OBJ(buf->flush_count));
PUT_C(rv, "flush_count", INTEGER_OBJ(buf->flush_count));
// lnum of current line
PUT(rv, "current_lnum", INTEGER_OBJ(buf->b_ml.ml_line_lnum));
PUT_C(rv, "current_lnum", INTEGER_OBJ(buf->b_ml.ml_line_lnum));
// whether the line has unflushed changes.
PUT(rv, "line_dirty", BOOLEAN_OBJ(buf->b_ml.ml_flags & ML_LINE_DIRTY));
PUT_C(rv, "line_dirty", BOOLEAN_OBJ(buf->b_ml.ml_flags & ML_LINE_DIRTY));
// NB: this should be zero at any time API functions are called,
// this exists to debug issues
PUT(rv, "dirty_bytes", INTEGER_OBJ((Integer)buf->deleted_bytes));
PUT(rv, "dirty_bytes2", INTEGER_OBJ((Integer)buf->deleted_bytes2));
PUT(rv, "virt_blocks", INTEGER_OBJ((Integer)buf_meta_total(buf, kMTMetaLines)));
PUT_C(rv, "dirty_bytes", INTEGER_OBJ((Integer)buf->deleted_bytes));
PUT_C(rv, "dirty_bytes2", INTEGER_OBJ((Integer)buf->deleted_bytes2));
PUT_C(rv, "virt_blocks", INTEGER_OBJ((Integer)buf_meta_total(buf, kMTMetaLines)));
u_header_T *uhp = NULL;
if (buf->b_u_curhead != NULL) {
@ -1292,7 +1291,7 @@ Dictionary nvim__buf_stats(Buffer buffer, Error *err)
uhp = buf->b_u_newhead;
}
if (uhp) {
PUT(rv, "uhp_extmark_size", INTEGER_OBJ((Integer)kv_size(uhp->uh_extmark)));
PUT_C(rv, "uhp_extmark_size", INTEGER_OBJ((Integer)kv_size(uhp->uh_extmark)));
}
return rv;

View File

@ -70,15 +70,15 @@ Integer nvim_create_namespace(String name)
/// Gets existing, non-anonymous |namespace|s.
///
/// @return dict that maps from names to namespace ids.
Dictionary nvim_get_namespaces(void)
Dictionary nvim_get_namespaces(Arena *arena)
FUNC_API_SINCE(5)
{
Dictionary retval = ARRAY_DICT_INIT;
Dictionary retval = arena_dict(arena, map_size(&namespace_ids));
String name;
handle_T id;
map_foreach(&namespace_ids, name, id, {
PUT(retval, name.data, INTEGER_OBJ(id));
PUT_C(retval, name.data, INTEGER_OBJ(id));
})
return retval;

View File

@ -1351,14 +1351,13 @@ Integer nvim_get_color_by_name(String name)
/// (e.g. 65535).
///
/// @return Map of color names and RGB values.
Dictionary nvim_get_color_map(void)
Dictionary nvim_get_color_map(Arena *arena)
FUNC_API_SINCE(1)
{
Dictionary colors = ARRAY_DICT_INIT;
Dictionary colors = arena_dict(arena, ARRAY_SIZE(color_name_table));
for (int i = 0; color_name_table[i].name != NULL; i++) {
PUT(colors, color_name_table[i].name,
INTEGER_OBJ(color_name_table[i].color));
PUT_C(colors, color_name_table[i].name, INTEGER_OBJ(color_name_table[i].color));
}
return colors;
}
@ -1438,16 +1437,16 @@ Object nvim_load_context(Dictionary dict, Error *err)
/// "blocking" is true if Nvim is waiting for input.
///
/// @returns Dictionary { "mode": String, "blocking": Boolean }
Dictionary nvim_get_mode(void)
Dictionary nvim_get_mode(Arena *arena)
FUNC_API_SINCE(2) FUNC_API_FAST
{
Dictionary rv = ARRAY_DICT_INIT;
char modestr[MODE_MAX_LENGTH];
Dictionary rv = arena_dict(arena, 2);
char *modestr = arena_alloc(arena, MODE_MAX_LENGTH, false);
get_mode(modestr);
bool blocked = input_blocking();
PUT(rv, "mode", CSTR_TO_OBJ(modestr));
PUT(rv, "blocking", BOOLEAN_OBJ(blocked));
PUT_C(rv, "mode", CSTR_AS_OBJ(modestr));
PUT_C(rv, "blocking", BOOLEAN_OBJ(blocked));
return rv;
}
@ -1848,14 +1847,14 @@ Float nvim__id_float(Float flt)
/// Gets internal stats.
///
/// @return Map of various internal stats.
Dictionary nvim__stats(void)
Dictionary nvim__stats(Arena *arena)
{
Dictionary rv = ARRAY_DICT_INIT;
PUT(rv, "fsync", INTEGER_OBJ(g_stats.fsync));
PUT(rv, "log_skip", INTEGER_OBJ(g_stats.log_skip));
PUT(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count()));
PUT(rv, "redraw", INTEGER_OBJ(g_stats.redraw));
PUT(rv, "arena_alloc_count", INTEGER_OBJ((Integer)arena_alloc_count));
Dictionary rv = arena_dict(arena, 5);
PUT_C(rv, "fsync", INTEGER_OBJ(g_stats.fsync));
PUT_C(rv, "log_skip", INTEGER_OBJ(g_stats.log_skip));
PUT_C(rv, "lua_refcount", INTEGER_OBJ(nlua_get_global_ref_count()));
PUT_C(rv, "redraw", INTEGER_OBJ(g_stats.redraw));
PUT_C(rv, "arena_alloc_count", INTEGER_OBJ((Integer)arena_alloc_count));
return rv;
}
@ -2151,7 +2150,7 @@ Array nvim_get_mark(String name, Dict(empty) *opts, Error *err)
/// |Dictionary| with these keys:
/// - start: (number) Byte index (0-based) of first character that uses the highlight.
/// - group: (string) Name of highlight group.
Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *err)
Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Arena *arena, Error *err)
FUNC_API_SINCE(8) FUNC_API_FAST
{
Dictionary result = ARRAY_DICT_INIT;
@ -2260,58 +2259,61 @@ Dictionary nvim_eval_statusline(String str, Dict(eval_statusline) *opts, Error *
&& global_stl_height() > 0)) ? Columns : wp->w_width;
}
char buf[MAXPATHL];
result = arena_dict(arena, 3);
char *buf = arena_alloc(arena, MAXPATHL, false);
stl_hlrec_t *hltab;
size_t hltab_len = 0;
// Temporarily reset 'cursorbind' to prevent side effects from moving the cursor away and back.
int p_crb_save = wp->w_p_crb;
wp->w_p_crb = false;
int width = build_stl_str_hl(wp, buf, sizeof(buf), str.data, -1, 0, fillchar, maxwidth,
opts->highlights ? &hltab : NULL, NULL,
int width = build_stl_str_hl(wp, buf, MAXPATHL, str.data, -1, 0, fillchar, maxwidth,
opts->highlights ? &hltab : NULL, &hltab_len, NULL,
statuscol_lnum ? &statuscol : NULL);
PUT(result, "width", INTEGER_OBJ(width));
PUT_C(result, "width", INTEGER_OBJ(width));
// Restore original value of 'cursorbind'
wp->w_p_crb = p_crb_save;
if (opts->highlights) {
Array hl_values = ARRAY_DICT_INIT;
const char *grpname;
Array hl_values = arena_array(arena, hltab_len + 1);
char user_group[15]; // strlen("User") + strlen("2147483647") + NUL
// If first character doesn't have a defined highlight,
// add the default highlight at the beginning of the highlight list
if (hltab->start == NULL || (hltab->start - buf) != 0) {
Dictionary hl_info = ARRAY_DICT_INIT;
grpname = get_default_stl_hl(opts->use_tabline ? NULL : wp, opts->use_winbar, stc_hl_id);
Dictionary hl_info = arena_dict(arena, 2);
const char *grpname = get_default_stl_hl(opts->use_tabline ? NULL : wp,
opts->use_winbar, stc_hl_id);
PUT(hl_info, "start", INTEGER_OBJ(0));
PUT(hl_info, "group", CSTR_TO_OBJ(grpname));
PUT_C(hl_info, "start", INTEGER_OBJ(0));
PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname));
ADD(hl_values, DICTIONARY_OBJ(hl_info));
ADD_C(hl_values, DICTIONARY_OBJ(hl_info));
}
for (stl_hlrec_t *sp = hltab; sp->start != NULL; sp++) {
Dictionary hl_info = ARRAY_DICT_INIT;
Dictionary hl_info = arena_dict(arena, 2);
PUT(hl_info, "start", INTEGER_OBJ(sp->start - buf));
PUT_C(hl_info, "start", INTEGER_OBJ(sp->start - buf));
const char *grpname;
if (sp->userhl == 0) {
grpname = get_default_stl_hl(opts->use_tabline ? NULL : wp, opts->use_winbar, stc_hl_id);
} else if (sp->userhl < 0) {
grpname = syn_id2name(-sp->userhl);
} else {
snprintf(user_group, sizeof(user_group), "User%d", sp->userhl);
grpname = user_group;
grpname = arena_memdupz(arena, user_group, strlen(user_group));
}
PUT(hl_info, "group", CSTR_TO_OBJ(grpname));
ADD(hl_values, DICTIONARY_OBJ(hl_info));
PUT_C(hl_info, "group", CSTR_AS_OBJ((char *)grpname));
ADD_C(hl_values, DICTIONARY_OBJ(hl_info));
}
PUT(result, "highlights", ARRAY_OBJ(hl_values));
PUT_C(result, "highlights", ARRAY_OBJ(hl_values));
}
PUT(result, "str", CSTR_TO_OBJ(buf));
PUT_C(result, "str", CSTR_AS_OBJ(buf));
return result;
}
@ -2336,15 +2338,15 @@ void nvim_error_event(uint64_t channel_id, Integer lvl, String data)
/// @return Dictionary containing these keys:
/// - winid: (number) floating window id
/// - bufnr: (number) buffer id in floating window
Dictionary nvim_complete_set(Integer index, Dict(complete_set) *opts)
Dictionary nvim_complete_set(Integer index, Dict(complete_set) *opts, Arena *arena)
FUNC_API_SINCE(12)
{
Dictionary rv = ARRAY_DICT_INIT;
Dictionary rv = arena_dict(arena, 2);
if (HAS_KEY(opts, complete_set, info)) {
win_T *wp = pum_set_info((int)index, opts->info.data);
if (wp) {
PUT(rv, "winid", WINDOW_OBJ(wp->handle));
PUT(rv, "bufnr", BUFFER_OBJ(wp->w_buffer->handle));
PUT_C(rv, "winid", WINDOW_OBJ(wp->handle));
PUT_C(rv, "bufnr", BUFFER_OBJ(wp->w_buffer->handle));
}
}
return rv;

View File

@ -3326,7 +3326,7 @@ void maketitle(void)
if (*p_titlestring != NUL) {
if (stl_syntax & STL_IN_TITLE) {
build_stl_str_hl(curwin, buf, sizeof(buf), p_titlestring,
kOptTitlestring, 0, 0, maxlen, NULL, NULL, NULL);
kOptTitlestring, 0, 0, maxlen, NULL, NULL, NULL, NULL);
title_str = buf;
} else {
title_str = p_titlestring;
@ -3431,7 +3431,7 @@ void maketitle(void)
if (*p_iconstring != NUL) {
if (stl_syntax & STL_IN_ICON) {
build_stl_str_hl(curwin, icon_str, sizeof(buf), p_iconstring,
kOptIconstring, 0, 0, 0, NULL, NULL, NULL);
kOptIconstring, 0, 0, 0, NULL, NULL, NULL, NULL);
} else {
icon_str = p_iconstring;
}

View File

@ -535,7 +535,6 @@ for i = 1, #functions do
end
-- function call
local call_args = table.concat(args, ', ')
output:write('\n ')
if fn.return_type ~= 'void' then
-- has a return value, prefix the call with a declaration
@ -545,58 +544,40 @@ for i = 1, #functions do
-- write the function name and the opening parenthesis
output:write(fn.name .. '(')
local call_args = {}
if fn.receives_channel_id then
-- if the function receives the channel id, pass it as first argument
if #args > 0 or fn.can_fail then
output:write('channel_id, ')
if fn.receives_array_args then
-- if the function receives the array args, pass it the second argument
output:write('args, ')
end
output:write(call_args)
else
output:write('channel_id')
if fn.receives_array_args then
output:write(', args')
end
end
else
if fn.receives_array_args then
if #args > 0 or fn.call_fail then
output:write('args, ' .. call_args)
else
output:write('args')
end
else
output:write(call_args)
end
table.insert(call_args, 'channel_id')
end
if fn.receives_array_args then
table.insert(call_args, 'args')
end
for _, a in ipairs(args) do
table.insert(call_args, a)
end
if fn.arena_return then
output:write(', arena')
table.insert(call_args, 'arena')
end
if fn.has_lua_imp then
if #args > 0 then
output:write(', NULL')
else
output:write('NULL')
end
table.insert(call_args, 'NULL')
end
if fn.can_fail then
table.insert(call_args, 'error')
end
output:write(table.concat(call_args, ', '))
output:write(');\n')
if fn.can_fail then
-- if the function can fail, also pass a pointer to the local error object
if #args > 0 then
output:write(', error);\n')
else
output:write('error);\n')
end
-- and check for the error
output:write('\n if (ERROR_SET(error)) {')
output:write('\n goto cleanup;')
output:write('\n }\n')
else
output:write(');\n')
end
local ret_type = real_type(fn.return_type)

View File

@ -12,7 +12,7 @@ typedef struct {
char *name;
RgbValue color;
} color_name_table_T;
extern color_name_table_T color_name_table[];
extern color_name_table_T color_name_table[700];
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "highlight_group.h.generated.h"

View File

@ -411,7 +411,7 @@ static void win_redr_custom(win_T *wp, bool draw_winbar, bool draw_ruler)
// might change the option value and free the memory.
stl = xstrdup(stl);
build_stl_str_hl(ewp, buf, sizeof(buf), stl, opt_idx, opt_scope,
fillchar, maxwidth, &hltab, &tabtab, NULL);
fillchar, maxwidth, &hltab, NULL, &tabtab, NULL);
xfree(stl);
ewp->w_p_crb = p_crb_save;
@ -880,7 +880,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, char *buf, st
StlClickRecord *clickrec;
char *stc = xstrdup(wp->w_p_stc);
int width = build_stl_str_hl(wp, buf, MAXPATHL, stc, kOptStatuscolumn, OPT_LOCAL, 0,
stcp->width, &stcp->hlrec, fillclick ? &clickrec : NULL, stcp);
stcp->width, &stcp->hlrec, NULL, fillclick ? &clickrec : NULL, stcp);
xfree(stc);
if (fillclick) {
@ -922,7 +922,7 @@ int build_statuscol_str(win_T *wp, linenr_T lnum, linenr_T relnum, char *buf, st
/// @return The final width of the statusline
int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex opt_idx,
int opt_scope, schar_T fillchar, int maxwidth, stl_hlrec_t **hltab,
StlClickRecord **tabtab, statuscol_T *stcp)
size_t *hltab_len, StlClickRecord **tabtab, statuscol_T *stcp)
{
static size_t stl_items_len = 20; // Initial value, grows as needed.
static stl_item_t *stl_items = NULL;
@ -2132,6 +2132,9 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
sp->start = NULL;
sp->userhl = 0;
}
if (hltab_len) {
*hltab_len = (size_t)itemcnt;
}
// Store the info about tab pages labels.
if (tabtab != NULL) {

View File

@ -43,6 +43,7 @@ describe('build_stl_str_hl', function()
maximum_cell_count,
NULL,
NULL,
NULL,
NULL
)
end