diff options
author | Famiu Haque <famiuhaque@proton.me> | 2023-12-17 05:23:33 +0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-17 07:23:33 +0800 |
commit | 8f08b1efbd096850c04c2e8e2890d993bd4d9f95 (patch) | |
tree | 2fa91d7a39c1c82e9b6d0c578d74f17bb80b1827 /src/nvim/generators | |
parent | 2b1bc94b768cb13801e7166f6b02bd09caa3c18f (diff) | |
download | rneovim-8f08b1efbd096850c04c2e8e2890d993bd4d9f95.tar.gz rneovim-8f08b1efbd096850c04c2e8e2890d993bd4d9f95.tar.bz2 rneovim-8f08b1efbd096850c04c2e8e2890d993bd4d9f95.zip |
refactor(options): use hashy for finding options (#26573)
Problem:
`findoption()` searches through the options[] table linearly for option
names, even though hashy can be used to generate a compile-time hash
table for it.
Solution:
Use hashy to generate a compile time hash table for finding options.
This also allows handling option aliases, so we don't need separate
options[] table entries for things like 'viminfo'.
Diffstat (limited to 'src/nvim/generators')
-rw-r--r-- | src/nvim/generators/gen_options.lua | 19 | ||||
-rw-r--r-- | src/nvim/generators/gen_options_enum.lua | 76 |
2 files changed, 77 insertions, 18 deletions
diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 61d5df3c84..2fd11e4c58 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -1,5 +1,4 @@ local options_file = arg[1] -local options_enum_file = arg[2] local opt_fd = assert(io.open(options_file, 'w')) @@ -171,7 +170,7 @@ local function dump_option(i, o) end if o.varname then w(' .var=&' .. o.varname) - -- Immutable options should directly point to the default value + -- Immutable options can directly point to the default value. elseif o.immutable then w((' .var=&options[%u].def_val'):format(i - 1)) elseif #o.scope == 1 and o.scope[1] == 'window' then @@ -248,19 +247,3 @@ w('') for _, v in ipairs(defines) do w('#define ' .. v[1] .. ' ' .. v[2]) end - --- Generate options enum file -opt_fd = assert(io.open(options_enum_file, 'w')) - -w('typedef enum {') -w(' kOptInvalid = -1,') - -for i, o in ipairs(options.options) do - w((' kOpt%s = %u,'):format(lowercase_to_titlecase(o.full_name), i - 1)) -end - -w(' // Option count, used when iterating through options') -w('#define kOptIndexCount ' .. tostring(#options.options)) -w('} OptIndex;') - -opt_fd:close() diff --git a/src/nvim/generators/gen_options_enum.lua b/src/nvim/generators/gen_options_enum.lua new file mode 100644 index 0000000000..c3fe9baae6 --- /dev/null +++ b/src/nvim/generators/gen_options_enum.lua @@ -0,0 +1,76 @@ +-- Generates option index enum and map of option name to option index. +-- Handles option full name, short name and aliases. + +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 + +--- @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 +--- @type { [string]: string } +local option_index = {} + +-- Generate option index enum and populate the `option_index` dictionary. +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() |