mirror of
https://github.com/neovim/neovim.git
synced 2024-12-31 17:13:26 -07:00
parent
cfcda91827
commit
24e3ee9d07
@ -124,14 +124,12 @@ local function get_option_metatype(name, info)
|
|||||||
return info.type
|
return info.type
|
||||||
end
|
end
|
||||||
|
|
||||||
local options_info = setmetatable({}, {
|
--- @param name string
|
||||||
__index = function(t, k)
|
local function get_options_info(name)
|
||||||
local info = api.nvim_get_option_info(k)
|
local info = api.nvim_get_option_info(name)
|
||||||
info.metatype = get_option_metatype(k, info)
|
info.metatype = get_option_metatype(name, info)
|
||||||
rawset(t, k, info)
|
return info
|
||||||
return rawget(t, k)
|
end
|
||||||
end,
|
|
||||||
})
|
|
||||||
|
|
||||||
---Environment variables defined in the editor session.
|
---Environment variables defined in the editor session.
|
||||||
---See |expand-env| and |:let-environment| for the Vimscript behavior.
|
---See |expand-env| and |:let-environment| for the Vimscript behavior.
|
||||||
@ -155,34 +153,16 @@ vim.env = setmetatable({}, {
|
|||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
local function opt_validate(option_name, target_scope)
|
|
||||||
local scope = options_info[option_name].scope
|
|
||||||
if scope ~= target_scope then
|
|
||||||
local scope_to_string = { buf = 'buffer', win = 'window' }
|
|
||||||
error(
|
|
||||||
string.format(
|
|
||||||
[['%s' is a %s option, not a %s option. See ":help %s"]],
|
|
||||||
option_name,
|
|
||||||
scope_to_string[scope] or scope,
|
|
||||||
scope_to_string[target_scope] or target_scope,
|
|
||||||
option_name
|
|
||||||
)
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function new_buf_opt_accessor(bufnr)
|
local function new_buf_opt_accessor(bufnr)
|
||||||
return setmetatable({}, {
|
return setmetatable({}, {
|
||||||
__index = function(_, k)
|
__index = function(_, k)
|
||||||
if bufnr == nil and type(k) == 'number' then
|
if bufnr == nil and type(k) == 'number' then
|
||||||
return new_buf_opt_accessor(k)
|
return new_buf_opt_accessor(k)
|
||||||
end
|
end
|
||||||
opt_validate(k, 'buf')
|
|
||||||
return api.nvim_get_option_value(k, { buf = bufnr or 0 })
|
return api.nvim_get_option_value(k, { buf = bufnr or 0 })
|
||||||
end,
|
end,
|
||||||
|
|
||||||
__newindex = function(_, k, v)
|
__newindex = function(_, k, v)
|
||||||
opt_validate(k, 'buf')
|
|
||||||
return api.nvim_set_option_value(k, v, { buf = bufnr or 0 })
|
return api.nvim_set_option_value(k, v, { buf = bufnr or 0 })
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
@ -203,7 +183,6 @@ local function new_win_opt_accessor(winid, bufnr)
|
|||||||
error('only bufnr=0 is supported')
|
error('only bufnr=0 is supported')
|
||||||
end
|
end
|
||||||
|
|
||||||
opt_validate(k, 'win')
|
|
||||||
-- TODO(lewis6991): allow passing both buf and win to nvim_get_option_value
|
-- TODO(lewis6991): allow passing both buf and win to nvim_get_option_value
|
||||||
return api.nvim_get_option_value(k, {
|
return api.nvim_get_option_value(k, {
|
||||||
scope = bufnr and 'local' or nil,
|
scope = bufnr and 'local' or nil,
|
||||||
@ -212,7 +191,6 @@ local function new_win_opt_accessor(winid, bufnr)
|
|||||||
end,
|
end,
|
||||||
|
|
||||||
__newindex = function(_, k, v)
|
__newindex = function(_, k, v)
|
||||||
opt_validate(k, 'win')
|
|
||||||
-- TODO(lewis6991): allow passing both buf and win to nvim_set_option_value
|
-- TODO(lewis6991): allow passing both buf and win to nvim_set_option_value
|
||||||
return api.nvim_set_option_value(k, v, {
|
return api.nvim_set_option_value(k, v, {
|
||||||
scope = bufnr and 'local' or nil,
|
scope = bufnr and 'local' or nil,
|
||||||
@ -680,7 +658,7 @@ local function create_option_accessor(scope)
|
|||||||
local option_mt
|
local option_mt
|
||||||
|
|
||||||
local function make_option(name, value)
|
local function make_option(name, value)
|
||||||
local info = assert(options_info[name], 'Not a valid option name: ' .. name)
|
local info = assert(get_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
|
||||||
assert(name == value._name, "must be the same value, otherwise that's weird.")
|
assert(name == value._name, "must be the same value, otherwise that's weird.")
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
# include "api/options.c.generated.h"
|
# include "api/options.c.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_type, void **from,
|
static int validate_option_value_args(Dict(option) *opts, char *name, int *scope, int *opt_type,
|
||||||
char **filetype, Error *err)
|
void **from, char **filetype, Error *err)
|
||||||
{
|
{
|
||||||
if (HAS_KEY(opts->scope)) {
|
if (HAS_KEY(opts->scope)) {
|
||||||
VALIDATE_T("scope", kObjectTypeString, opts->scope.type, {
|
VALIDATE_T("scope", kObjectTypeString, opts->scope.type, {
|
||||||
@ -92,6 +92,24 @@ static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_t
|
|||||||
return FAIL;
|
return FAIL;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
int flags = get_option_value_strict(name, NULL, NULL, 0, NULL);
|
||||||
|
if (flags == 0) {
|
||||||
|
// hidden or unknown option
|
||||||
|
api_set_error(err, kErrorTypeValidation, "Unknown option '%s'", name);
|
||||||
|
} else if (*opt_type & (SREQ_BUF | SREQ_WIN)) {
|
||||||
|
// if 'buf' or 'win' is passed, make sure the option supports it
|
||||||
|
int req_flags = *opt_type & SREQ_BUF ? SOPT_BUF : SOPT_WIN;
|
||||||
|
if (!(flags & req_flags)) {
|
||||||
|
char *tgt = *opt_type & SREQ_BUF ? "buf" : "win";
|
||||||
|
char *global = flags & SOPT_GLOBAL ? "global ": "";
|
||||||
|
char *req = flags & SOPT_BUF ? "buffer-local " :
|
||||||
|
flags & SOPT_WIN ? "window-local " : "";
|
||||||
|
|
||||||
|
api_set_error(err, kErrorTypeValidation, "'%s' cannot be passed for %s%soption '%s'",
|
||||||
|
tgt, global, req, name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -197,7 +215,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
|
|||||||
void *from = NULL;
|
void *from = NULL;
|
||||||
char *filetype = NULL;
|
char *filetype = NULL;
|
||||||
|
|
||||||
if (!validate_option_value_args(opts, &scope, &opt_type, &from, &filetype, err)) {
|
if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &from, &filetype, err)) {
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +277,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict(
|
|||||||
int scope = 0;
|
int scope = 0;
|
||||||
int opt_type = SREQ_GLOBAL;
|
int opt_type = SREQ_GLOBAL;
|
||||||
void *to = NULL;
|
void *to = NULL;
|
||||||
if (!validate_option_value_args(opts, &scope, &opt_type, &to, NULL, err)) {
|
if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &to, NULL, err)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -343,7 +361,7 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err)
|
|||||||
int scope = 0;
|
int scope = 0;
|
||||||
int opt_type = SREQ_GLOBAL;
|
int opt_type = SREQ_GLOBAL;
|
||||||
void *from = NULL;
|
void *from = NULL;
|
||||||
if (!validate_option_value_args(opts, &scope, &opt_type, &from, NULL, err)) {
|
if (!validate_option_value_args(opts, name.data, &scope, &opt_type, &from, NULL, err)) {
|
||||||
return (Dictionary)ARRAY_DICT_INIT;
|
return (Dictionary)ARRAY_DICT_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2445,7 +2445,7 @@ describe('API', function()
|
|||||||
it('can throw exceptions', function()
|
it('can throw exceptions', function()
|
||||||
local status, err = pcall(nvim, 'get_option_value', 'invalid-option', {})
|
local status, err = pcall(nvim, 'get_option_value', 'invalid-option', {})
|
||||||
eq(false, status)
|
eq(false, status)
|
||||||
ok(err:match("Invalid 'option': 'invalid%-option'") ~= nil)
|
ok(err:match("Unknown option 'invalid%-option'") ~= nil)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it('does not truncate error message <1 MB #5984', function()
|
it('does not truncate error message <1 MB #5984', function()
|
||||||
|
@ -1509,7 +1509,7 @@ describe('lua stdlib', function()
|
|||||||
]]
|
]]
|
||||||
eq('', funcs.luaeval "vim.bo.filetype")
|
eq('', funcs.luaeval "vim.bo.filetype")
|
||||||
eq(true, funcs.luaeval "vim.bo[BUF].modifiable")
|
eq(true, funcs.luaeval "vim.bo[BUF].modifiable")
|
||||||
matches("Invalid option %(not found%): 'nosuchopt'$",
|
matches("Unknown option 'nosuchopt'$",
|
||||||
pcall_err(exec_lua, 'return vim.bo.nosuchopt'))
|
pcall_err(exec_lua, 'return vim.bo.nosuchopt'))
|
||||||
matches("Expected lua string$",
|
matches("Expected lua string$",
|
||||||
pcall_err(exec_lua, 'return vim.bo[0][0].autoread'))
|
pcall_err(exec_lua, 'return vim.bo[0][0].autoread'))
|
||||||
@ -1530,7 +1530,7 @@ describe('lua stdlib', function()
|
|||||||
eq(0, funcs.luaeval "vim.wo.cole")
|
eq(0, funcs.luaeval "vim.wo.cole")
|
||||||
eq(0, funcs.luaeval "vim.wo[0].cole")
|
eq(0, funcs.luaeval "vim.wo[0].cole")
|
||||||
eq(0, funcs.luaeval "vim.wo[1001].cole")
|
eq(0, funcs.luaeval "vim.wo[1001].cole")
|
||||||
matches("Invalid option %(not found%): 'notanopt'$",
|
matches("Unknown option 'notanopt'$",
|
||||||
pcall_err(exec_lua, 'return vim.wo.notanopt'))
|
pcall_err(exec_lua, 'return vim.wo.notanopt'))
|
||||||
matches("Invalid window id: %-1$",
|
matches("Invalid window id: %-1$",
|
||||||
pcall_err(exec_lua, 'return vim.wo[-1].list'))
|
pcall_err(exec_lua, 'return vim.wo[-1].list'))
|
||||||
|
Loading…
Reference in New Issue
Block a user