feat(api): add nvim_get_option_value

This commit is contained in:
Gregory Anders
2021-10-11 22:09:08 -06:00
parent 7b910a1716
commit 71ac00ccb5
9 changed files with 193 additions and 121 deletions

View File

@@ -133,107 +133,18 @@ do -- window option accessor
vim.wo = new_win_opt_accessor(nil)
end
--[[
Local window setter
buffer options: does not get copied when split
nvim_set_option(buf_opt, value) -> sets the default for NEW buffers
this sets the hidden global default for buffer options
nvim_buf_set_option(...) -> sets the local value for the buffer
set opt=value, does BOTH global default AND buffer local value
setlocal opt=value, does ONLY buffer local value
window options: gets copied
does not need to call nvim_set_option because nobody knows what the heck this does⸮
We call it anyway for more readable code.
Command global value local value
:set option=value set set
:setlocal option=value - set
:setglobal option=value set -
--]]
local function set_scoped_option(k, v, set_type)
local info = options_info[k]
-- Don't let people do setlocal with global options.
-- That is a feature that doesn't make sense.
if set_type == SET_TYPES.LOCAL and is_global_option(info) then
error(string.format("Unable to setlocal option: '%s', which is a global option.", k))
end
-- Only `setlocal` skips setting the default/global value
-- This will more-or-less noop for window options, but that's OK
if set_type ~= SET_TYPES.LOCAL then
a.nvim_set_option(k, v)
end
if is_window_option(info) then
if set_type ~= SET_TYPES.GLOBAL then
a.nvim_win_set_option(0, k, v)
end
elseif is_buffer_option(info) then
if set_type == SET_TYPES.LOCAL
or (set_type == SET_TYPES.SET and not info.global_local) then
a.nvim_buf_set_option(0, k, v)
end
end
end
--[[
Local window getter
Command global value local value
:set option? - display
:setlocal option? - display
:setglobal option? display -
--]]
local function get_scoped_option(k, set_type)
local info = assert(options_info[k], "Must be a valid option: " .. tostring(k))
if set_type == SET_TYPES.GLOBAL or is_global_option(info) then
return a.nvim_get_option(k)
end
if is_buffer_option(info) then
local was_set, value = pcall(a.nvim_buf_get_option, 0, k)
if was_set then return value end
if info.global_local then
return a.nvim_get_option(k)
end
error("buf_get: This should not be able to happen, given my understanding of options // " .. k)
end
if is_window_option(info) then
local ok, value = pcall(a.nvim_win_get_option, 0, k)
if ok then
return value
end
local global_ok, global_val = pcall(a.nvim_get_option, k)
if global_ok then
return global_val
end
error("win_get: This should never happen. File an issue and tag @tjdevries")
end
error("This fallback case should not be possible. " .. k)
end
-- vim global option
-- this ONLY sets the global option. like `setglobal`
vim.go = make_meta_accessor(a.nvim_get_option, a.nvim_set_option)
vim.go = make_meta_accessor(
function(k) return a.nvim_get_option_value(k, {scope = "global"}) end,
function(k, v) return a.nvim_set_option_value(k, v, {scope = "global"}) end
)
-- vim `set` style options.
-- it has no additional metamethod magic.
vim.o = make_meta_accessor(
function(k) return get_scoped_option(k, SET_TYPES.SET) end,
function(k, v) return set_scoped_option(k, v, SET_TYPES.SET) end
function(k) return a.nvim_get_option_value(k, {}) end,
function(k, v) return a.nvim_set_option_value(k, v, {}) end
)
---@brief [[
@@ -389,6 +300,10 @@ local convert_value_to_vim = (function()
}
return function(name, info, value)
if value == nil then
return vim.NIL
end
local option_type = get_option_type(name, info)
assert_valid_value(name, value, valid_types[option_type])
@@ -671,15 +586,19 @@ local create_option_metatable = function(set_type)
}, option_mt)
end
-- TODO(tjdevries): consider supporting `nil` for set to remove the local option.
-- vim.cmd [[set option<]]
local scope
if set_type == SET_TYPES.GLOBAL then
scope = "global"
elseif set_type == SET_TYPES.LOCAL then
scope = "local"
end
option_mt = {
-- To set a value, instead use:
-- opt[my_option] = value
_set = function(self)
local value = convert_value_to_vim(self._name, self._info, self._value)
set_scoped_option(self._name, value, set_type)
a.nvim_set_option_value(self._name, value, {scope = scope})
return self
end,
@@ -716,7 +635,7 @@ local create_option_metatable = function(set_type)
set_mt = {
__index = function(_, k)
return make_option(k, get_scoped_option(k, set_type))
return make_option(k, a.nvim_get_option_value(k, {scope = scope}))
end,
__newindex = function(_, k, v)