mirror of
https://github.com/neovim/neovim.git
synced 2025-12-26 16:19:15 +00:00
Merge pull request #13173 from tjdevries/tjdevries/option_info
api: add option metadata
This commit is contained in:
@@ -933,6 +933,39 @@ nvim_get_option({name}) *nvim_get_option()*
|
||||
Return: ~
|
||||
Option value (global)
|
||||
|
||||
nvim_get_option_info({name}) *nvim_get_option_info()*
|
||||
Gets the option information for one option
|
||||
|
||||
Resulting dictionary has keys:
|
||||
• name (string): Name of the option
|
||||
• shortname (shortname): Shortened name of the option
|
||||
• type (string): Name of the type of option
|
||||
• default (Any): The default value for the option
|
||||
|
||||
Script-Related Keys:
|
||||
• was_set (bool): Whether the option was set.
|
||||
• last_set_sid (int): Last set script id
|
||||
• last_set_linenr (int): Last set script id, -1 if invalid.
|
||||
• last_set_lchan (int): Last set script id, -1 if invalid.
|
||||
|
||||
Flag-Related Keys:
|
||||
• win (bool): Window-local option
|
||||
• buf (bool): Buffer-local option
|
||||
• global_local (bool): Global or Buffer local option
|
||||
• flaglist (bool): List of single char flags
|
||||
|
||||
Parameters: ~
|
||||
{name} Option name
|
||||
|
||||
Return: ~
|
||||
Option Information
|
||||
|
||||
nvim_get_options_info() *nvim_get_options_info()*
|
||||
Gets the option information for all options.
|
||||
|
||||
Return: ~
|
||||
Map<option_name, option_info>
|
||||
|
||||
nvim_get_proc({pid}) *nvim_get_proc()*
|
||||
Gets info describing process `pid` .
|
||||
|
||||
@@ -950,11 +983,16 @@ nvim_get_runtime_file({name}, {all}) *nvim_get_runtime_file()*
|
||||
|
||||
'name' can contain wildcards. For example
|
||||
nvim_get_runtime_file("colors/*.vim", true) will return all
|
||||
color scheme files.
|
||||
color scheme files. Always use forward slashes (/) in the
|
||||
search pattern for subdirectories regardless of platform.
|
||||
|
||||
It is not an error to not find any files. An empty array is
|
||||
returned then.
|
||||
|
||||
To find a directory, `name` must end with a forward slash,
|
||||
like "rplugin/python/". Without the slash it would instead
|
||||
look for an ordinary file called "rplugin/python".
|
||||
|
||||
Attributes: ~
|
||||
{fast}
|
||||
|
||||
@@ -1535,7 +1573,9 @@ nvim_set_hl({ns_id}, {name}, {val}) *nvim_set_hl()*
|
||||
{ns_id} number of namespace for this highlight
|
||||
{name} highlight group name, like ErrorMsg
|
||||
{val} highlight definiton map, like
|
||||
|nvim_get_hl_by_name|.
|
||||
|nvim_get_hl_by_name|. in addition the following
|
||||
keys are also recognized: `default` : don't
|
||||
override existing definition, like `hi default`
|
||||
|
||||
nvim_set_hl_ns({ns_id}) *nvim_set_hl_ns()*
|
||||
Set active namespace for highlights.
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#define BOOLEAN_OBJ(b) ((Object) { \
|
||||
.type = kObjectTypeBoolean, \
|
||||
.data.boolean = b })
|
||||
#define BOOL(b) BOOLEAN_OBJ(b)
|
||||
|
||||
#define INTEGER_OBJ(i) ((Object) { \
|
||||
.type = kObjectTypeInteger, \
|
||||
@@ -29,6 +30,8 @@
|
||||
.type = kObjectTypeString, \
|
||||
.data.string = s })
|
||||
|
||||
#define CSTR_TO_OBJ(s) STRING_OBJ(cstr_to_string(s))
|
||||
|
||||
#define BUFFER_OBJ(s) ((Object) { \
|
||||
.type = kObjectTypeBuffer, \
|
||||
.data.integer = s })
|
||||
@@ -59,6 +62,8 @@
|
||||
#define PUT(dict, k, v) \
|
||||
kv_push(dict, ((KeyValuePair) { .key = cstr_to_string(k), .value = v }))
|
||||
|
||||
#define PUT_BOOL(dict, name, condition) PUT(dict, name, BOOLEAN_OBJ(condition));
|
||||
|
||||
#define ADD(array, item) \
|
||||
kv_push(array, item)
|
||||
|
||||
|
||||
@@ -970,6 +970,47 @@ Object nvim_get_option(String name, Error *err)
|
||||
return get_option_from(NULL, SREQ_GLOBAL, name, err);
|
||||
}
|
||||
|
||||
/// Gets the option information for all options.
|
||||
///
|
||||
/// The dictionary has the full option names as keys and option metadata
|
||||
/// dictionaries as detailed at |nvim_get_option_info|.
|
||||
///
|
||||
/// @return dictionary of all options
|
||||
Dictionary nvim_get_all_options_info(Error *err)
|
||||
FUNC_API_SINCE(7)
|
||||
{
|
||||
return get_all_vimoptions();
|
||||
}
|
||||
|
||||
/// Gets the option information for one option
|
||||
///
|
||||
/// Resulting dictionary has keys:
|
||||
/// - name: Name of the option (like 'filetype')
|
||||
/// - shortname: Shortened name of the option (like 'ft')
|
||||
/// - type: type of option ("string", "integer" or "boolean")
|
||||
/// - default: The default value for the option
|
||||
/// - was_set: Whether the option was set.
|
||||
///
|
||||
/// - last_set_sid: Last set script id (if any)
|
||||
/// - last_set_linenr: line number where option was set
|
||||
/// - last_set_chan: Channel where option was set (0 for local)
|
||||
///
|
||||
/// - scope: one of "global", "win", or "buf"
|
||||
/// - global_local: whether win or buf option has a global value
|
||||
///
|
||||
/// - commalist: List of comma separated values
|
||||
/// - flaglist: List of single char flags
|
||||
///
|
||||
///
|
||||
/// @param name Option name
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return Option Information
|
||||
Dictionary nvim_get_option_info(String name, Error *err)
|
||||
FUNC_API_SINCE(7)
|
||||
{
|
||||
return get_vimoption(name, err);
|
||||
}
|
||||
|
||||
/// Sets an option value.
|
||||
///
|
||||
/// @param channel_id
|
||||
|
||||
@@ -352,9 +352,6 @@ void set_init_1(bool clean_arg)
|
||||
|
||||
langmap_init();
|
||||
|
||||
// Be nocompatible
|
||||
p_cp = false;
|
||||
|
||||
/*
|
||||
* Find default value for 'shell' option.
|
||||
* Don't use it if it is empty.
|
||||
@@ -683,7 +680,7 @@ set_options_default(
|
||||
{
|
||||
for (int i = 0; options[i].fullname; i++) {
|
||||
if (!(options[i].flags & P_NODEFAULT)) {
|
||||
set_option_default(i, opt_flags, p_cp);
|
||||
set_option_default(i, opt_flags, false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -763,7 +760,7 @@ void set_init_2(bool headless)
|
||||
// which results in the actual value computed from the window height.
|
||||
idx = findoption("scroll");
|
||||
if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
|
||||
set_option_default(idx, OPT_LOCAL, p_cp);
|
||||
set_option_default(idx, OPT_LOCAL, false);
|
||||
}
|
||||
comp_col();
|
||||
|
||||
@@ -1113,7 +1110,7 @@ int do_set(
|
||||
|
||||
if (vim_strchr((char_u *)"?=:!&<", nextchar) != NULL) {
|
||||
arg += len;
|
||||
cp_val = p_cp;
|
||||
cp_val = false;
|
||||
if (nextchar == '&' && arg[1] == 'v' && arg[2] == 'i') {
|
||||
if (arg[3] == 'm') { // "opt&vim": set to Vim default
|
||||
cp_val = false;
|
||||
@@ -3617,10 +3614,14 @@ static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
|
||||
{
|
||||
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
|
||||
int indir = (int)options[opt_idx].indir;
|
||||
const LastSet last_set = { .script_ctx =
|
||||
{ script_ctx.sc_sid, script_ctx.sc_seq,
|
||||
script_ctx.sc_lnum + sourcing_lnum },
|
||||
current_channel_id };
|
||||
const LastSet last_set = {
|
||||
.script_ctx = {
|
||||
script_ctx.sc_sid,
|
||||
script_ctx.sc_seq,
|
||||
script_ctx.sc_lnum + sourcing_lnum
|
||||
},
|
||||
current_channel_id
|
||||
};
|
||||
|
||||
// Remember where the option was set. For local options need to do that
|
||||
// in the buffer or window structure.
|
||||
@@ -4950,7 +4951,7 @@ static int optval_default(vimoption_T *p, char_u *varp)
|
||||
if (varp == NULL) {
|
||||
return true; // hidden option is always at default
|
||||
}
|
||||
dvi = ((p->flags & P_VI_DEF) || p_cp) ? VI_DEFAULT : VIM_DEFAULT;
|
||||
dvi = (p->flags & P_VI_DEF) ? VI_DEFAULT : VIM_DEFAULT;
|
||||
if (p->flags & P_NUM) {
|
||||
return *(long *)varp == (long)(intptr_t)p->def_val[dvi];
|
||||
}
|
||||
@@ -7174,3 +7175,75 @@ long get_sidescrolloff_value(void)
|
||||
{
|
||||
return curwin->w_p_siso < 0 ? p_siso : curwin->w_p_siso;
|
||||
}
|
||||
|
||||
Dictionary get_vimoption(String name, Error *err)
|
||||
{
|
||||
int opt_idx = findoption_len((const char *)name.data, name.size);
|
||||
if (opt_idx < 0) {
|
||||
api_set_error(err, kErrorTypeValidation, "no such option: '%s'", name.data);
|
||||
return (Dictionary)ARRAY_DICT_INIT;
|
||||
}
|
||||
return vimoption2dict(&options[opt_idx]);
|
||||
}
|
||||
|
||||
Dictionary get_all_vimoptions(void)
|
||||
{
|
||||
Dictionary retval = ARRAY_DICT_INIT;
|
||||
for (size_t i = 0; i < PARAM_COUNT; i++) {
|
||||
Dictionary opt_dict = vimoption2dict(&options[i]);
|
||||
PUT(retval, options[i].fullname, DICTIONARY_OBJ(opt_dict));
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
static Dictionary vimoption2dict(vimoption_T *opt)
|
||||
{
|
||||
Dictionary dict = ARRAY_DICT_INIT;
|
||||
|
||||
PUT(dict, "name", CSTR_TO_OBJ(opt->fullname));
|
||||
PUT(dict, "shortname", CSTR_TO_OBJ(opt->shortname));
|
||||
|
||||
const char *scope;
|
||||
if (opt->indir & PV_BUF) {
|
||||
scope = "buf";
|
||||
} else if (opt->indir & PV_WIN) {
|
||||
scope = "win";
|
||||
} else {
|
||||
scope = "global";
|
||||
}
|
||||
|
||||
PUT(dict, "scope", CSTR_TO_OBJ(scope));
|
||||
|
||||
// welcome to the jungle
|
||||
PUT(dict, "global_local", BOOL(opt->indir & PV_BOTH));
|
||||
PUT(dict, "commalist", BOOL(opt->flags & P_COMMA));
|
||||
PUT(dict, "flaglist", BOOL(opt->flags & P_FLAGLIST));
|
||||
|
||||
PUT(dict, "was_set", BOOL(opt->flags & P_WAS_SET));
|
||||
|
||||
PUT(dict, "last_set_sid", INTEGER_OBJ(opt->last_set.script_ctx.sc_sid));
|
||||
PUT(dict, "last_set_linenr", INTEGER_OBJ(opt->last_set.script_ctx.sc_lnum));
|
||||
PUT(dict, "last_set_chan", INTEGER_OBJ((int64_t)opt->last_set.channel_id));
|
||||
|
||||
const char *type;
|
||||
Object def;
|
||||
// TODO(bfredl): do you even nocp?
|
||||
char_u *def_val = opt->def_val[(opt->flags & P_VI_DEF)
|
||||
? VI_DEFAULT : VIM_DEFAULT];
|
||||
if (opt->flags & P_STRING) {
|
||||
type = "string";
|
||||
def = CSTR_TO_OBJ(def_val ? (char *)def_val : "");
|
||||
} else if (opt->flags & P_NUM) {
|
||||
type = "number";
|
||||
def = INTEGER_OBJ((Integer)(intptr_t)def_val);
|
||||
} else if (opt->flags & P_BOOL) {
|
||||
type = "boolean";
|
||||
def = BOOL((intptr_t)def_val);
|
||||
} else {
|
||||
type = ""; def = NIL;
|
||||
}
|
||||
PUT(dict, "type", CSTR_TO_OBJ(type));
|
||||
PUT(dict, "default", def);
|
||||
|
||||
return dict;
|
||||
}
|
||||
|
||||
@@ -372,7 +372,6 @@ EXTERN long p_cwh; // 'cmdwinheight'
|
||||
EXTERN long p_ch; // 'cmdheight'
|
||||
EXTERN long p_columns; // 'columns'
|
||||
EXTERN int p_confirm; // 'confirm'
|
||||
EXTERN int p_cp; // 'compatible'
|
||||
EXTERN char_u *p_cot; // 'completeopt'
|
||||
# ifdef BACKSLASH_IN_FILENAME
|
||||
EXTERN char_u *p_csl; // 'completeslash'
|
||||
|
||||
@@ -1921,4 +1921,79 @@ describe('API', function()
|
||||
eq({}, meths.get_runtime_file("foobarlang/", true))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_get_all_options_info', function()
|
||||
it('should have key value pairs of option names', function()
|
||||
local options_info = meths.get_all_options_info()
|
||||
neq(nil, options_info.listchars)
|
||||
neq(nil, options_info.tabstop)
|
||||
|
||||
eq(meths.get_option_info'winhighlight', options_info.winhighlight)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('nvim_get_option_info', function()
|
||||
it('should error for unknown options', function()
|
||||
eq("no such option: 'bogus'", pcall_err(meths.get_option_info, 'bogus'))
|
||||
end)
|
||||
|
||||
it('should return the same options for short and long name', function()
|
||||
eq(meths.get_option_info'winhl', meths.get_option_info'winhighlight')
|
||||
end)
|
||||
|
||||
it('should have information about window options', function()
|
||||
eq({
|
||||
commalist = false;
|
||||
default = "";
|
||||
flaglist = false;
|
||||
global_local = false;
|
||||
last_set_chan = 0;
|
||||
last_set_linenr = 0;
|
||||
last_set_sid = 0;
|
||||
name = "winhighlight";
|
||||
scope = "win";
|
||||
shortname = "winhl";
|
||||
type = "string";
|
||||
was_set = false;
|
||||
}, meths.get_option_info'winhl')
|
||||
end)
|
||||
|
||||
it('should have information about buffer options', function()
|
||||
eq({
|
||||
commalist = false,
|
||||
default = "",
|
||||
flaglist = false,
|
||||
global_local = false,
|
||||
last_set_chan = 0,
|
||||
last_set_linenr = 0,
|
||||
last_set_sid = 0,
|
||||
name = "filetype",
|
||||
scope = "buf",
|
||||
shortname = "ft",
|
||||
type = "string",
|
||||
was_set = false
|
||||
}, meths.get_option_info'filetype')
|
||||
end)
|
||||
|
||||
it('should have information about global options', function()
|
||||
-- precondition: the option was changed from its default
|
||||
-- in test setup.
|
||||
eq(false, meths.get_option'showcmd')
|
||||
|
||||
eq({
|
||||
commalist = false,
|
||||
default = true,
|
||||
flaglist = false,
|
||||
global_local = false,
|
||||
last_set_chan = 0,
|
||||
last_set_linenr = 0,
|
||||
last_set_sid = -2,
|
||||
name = "showcmd",
|
||||
scope = "global",
|
||||
shortname = "sc",
|
||||
type = "boolean",
|
||||
was_set = true
|
||||
}, meths.get_option_info'showcmd')
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
|
||||
Reference in New Issue
Block a user