mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 18:55:14 -07:00
parent
cfcda91827
commit
24e3ee9d07
@ -124,14 +124,12 @@ local function get_option_metatype(name, info)
|
||||
return info.type
|
||||
end
|
||||
|
||||
local options_info = setmetatable({}, {
|
||||
__index = function(t, k)
|
||||
local info = api.nvim_get_option_info(k)
|
||||
info.metatype = get_option_metatype(k, info)
|
||||
rawset(t, k, info)
|
||||
return rawget(t, k)
|
||||
end,
|
||||
})
|
||||
--- @param name string
|
||||
local function get_options_info(name)
|
||||
local info = api.nvim_get_option_info(name)
|
||||
info.metatype = get_option_metatype(name, info)
|
||||
return info
|
||||
end
|
||||
|
||||
---Environment variables defined in the editor session.
|
||||
---See |expand-env| and |:let-environment| for the Vimscript behavior.
|
||||
@ -155,34 +153,16 @@ vim.env = setmetatable({}, {
|
||||
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)
|
||||
return setmetatable({}, {
|
||||
__index = function(_, k)
|
||||
if bufnr == nil and type(k) == 'number' then
|
||||
return new_buf_opt_accessor(k)
|
||||
end
|
||||
opt_validate(k, 'buf')
|
||||
return api.nvim_get_option_value(k, { buf = bufnr or 0 })
|
||||
end,
|
||||
|
||||
__newindex = function(_, k, v)
|
||||
opt_validate(k, 'buf')
|
||||
return api.nvim_set_option_value(k, v, { buf = bufnr or 0 })
|
||||
end,
|
||||
})
|
||||
@ -203,7 +183,6 @@ local function new_win_opt_accessor(winid, bufnr)
|
||||
error('only bufnr=0 is supported')
|
||||
end
|
||||
|
||||
opt_validate(k, 'win')
|
||||
-- TODO(lewis6991): allow passing both buf and win to nvim_get_option_value
|
||||
return api.nvim_get_option_value(k, {
|
||||
scope = bufnr and 'local' or nil,
|
||||
@ -212,7 +191,6 @@ local function new_win_opt_accessor(winid, bufnr)
|
||||
end,
|
||||
|
||||
__newindex = function(_, k, v)
|
||||
opt_validate(k, 'win')
|
||||
-- TODO(lewis6991): allow passing both buf and win to nvim_set_option_value
|
||||
return api.nvim_set_option_value(k, v, {
|
||||
scope = bufnr and 'local' or nil,
|
||||
@ -680,7 +658,7 @@ local function create_option_accessor(scope)
|
||||
local option_mt
|
||||
|
||||
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
|
||||
assert(name == value._name, "must be the same value, otherwise that's weird.")
|
||||
|
@ -23,8 +23,8 @@
|
||||
# include "api/options.c.generated.h"
|
||||
#endif
|
||||
|
||||
static int validate_option_value_args(Dict(option) *opts, int *scope, int *opt_type, void **from,
|
||||
char **filetype, Error *err)
|
||||
static int validate_option_value_args(Dict(option) *opts, char *name, int *scope, int *opt_type,
|
||||
void **from, char **filetype, Error *err)
|
||||
{
|
||||
if (HAS_KEY(opts->scope)) {
|
||||
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;
|
||||
});
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -197,7 +215,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
|
||||
void *from = 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;
|
||||
}
|
||||
|
||||
@ -259,7 +277,7 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict(
|
||||
int scope = 0;
|
||||
int opt_type = SREQ_GLOBAL;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -343,7 +361,7 @@ Dictionary nvim_get_option_info2(String name, Dict(option) *opts, Error *err)
|
||||
int scope = 0;
|
||||
int opt_type = SREQ_GLOBAL;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -2445,7 +2445,7 @@ describe('API', function()
|
||||
it('can throw exceptions', function()
|
||||
local status, err = pcall(nvim, 'get_option_value', 'invalid-option', {})
|
||||
eq(false, status)
|
||||
ok(err:match("Invalid 'option': 'invalid%-option'") ~= nil)
|
||||
ok(err:match("Unknown option 'invalid%-option'") ~= nil)
|
||||
end)
|
||||
|
||||
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(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'))
|
||||
matches("Expected lua string$",
|
||||
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[0].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'))
|
||||
matches("Invalid window id: %-1$",
|
||||
pcall_err(exec_lua, 'return vim.wo[-1].list'))
|
||||
|
Loading…
Reference in New Issue
Block a user