264 lines
5.4 KiB
Lua
264 lines
5.4 KiB
Lua
--[[ To use a more declarative syntax, you could do something like this:
|
|
|
|
local function set_opts(opts_table)
|
|
for k, v in pairs(opts_table) do
|
|
vim.opt[k] = v
|
|
end
|
|
end
|
|
|
|
set_opts {
|
|
mouse = 'n',
|
|
fillchars = { eob = "~" },
|
|
}
|
|
|
|
--]]
|
|
|
|
--[[ Global option names
|
|
|
|
For those wondering how to get the values at the top level,
|
|
you could use Lua's `setfenv` function to set the environment
|
|
equal to the vim.opt dict
|
|
|
|
cc @mccanch
|
|
|
|
setfenv(function()
|
|
mouse = 'n'
|
|
end, vim.opt)()
|
|
|
|
--]]
|
|
|
|
local if_nil = function(a, b)
|
|
if a == nil then
|
|
return b
|
|
end
|
|
return a
|
|
end
|
|
|
|
local singular_values = {
|
|
['boolean'] = true,
|
|
['number'] = true,
|
|
['nil'] = true,
|
|
}
|
|
|
|
local set_key_value = function(t, key_value_str)
|
|
assert(string.find(key_value_str, ":"), "Must have a :" .. tostring(key_value_str))
|
|
|
|
local key, value = unpack(vim.split(key_value_str, ":"))
|
|
key = vim.trim(key)
|
|
value = vim.trim(value)
|
|
|
|
t[key] = value
|
|
end
|
|
|
|
local convert_vimoption_to_lua = function(option, val)
|
|
-- Short circuit if we've already converted!
|
|
if type(val) == 'table' then
|
|
return val
|
|
end
|
|
|
|
if singular_values[type(val)] then
|
|
return val
|
|
end
|
|
|
|
if type(val) == "string" then
|
|
-- TODO: Bad hax I think
|
|
if string.find(val, ":") then
|
|
local result = {}
|
|
local items = vim.split(val, ",")
|
|
for _, item in ipairs(items) do
|
|
set_key_value(result, item)
|
|
end
|
|
|
|
return result
|
|
else
|
|
return vim.split(val, ",")
|
|
end
|
|
end
|
|
end
|
|
|
|
-- local concat_keys = function(t, sep)
|
|
-- return table.concat(vim.tbl_keys(t), sep)
|
|
-- end
|
|
|
|
local concat_key_values = function(t, sep, divider)
|
|
local final = {}
|
|
for k, v in pairs(t) do
|
|
table.insert(final, string.format('%s%s%s', k, divider, v))
|
|
end
|
|
|
|
table.sort(final)
|
|
return table.concat(final, sep)
|
|
end
|
|
|
|
local remove_duplicate_values = function(t)
|
|
local result = {}
|
|
for _, v in ipairs(t) do
|
|
result[v] = true
|
|
end
|
|
|
|
return vim.tbl_keys(result)
|
|
end
|
|
|
|
local remove_value = function(t, val)
|
|
if vim.tbl_islist(t) then
|
|
local remove_index = nil
|
|
for i, v in ipairs(t) do
|
|
if v == val then
|
|
remove_index = i
|
|
end
|
|
end
|
|
|
|
if remove_index then
|
|
table.remove(t, remove_index)
|
|
end
|
|
else
|
|
t[val] = nil
|
|
end
|
|
|
|
return t
|
|
end
|
|
|
|
local add_value = function(current, new)
|
|
if singular_values[type(current)] then
|
|
error(
|
|
"This is not possible to do. Please do something different: "
|
|
.. tostring(current)
|
|
.. " // "
|
|
.. tostring(new)
|
|
)
|
|
end
|
|
|
|
if type(new) == 'string' then
|
|
if vim.tbl_islist(current) then
|
|
table.insert(current, new)
|
|
else
|
|
set_key_value(current, new)
|
|
end
|
|
|
|
return current
|
|
elseif type(new) == 'table' then
|
|
if vim.tbl_islist(current) then
|
|
assert(vim.tbl_islist(new))
|
|
vim.list_extend(current, new)
|
|
else
|
|
assert(not vim.tbl_islist(new), vim.inspect(new) .. vim.inspect(current))
|
|
current = vim.tbl_extend("force", current, new)
|
|
end
|
|
|
|
return current
|
|
else
|
|
error("Unknown type")
|
|
end
|
|
end
|
|
|
|
local convert_lua_to_vimoption = function(t)
|
|
if vim.tbl_islist(t) then
|
|
t = remove_duplicate_values(t)
|
|
|
|
table.sort(t)
|
|
return table.concat(t, ',')
|
|
else
|
|
return concat_key_values(t, ',', ':')
|
|
end
|
|
end
|
|
|
|
local clean_value = function(v)
|
|
if singular_values[type(v)] then
|
|
return v
|
|
end
|
|
|
|
local result = v:gsub('^,', '')
|
|
|
|
return result
|
|
end
|
|
|
|
local opt_mt
|
|
|
|
opt_mt = {
|
|
__index = function(t, k)
|
|
if k == '_value' then
|
|
return rawget(t, k)
|
|
end
|
|
|
|
return setmetatable({ _option = k, }, opt_mt)
|
|
end,
|
|
|
|
__newindex = function(t, k, v)
|
|
if k == '_value' then
|
|
return rawset(t, k, v)
|
|
end
|
|
|
|
if type(v) == 'table' then
|
|
local new_value
|
|
if getmetatable(v) ~= opt_mt then
|
|
new_value = v
|
|
else
|
|
assert(v._value, "Must have a value to set this")
|
|
new_value = v._value
|
|
end
|
|
|
|
vim.o[k] = convert_lua_to_vimoption(new_value)
|
|
return
|
|
end
|
|
|
|
if v == nil then
|
|
v = ''
|
|
end
|
|
|
|
-- TODO: Figure out why nvim_set_option doesn't override values the same way.
|
|
-- @bfredl said he will fix this for me, so I can just use nvim_set_option
|
|
if type(v) == 'boolean' then
|
|
vim.o[k] = clean_value(v)
|
|
if v then
|
|
vim.cmd(string.format("set %s", k))
|
|
else
|
|
vim.cmd(string.format("set no%s", k))
|
|
end
|
|
else
|
|
vim.cmd(string.format("set %s=%s", k, clean_value(v)))
|
|
end
|
|
end,
|
|
|
|
__add = function(left, right)
|
|
--[[
|
|
set.wildignore = set.wildignore + 'hello'
|
|
set.wildignore = set.wildignore + { '*.o', '*~', }
|
|
--]]
|
|
|
|
assert(left._option, "must have an option key")
|
|
if left._option == 'foldcolumn' then
|
|
error("not implemented for foldcolumn.. use a string")
|
|
end
|
|
|
|
local existing = if_nil(left._value, vim.o[left._option])
|
|
local current = convert_vimoption_to_lua(left._option, existing)
|
|
if not current then
|
|
left._value = convert_vimoption_to_lua(right)
|
|
end
|
|
|
|
left._value = add_value(current, right)
|
|
return left
|
|
end,
|
|
|
|
__sub = function(left, right)
|
|
assert(left._option, "must have an option key")
|
|
|
|
local existing = if_nil(left._value, vim.o[left._option])
|
|
local current = convert_vimoption_to_lua(left._option, existing)
|
|
if not current then
|
|
return left
|
|
end
|
|
|
|
left._value = remove_value(current, right)
|
|
return left
|
|
end
|
|
}
|
|
|
|
vim.opt = setmetatable({}, opt_mt)
|
|
|
|
return {
|
|
convert_vimoption_to_lua = convert_vimoption_to_lua,
|
|
opt = vim.opt,
|
|
opt_mt = opt_mt
|
|
}
|