diff options
author | Famiu Haque <famiuhaque@proton.me> | 2024-11-17 02:56:16 +0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-16 12:56:16 -0800 |
commit | 29ded889579a9d590e8ea885a9a402ff4bae87be (patch) | |
tree | 476bc3746cfac48f141e5ab0aaf562480502fad2 /src/nvim/generators/gen_options_enum.lua | |
parent | be8648f345aed5e403251990721918c8302be760 (diff) | |
download | rneovim-29ded889579a9d590e8ea885a9a402ff4bae87be.tar.gz rneovim-29ded889579a9d590e8ea885a9a402ff4bae87be.tar.bz2 rneovim-29ded889579a9d590e8ea885a9a402ff4bae87be.zip |
refactor(options): remove `.indir`, redesign option scopes #31066
Problem:
The way option scopes currently work is inflexible and does not allow for nested
option scopes or easily finding the value of an option at any arbitrary scope
without having to do long handwritten switch-case statements like in
`get_varp()`. `.indir` is also confusing and redundant since option indices for
each scope can be autogenerated.
Solution:
Expand option scopes in such a way that an option can support any amount of
scopes using a set of scope flags, similarly to how it's already done for option
types. Also make options contain information about its index at each scope it
supports. This allows for massively simplifying `get_varp()` and
`get_varp_scope()` in the future by just using a struct for options at each
scope. This would be done by creating a table that stores the offset of an
option's variable at a scope by using the option's index at that scope as a key.
This PR also autogenerates enums for option indices at each scope to remove the
need for `.indir` entirely, and also to allow easily iterating over options all
options that support any scope.
Ref: #29314
Diffstat (limited to 'src/nvim/generators/gen_options_enum.lua')
-rw-r--r-- | src/nvim/generators/gen_options_enum.lua | 129 |
1 files changed, 0 insertions, 129 deletions
diff --git a/src/nvim/generators/gen_options_enum.lua b/src/nvim/generators/gen_options_enum.lua deleted file mode 100644 index d1419137d3..0000000000 --- a/src/nvim/generators/gen_options_enum.lua +++ /dev/null @@ -1,129 +0,0 @@ --- Generates option index enum and map of option name to option index. --- Handles option full name, short name and aliases. --- Also generates BV_ and WV_ enum constants. - -local options_enum_file = arg[1] -local options_map_file = arg[2] -local options_enum_fd = assert(io.open(options_enum_file, 'w')) -local options_map_fd = assert(io.open(options_map_file, 'w')) - ---- @param s string -local function enum_w(s) - options_enum_fd:write(s .. '\n') -end - ---- @param s string -local function map_w(s) - options_map_fd:write(s .. '\n') -end - -enum_w('// IWYU pragma: private, include "nvim/option_defs.h"') -enum_w('') - ---- @param s string ---- @return string -local lowercase_to_titlecase = function(s) - return s:sub(1, 1):upper() .. s:sub(2) -end - ---- @type vim.option_meta[] -local options = require('options').options - --- Generate BV_ enum constants. -enum_w('/// "indir" values for buffer-local options.') -enum_w('/// These need to be defined globally, so that the BV_COUNT can be used with') -enum_w('/// b_p_script_stx[].') -enum_w('enum {') - -local bv_val = 0 - -for _, o in ipairs(options) do - assert(#o.scope == 1 or #o.scope == 2) - assert(#o.scope == 1 or o.scope[1] == 'global') - local min_scope = o.scope[#o.scope] - if min_scope == 'buffer' then - local varname = o.pv_name or o.varname or ('p_' .. (o.abbreviation or o.full_name)) - local bv_name = 'BV_' .. varname:sub(3):upper() - enum_w((' %s = %u,'):format(bv_name, bv_val)) - bv_val = bv_val + 1 - end -end - -enum_w((' BV_COUNT = %u, ///< must be the last one'):format(bv_val)) -enum_w('};') -enum_w('') - --- Generate WV_ enum constants. -enum_w('/// "indir" values for window-local options.') -enum_w('/// These need to be defined globally, so that the WV_COUNT can be used in the') -enum_w('/// window structure.') -enum_w('enum {') - -local wv_val = 0 - -for _, o in ipairs(options) do - assert(#o.scope == 1 or #o.scope == 2) - assert(#o.scope == 1 or o.scope[1] == 'global') - local min_scope = o.scope[#o.scope] - if min_scope == 'window' then - local varname = o.pv_name or o.varname or ('p_' .. (o.abbreviation or o.full_name)) - local wv_name = 'WV_' .. varname:sub(3):upper() - enum_w((' %s = %u,'):format(wv_name, wv_val)) - wv_val = wv_val + 1 - end -end - -enum_w((' WV_COUNT = %u, ///< must be the last one'):format(wv_val)) -enum_w('};') -enum_w('') - ---- @type { [string]: string } -local option_index = {} - --- Generate option index enum and populate the `option_index` dict. -enum_w('typedef enum {') -enum_w(' kOptInvalid = -1,') - -for i, o in ipairs(options) do - local enum_val_name = 'kOpt' .. lowercase_to_titlecase(o.full_name) - enum_w((' %s = %u,'):format(enum_val_name, i - 1)) - - option_index[o.full_name] = enum_val_name - - if o.abbreviation then - option_index[o.abbreviation] = enum_val_name - end - - if o.alias then - o.alias = type(o.alias) == 'string' and { o.alias } or o.alias - - for _, v in ipairs(o.alias) do - option_index[v] = enum_val_name - end - end -end - -enum_w(' // Option count, used when iterating through options') -enum_w('#define kOptIndexCount ' .. tostring(#options)) -enum_w('} OptIndex;') -enum_w('') - -options_enum_fd:close() - ---- Generate option index map. -local hashy = require('generators.hashy') -local neworder, hashfun = hashy.hashy_hash('find_option', vim.tbl_keys(option_index), function(idx) - return ('option_hash_elems[%s].name'):format(idx) -end) - -map_w('static const struct { const char *name; OptIndex opt_idx; } option_hash_elems[] = {') - -for _, name in ipairs(neworder) do - assert(option_index[name] ~= nil) - map_w((' { .name = "%s", .opt_idx = %s },'):format(name, option_index[name])) -end - -map_w('};\n') -map_w('static ' .. hashfun) - -options_map_fd:close() |