From 646fdf1073433e2bdeec3433f6cbdf8f4be37098 Mon Sep 17 00:00:00 2001 From: glepnir Date: Wed, 17 Jan 2024 20:14:26 +0800 Subject: [PATCH 1/2] refactor(api): use hl id directly in nvim_buf_set_extmark --- runtime/lua/vim/_meta/api_keysets.lua | 10 +++---- src/nvim/api/extmark.c | 38 ++++++------------------ src/nvim/api/keysets_defs.h | 10 +++---- src/nvim/api/private/defs.h | 1 + src/nvim/api/private/helpers.c | 21 ++++++++++--- src/nvim/generators/gen_api_dispatch.lua | 17 +++++++---- src/nvim/lua/converter.c | 10 ++++++- 7 files changed, 58 insertions(+), 49 deletions(-) diff --git a/runtime/lua/vim/_meta/api_keysets.lua b/runtime/lua/vim/_meta/api_keysets.lua index bb1031b2fa..377060256a 100644 --- a/runtime/lua/vim/_meta/api_keysets.lua +++ b/runtime/lua/vim/_meta/api_keysets.lua @@ -246,7 +246,7 @@ error('Cannot require a meta file') --- @field end_line? integer --- @field end_row? integer --- @field end_col? integer ---- @field hl_group? any +--- @field hl_group? integer --- @field virt_text? any[] --- @field virt_text_pos? string --- @field virt_text_win_col? integer @@ -264,10 +264,10 @@ error('Cannot require a meta file') --- @field virt_lines_leftcol? boolean --- @field strict? boolean --- @field sign_text? string ---- @field sign_hl_group? any ---- @field number_hl_group? any ---- @field line_hl_group? any ---- @field cursorline_hl_group? any +--- @field sign_hl_group? integer +--- @field number_hl_group? integer +--- @field line_hl_group? integer +--- @field cursorline_hl_group? integer --- @field conceal? string --- @field spell? boolean --- @field ui_watched? boolean diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c index fd07ec96fe..4e4befee1d 100644 --- a/src/nvim/api/extmark.c +++ b/src/nvim/api/extmark.c @@ -14,6 +14,7 @@ #include "nvim/buffer_defs.h" #include "nvim/charset.h" #include "nvim/decoration.h" +#include "nvim/decoration_defs.h" #include "nvim/decoration_provider.h" #include "nvim/drawscreen.h" #include "nvim/extmark.h" @@ -540,36 +541,15 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer col2 = (int)val; } - // uncrustify:off + hl.hl_id = (int)opts->hl_group; + has_hl = hl.hl_id > 0; + sign.hl_id = (int)opts->sign_hl_group; + sign.cursorline_hl_id = (int)opts->cursorline_hl_group; + sign.number_hl_id = (int)opts->number_hl_group; + sign.line_hl_id = (int)opts->line_hl_group; - // TODO(bfredl): keyset type alias for hl_group? (nil|int|string) - struct { - const char *name; - Object *opt; - int *dest; - } hls[] = { - { "hl_group" , &opts->hl_group , &hl.hl_id }, - { "sign_hl_group" , &opts->sign_hl_group , &sign.hl_id }, - { "number_hl_group" , &opts->number_hl_group , &sign.number_hl_id }, - { "line_hl_group" , &opts->line_hl_group , &sign.line_hl_id }, - { "cursorline_hl_group", &opts->cursorline_hl_group, &sign.cursorline_hl_id }, - { NULL, NULL, NULL }, - }; - - // uncrustify:on - - for (int j = 0; hls[j].name && hls[j].dest; j++) { - if (hls[j].opt->type != kObjectTypeNil) { - if (j > 0) { - sign.flags |= kSHIsSign; - } else { - has_hl = true; - } - *hls[j].dest = object_to_hl_id(*hls[j].opt, hls[j].name, err); - if (ERROR_SET(err)) { - goto error; - } - } + if (sign.hl_id || sign.cursorline_hl_id || sign.number_hl_id || sign.line_hl_id) { + sign.flags |= kSHIsSign; } if (HAS_KEY(opts, set_extmark, conceal)) { diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h index 897d546f3d..aad8ba3238 100644 --- a/src/nvim/api/keysets_defs.h +++ b/src/nvim/api/keysets_defs.h @@ -28,7 +28,7 @@ typedef struct { Integer end_line; Integer end_row; Integer end_col; - Object hl_group; + Integer hl_group; Array virt_text; String virt_text_pos; Integer virt_text_win_col; @@ -46,10 +46,10 @@ typedef struct { Boolean virt_lines_leftcol; Boolean strict; String sign_text; - Object sign_hl_group; - Object number_hl_group; - Object line_hl_group; - Object cursorline_hl_group; + Integer sign_hl_group; + Integer number_hl_group; + Integer line_hl_group; + Integer cursorline_hl_group; String conceal; Boolean spell; Boolean ui_watched; diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 25c8377518..84ded1e647 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -135,6 +135,7 @@ typedef struct { size_t ptr_off; ObjectType type; // kObjectTypeNil == untyped int opt_index; + bool is_hlgroup; } KeySetLink; typedef KeySetLink *(*FieldHashfn)(const char *str, size_t len); diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 677e1ce9fd..8f30ac7c8f 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -936,13 +936,26 @@ bool api_dict_to_keydict(void *retval, FieldHashfn hashy, Dictionary dict, Error char *mem = ((char *)retval + field->ptr_off); Object *value = &dict.items[i].value; + if (field->type == kObjectTypeNil) { *(Object *)mem = *value; } else if (field->type == kObjectTypeInteger) { - VALIDATE_T(field->str, kObjectTypeInteger, value->type, { - return false; - }); - *(Integer *)mem = value->data.integer; + if (field->is_hlgroup) { + int hl_id = 0; + if (value->type != kObjectTypeNil) { + hl_id = object_to_hl_id(*value, k.data, err); + if (ERROR_SET(err)) { + return false; + } + } + *(Integer *)mem = hl_id; + } else { + VALIDATE_T(field->str, kObjectTypeInteger, value->type, { + return false; + }); + + *(Integer *)mem = value->data.integer; + } } else if (field->type == kObjectTypeFloat) { Float *val = (Float *)mem; if (value->type == kObjectTypeInteger) { diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 791edfff96..3fb240d70b 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -72,6 +72,7 @@ local keysets = {} local function add_keyset(val) local keys = {} local types = {} + local hlgroups = {} local is_set_name = 'is_set__' .. val.keyset_name .. '_' local has_optional = false for i, field in ipairs(val.fields) do @@ -80,6 +81,7 @@ local function add_keyset(val) end if field.name ~= is_set_name and field.type ~= 'OptionalKeys' then table.insert(keys, field.name) + hlgroups[field.name] = field.name:find('hl_group') and true or false else if i > 1 then error("'is_set__{type}_' must be first if present") @@ -91,10 +93,13 @@ local function add_keyset(val) has_optional = true end end - table.insert( - keysets, - { name = val.keyset_name, keys = keys, types = types, has_optional = has_optional } - ) + table.insert(keysets, { + name = val.keyset_name, + keys = keys, + types = types, + hlgroups = hlgroups, + has_optional = has_optional, + }) end -- read each input file, parse and append to the api metadata @@ -305,10 +310,12 @@ for _, k in ipairs(keysets) do .. typename(k.types[key]) .. ', ' .. ind + .. ', ' + .. (k.hlgroups[key] and 'true' or 'false') .. '},\n' ) end - output:write(' {NULL, 0, kObjectTypeNil, -1},\n') + output:write(' {NULL, 0, kObjectTypeNil, -1, false},\n') output:write('};\n\n') output:write(hashfun) diff --git a/src/nvim/lua/converter.c b/src/nvim/lua/converter.c index 575dc2ce37..91f2db3ac9 100644 --- a/src/nvim/lua/converter.c +++ b/src/nvim/lua/converter.c @@ -17,6 +17,7 @@ #include "nvim/eval/typval_encode.h" #include "nvim/eval/userfunc.h" #include "nvim/gettext_defs.h" +#include "nvim/highlight_group.h" #include "nvim/lua/converter.h" #include "nvim/lua/executor.h" #include "nvim/macros_defs.h" @@ -1324,7 +1325,14 @@ void nlua_pop_keydict(lua_State *L, void *retval, FieldHashfn hashy, char **err_ if (field->type == kObjectTypeNil) { *(Object *)mem = nlua_pop_Object(L, true, err); } else if (field->type == kObjectTypeInteger) { - *(Integer *)mem = nlua_pop_Integer(L, err); + if (field->is_hlgroup && lua_type(L, -1) == LUA_TSTRING) { + size_t name_len; + const char *name = lua_tolstring(L, -1, &name_len); + lua_pop(L, 1); + *(Integer *)mem = name_len > 0 ? syn_check_group(name, name_len) : 0; + } else { + *(Integer *)mem = nlua_pop_Integer(L, err); + } } else if (field->type == kObjectTypeBoolean) { *(Boolean *)mem = nlua_pop_Boolean_strict(L, err); } else if (field->type == kObjectTypeString) { From d66ed4ea468d411668713c3777ad3658f18badf3 Mon Sep 17 00:00:00 2001 From: bfredl Date: Mon, 22 Jan 2024 08:49:45 +0100 Subject: [PATCH 2/2] refactor(api): give "hl_group" more accurate _meta type These can either be number or string in lua, so we can specify this directly as "number|string". --- runtime/lua/vim/_meta/api_keysets.lua | 10 +++++----- scripts/gen_eval_files.lua | 1 + src/nvim/api/keysets_defs.h | 10 +++++----- src/nvim/api/private/defs.h | 1 + src/nvim/generators/gen_api_dispatch.lua | 9 ++++----- 5 files changed, 16 insertions(+), 15 deletions(-) diff --git a/runtime/lua/vim/_meta/api_keysets.lua b/runtime/lua/vim/_meta/api_keysets.lua index 377060256a..5ebedc977b 100644 --- a/runtime/lua/vim/_meta/api_keysets.lua +++ b/runtime/lua/vim/_meta/api_keysets.lua @@ -246,7 +246,7 @@ error('Cannot require a meta file') --- @field end_line? integer --- @field end_row? integer --- @field end_col? integer ---- @field hl_group? integer +--- @field hl_group? number|string --- @field virt_text? any[] --- @field virt_text_pos? string --- @field virt_text_win_col? integer @@ -264,10 +264,10 @@ error('Cannot require a meta file') --- @field virt_lines_leftcol? boolean --- @field strict? boolean --- @field sign_text? string ---- @field sign_hl_group? integer ---- @field number_hl_group? integer ---- @field line_hl_group? integer ---- @field cursorline_hl_group? integer +--- @field sign_hl_group? number|string +--- @field number_hl_group? number|string +--- @field line_hl_group? number|string +--- @field cursorline_hl_group? number|string --- @field conceal? string --- @field spell? boolean --- @field ui_watched? boolean diff --git a/scripts/gen_eval_files.lua b/scripts/gen_eval_files.lua index c49f598304..499c7dc9a7 100755 --- a/scripts/gen_eval_files.lua +++ b/scripts/gen_eval_files.lua @@ -88,6 +88,7 @@ local API_TYPES = { LuaRef = 'function', Dictionary = 'table', Float = 'number', + HLGroupID = 'number|string', void = '', } diff --git a/src/nvim/api/keysets_defs.h b/src/nvim/api/keysets_defs.h index aad8ba3238..b2f0039eb9 100644 --- a/src/nvim/api/keysets_defs.h +++ b/src/nvim/api/keysets_defs.h @@ -28,7 +28,7 @@ typedef struct { Integer end_line; Integer end_row; Integer end_col; - Integer hl_group; + HLGroupID hl_group; Array virt_text; String virt_text_pos; Integer virt_text_win_col; @@ -46,10 +46,10 @@ typedef struct { Boolean virt_lines_leftcol; Boolean strict; String sign_text; - Integer sign_hl_group; - Integer number_hl_group; - Integer line_hl_group; - Integer cursorline_hl_group; + HLGroupID sign_hl_group; + HLGroupID number_hl_group; + HLGroupID line_hl_group; + HLGroupID cursorline_hl_group; String conceal; Boolean spell; Boolean ui_watched; diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 84ded1e647..0cdc90e50f 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -124,6 +124,7 @@ struct key_value_pair { }; typedef uint64_t OptionalKeys; +typedef Integer HLGroupID; // this is the prefix of all keysets with optional keys typedef struct { diff --git a/src/nvim/generators/gen_api_dispatch.lua b/src/nvim/generators/gen_api_dispatch.lua index 3fb240d70b..2eee1724c0 100644 --- a/src/nvim/generators/gen_api_dispatch.lua +++ b/src/nvim/generators/gen_api_dispatch.lua @@ -72,7 +72,6 @@ local keysets = {} local function add_keyset(val) local keys = {} local types = {} - local hlgroups = {} local is_set_name = 'is_set__' .. val.keyset_name .. '_' local has_optional = false for i, field in ipairs(val.fields) do @@ -81,7 +80,6 @@ local function add_keyset(val) end if field.name ~= is_set_name and field.type ~= 'OptionalKeys' then table.insert(keys, field.name) - hlgroups[field.name] = field.name:find('hl_group') and true or false else if i > 1 then error("'is_set__{type}_' must be first if present") @@ -97,7 +95,6 @@ local function add_keyset(val) name = val.keyset_name, keys = keys, types = types, - hlgroups = hlgroups, has_optional = has_optional, }) end @@ -285,7 +282,9 @@ for _, k in ipairs(keysets) do keysets_defs:write('extern KeySetLink ' .. k.name .. '_table[];\n') local function typename(type) - if type ~= nil then + if type == 'HLGroupID' then + return 'kObjectTypeInteger' + elseif type ~= nil then return 'kObjectType' .. type else return 'kObjectTypeNil' @@ -311,7 +310,7 @@ for _, k in ipairs(keysets) do .. ', ' .. ind .. ', ' - .. (k.hlgroups[key] and 'true' or 'false') + .. (k.types[key] == 'HLGroupID' and 'true' or 'false') .. '},\n' ) end