mirror of
https://github.com/neovim/neovim.git
synced 2025-10-05 17:36:29 +00:00
refactor(vim.opt): replace _setup with lazy table
This commit is contained in:
@@ -4,39 +4,52 @@ local vim = assert(vim)
|
|||||||
local a = vim.api
|
local a = vim.api
|
||||||
local validate = vim.validate
|
local validate = vim.validate
|
||||||
|
|
||||||
local options_info = nil
|
-- TODO(tjdevries): Improve option metadata so that this doesn't have to be hardcoded.
|
||||||
local buf_options = nil
|
-- Can be done in a separate PR.
|
||||||
local glb_options = nil
|
local key_value_options = {
|
||||||
local win_options = nil
|
fillchars = true,
|
||||||
|
fcs = true,
|
||||||
|
listchars = true,
|
||||||
|
lcs = true,
|
||||||
|
winhighlight = true,
|
||||||
|
winhl = true,
|
||||||
|
}
|
||||||
|
|
||||||
local function _setup()
|
--- Convert a vimoption_T style dictionary to the correct OptionType associated with it.
|
||||||
if options_info ~= nil then
|
---@return string
|
||||||
return
|
local function get_option_metatype(name, info)
|
||||||
end
|
if info.type == 'boolean' then
|
||||||
options_info = {}
|
return 'boolean'
|
||||||
for _, v in pairs(a.nvim_get_all_options_info()) do
|
elseif info.type == 'number' then
|
||||||
options_info[v.name] = v
|
return 'number'
|
||||||
if v.shortname ~= '' then
|
elseif info.type == 'string' then
|
||||||
options_info[v.shortname] = v
|
if not info.commalist and not info.flaglist then
|
||||||
end
|
return 'string'
|
||||||
end
|
|
||||||
|
|
||||||
local function get_scoped_options(scope)
|
|
||||||
local result = {}
|
|
||||||
for name, option_info in pairs(options_info) do
|
|
||||||
if option_info.scope == scope then
|
|
||||||
result[name] = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
return result
|
if key_value_options[name] then
|
||||||
end
|
assert(info.commalist, 'Must be a comma list to use key:value style')
|
||||||
|
return 'map'
|
||||||
|
end
|
||||||
|
|
||||||
buf_options = get_scoped_options('buf')
|
if info.flaglist then
|
||||||
glb_options = get_scoped_options('global')
|
return 'set'
|
||||||
win_options = get_scoped_options('win')
|
elseif info.commalist then
|
||||||
|
return 'array'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
error('Not a known info.type:' .. info.type)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local options_info = setmetatable({}, {
|
||||||
|
__index = function(t, k)
|
||||||
|
local info = a.nvim_get_option_info(k)
|
||||||
|
info.metatype = get_option_metatype(k, info)
|
||||||
|
rawset(t, k, info)
|
||||||
|
return rawget(t, k)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
||||||
local function make_meta_accessor(get, set, validator)
|
local function make_meta_accessor(get, set, validator)
|
||||||
validator = validator or function()
|
validator = validator or function()
|
||||||
return true
|
return true
|
||||||
@@ -90,12 +103,12 @@ do -- buffer option accessor
|
|||||||
|
|
||||||
return make_meta_accessor(get, set, function(k)
|
return make_meta_accessor(get, set, function(k)
|
||||||
if type(k) == 'string' then
|
if type(k) == 'string' then
|
||||||
_setup()
|
local scope = options_info[k].scope
|
||||||
if win_options[k] then
|
if scope == 'win' then
|
||||||
error(
|
error(
|
||||||
string.format([['%s' is a window option, not a buffer option. See ":help %s"]], k, k)
|
string.format([['%s' is a window option, not a buffer option. See ":help %s"]], k, k)
|
||||||
)
|
)
|
||||||
elseif glb_options[k] then
|
elseif scope == 'global' then
|
||||||
error(
|
error(
|
||||||
string.format([['%s' is a global option, not a buffer option. See ":help %s"]], k, k)
|
string.format([['%s' is a global option, not a buffer option. See ":help %s"]], k, k)
|
||||||
)
|
)
|
||||||
@@ -124,12 +137,12 @@ do -- window option accessor
|
|||||||
|
|
||||||
return make_meta_accessor(get, set, function(k)
|
return make_meta_accessor(get, set, function(k)
|
||||||
if type(k) == 'string' then
|
if type(k) == 'string' then
|
||||||
_setup()
|
local scope = options_info[k].scope
|
||||||
if buf_options[k] then
|
if scope == 'buf' then
|
||||||
error(
|
error(
|
||||||
string.format([['%s' is a buffer option, not a window option. See ":help %s"]], k, k)
|
string.format([['%s' is a buffer option, not a window option. See ":help %s"]], k, k)
|
||||||
)
|
)
|
||||||
elseif glb_options[k] then
|
elseif scope == 'global' then
|
||||||
error(
|
error(
|
||||||
string.format([['%s' is a global option, not a window option. See ":help %s"]], k, k)
|
string.format([['%s' is a global option, not a window option. See ":help %s"]], k, k)
|
||||||
)
|
)
|
||||||
@@ -184,43 +197,6 @@ local remove_duplicate_values = function(t)
|
|||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
-- TODO(tjdevries): Improve option metadata so that this doesn't have to be hardcoded.
|
|
||||||
-- Can be done in a separate PR.
|
|
||||||
local key_value_options = {
|
|
||||||
fillchars = true,
|
|
||||||
fcs = true,
|
|
||||||
listchars = true,
|
|
||||||
lcs = true,
|
|
||||||
winhighlight = true,
|
|
||||||
winhl = true,
|
|
||||||
}
|
|
||||||
|
|
||||||
--- Convert a vimoption_T style dictionary to the correct OptionType associated with it.
|
|
||||||
---@return string
|
|
||||||
local get_option_type = function(name, info)
|
|
||||||
if info.type == 'boolean' then
|
|
||||||
return 'boolean'
|
|
||||||
elseif info.type == 'number' then
|
|
||||||
return 'number'
|
|
||||||
elseif info.type == 'string' then
|
|
||||||
if not info.commalist and not info.flaglist then
|
|
||||||
return 'string'
|
|
||||||
end
|
|
||||||
|
|
||||||
if key_value_options[name] then
|
|
||||||
assert(info.commalist, 'Must be a comma list to use key:value style')
|
|
||||||
return 'map'
|
|
||||||
end
|
|
||||||
|
|
||||||
if info.flaglist then
|
|
||||||
return 'set'
|
|
||||||
elseif info.commalist then
|
|
||||||
return 'array'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
error('Not a known info.type:' .. info.type)
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check whether the OptionTypes is allowed for vim.opt
|
-- Check whether the OptionTypes is allowed for vim.opt
|
||||||
-- If it does not match, throw an error which indicates which option causes the error.
|
-- If it does not match, throw an error which indicates which option causes the error.
|
||||||
local function assert_valid_value(name, value, types)
|
local function assert_valid_value(name, value, types)
|
||||||
@@ -322,10 +298,9 @@ local convert_value_to_vim = (function()
|
|||||||
return vim.NIL
|
return vim.NIL
|
||||||
end
|
end
|
||||||
|
|
||||||
local option_type = get_option_type(name, info)
|
assert_valid_value(name, value, valid_types[info.metatype])
|
||||||
assert_valid_value(name, value, valid_types[option_type])
|
|
||||||
|
|
||||||
return to_vim_value[option_type](info, value)
|
return to_vim_value[info.metatype](info, value)
|
||||||
end
|
end
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
@@ -445,14 +420,14 @@ local convert_value_to_lua = (function()
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(name, info, option_value)
|
return function(info, option_value)
|
||||||
return to_lua_value[get_option_type(name, info)](info, option_value)
|
return to_lua_value[info.metatype](info, option_value)
|
||||||
end
|
end
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
--- Handles the mutation of various different values.
|
--- Handles the mutation of various different values.
|
||||||
local value_mutator = function(name, info, current, new, mutator)
|
local value_mutator = function(info, current, new, mutator)
|
||||||
return mutator[get_option_type(name, info)](current, new)
|
return mutator[info.metatype](current, new)
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Handles the '^' operator
|
--- Handles the '^' operator
|
||||||
@@ -483,12 +458,11 @@ local prepend_value = (function()
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(name, info, current, new)
|
return function(info, current, new)
|
||||||
return value_mutator(
|
return value_mutator(
|
||||||
name,
|
|
||||||
info,
|
info,
|
||||||
convert_value_to_lua(name, info, current),
|
convert_value_to_lua(info, current),
|
||||||
convert_value_to_lua(name, info, new),
|
convert_value_to_lua(info, new),
|
||||||
methods
|
methods
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -522,12 +496,11 @@ local add_value = (function()
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(name, info, current, new)
|
return function(info, current, new)
|
||||||
return value_mutator(
|
return value_mutator(
|
||||||
name,
|
|
||||||
info,
|
info,
|
||||||
convert_value_to_lua(name, info, current),
|
convert_value_to_lua(info, current),
|
||||||
convert_value_to_lua(name, info, new),
|
convert_value_to_lua(info, new),
|
||||||
methods
|
methods
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
@@ -598,8 +571,8 @@ local remove_value = (function()
|
|||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(name, info, current, new)
|
return function(info, current, new)
|
||||||
return value_mutator(name, info, convert_value_to_lua(name, info, current), new, methods)
|
return value_mutator(info, convert_value_to_lua(info, current), new, methods)
|
||||||
end
|
end
|
||||||
end)()
|
end)()
|
||||||
|
|
||||||
@@ -607,7 +580,6 @@ local create_option_metatable = function(scope)
|
|||||||
local set_mt, option_mt
|
local set_mt, option_mt
|
||||||
|
|
||||||
local make_option = function(name, value)
|
local make_option = function(name, value)
|
||||||
_setup()
|
|
||||||
local info = assert(options_info[name], 'Not a valid option name: ' .. name)
|
local info = assert(options_info[name], 'Not a valid option name: ' .. name)
|
||||||
|
|
||||||
if type(value) == 'table' and getmetatable(value) == option_mt then
|
if type(value) == 'table' and getmetatable(value) == option_mt then
|
||||||
@@ -634,7 +606,7 @@ local create_option_metatable = function(scope)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
get = function(self)
|
get = function(self)
|
||||||
return convert_value_to_lua(self._name, self._info, self._value)
|
return convert_value_to_lua(self._info, self._value)
|
||||||
end,
|
end,
|
||||||
|
|
||||||
append = function(self, right)
|
append = function(self, right)
|
||||||
@@ -642,7 +614,7 @@ local create_option_metatable = function(scope)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
__add = function(self, right)
|
__add = function(self, right)
|
||||||
return make_option(self._name, add_value(self._name, self._info, self._value, right))
|
return make_option(self._name, add_value(self._info, self._value, right))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
prepend = function(self, right)
|
prepend = function(self, right)
|
||||||
@@ -650,7 +622,7 @@ local create_option_metatable = function(scope)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
__pow = function(self, right)
|
__pow = function(self, right)
|
||||||
return make_option(self._name, prepend_value(self._name, self._info, self._value, right))
|
return make_option(self._name, prepend_value(self._info, self._value, right))
|
||||||
end,
|
end,
|
||||||
|
|
||||||
remove = function(self, right)
|
remove = function(self, right)
|
||||||
@@ -658,7 +630,7 @@ local create_option_metatable = function(scope)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
__sub = function(self, right)
|
__sub = function(self, right)
|
||||||
return make_option(self._name, remove_value(self._name, self._info, self._value, right))
|
return make_option(self._name, remove_value(self._info, self._value, right))
|
||||||
end,
|
end,
|
||||||
}
|
}
|
||||||
option_mt.__index = option_mt
|
option_mt.__index = option_mt
|
||||||
|
Reference in New Issue
Block a user