mirror of
https://github.com/neovim/neovim.git
synced 2026-08-27 01:21:48 +00:00
feat(api): add nvim_get_option_value
This commit is contained in:
@@ -58,5 +58,8 @@ return {
|
||||
"highlights";
|
||||
"use_tabline";
|
||||
};
|
||||
option = {
|
||||
"scope";
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -642,7 +642,7 @@ void nvim_set_vvar(String name, Object value, Error *err)
|
||||
dict_set_var(&vimvardict, name, value, false, false, err);
|
||||
}
|
||||
|
||||
/// Gets an option value string.
|
||||
/// Gets the global value of an option.
|
||||
///
|
||||
/// @param name Option name
|
||||
/// @param[out] err Error details, if any
|
||||
@@ -653,6 +653,115 @@ Object nvim_get_option(String name, Error *err)
|
||||
return get_option_from(NULL, SREQ_GLOBAL, name, err);
|
||||
}
|
||||
|
||||
/// Gets the value of an option. The behavior of this function matches that of
|
||||
/// |:set|: the local value of an option is returned if it exists; otherwise,
|
||||
/// the global value is returned. Local values always correspond to the current
|
||||
/// buffer or window. To get a buffer-local or window-local option for a
|
||||
/// specific buffer or window, use |nvim_buf_get_option()| or
|
||||
/// |nvim_win_get_option()|.
|
||||
///
|
||||
/// @param name Option name
|
||||
/// @param opts Optional parameters
|
||||
/// - scope: One of 'global' or 'local'. Analagous to
|
||||
/// |:setglobal| and |:setlocal|, respectively.
|
||||
/// @param[out] err Error details, if any
|
||||
/// @return Option value
|
||||
Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
|
||||
FUNC_API_SINCE(9)
|
||||
{
|
||||
Object rv = OBJECT_INIT;
|
||||
|
||||
int scope = 0;
|
||||
if (opts->scope.type == kObjectTypeString) {
|
||||
if (!strcmp(opts->scope.data.string.data, "local")) {
|
||||
scope = OPT_LOCAL;
|
||||
} else if (!strcmp(opts->scope.data.string.data, "global")) {
|
||||
scope = OPT_GLOBAL;
|
||||
} else {
|
||||
api_set_error(err, kErrorTypeValidation, "invalid scope: must be 'local' or 'global'");
|
||||
goto end;
|
||||
}
|
||||
} else if (HAS_KEY(opts->scope)) {
|
||||
api_set_error(err, kErrorTypeValidation, "invalid value for key: scope");
|
||||
goto end;
|
||||
}
|
||||
|
||||
long numval = 0;
|
||||
char *stringval = NULL;
|
||||
switch (get_option_value(name.data, &numval, (char_u **)&stringval, scope)) {
|
||||
case 0:
|
||||
rv = STRING_OBJ(cstr_as_string(stringval));
|
||||
break;
|
||||
case 1:
|
||||
rv = INTEGER_OBJ(numval);
|
||||
break;
|
||||
case 2:
|
||||
rv = BOOLEAN_OBJ(!!numval);
|
||||
break;
|
||||
default:
|
||||
api_set_error(err, kErrorTypeValidation, "unknown option '%s'", name.data);
|
||||
goto end;
|
||||
}
|
||||
|
||||
end:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/// Sets the value of an option. The behavior of this function matches that of
|
||||
/// |:set|: for global-local options, both the global and local value are set
|
||||
/// unless otherwise specified with {scope}.
|
||||
///
|
||||
/// @param name Option name
|
||||
/// @param value New option value
|
||||
/// @param opts Optional parameters
|
||||
/// - scope: One of 'global' or 'local'. Analagous to
|
||||
/// |:setglobal| and |:setlocal|, respectively.
|
||||
/// @param[out] err Error details, if any
|
||||
void nvim_set_option_value(String name, Object value, Dict(option) *opts, Error *err)
|
||||
FUNC_API_SINCE(9)
|
||||
{
|
||||
int scope = 0;
|
||||
if (opts->scope.type == kObjectTypeString) {
|
||||
if (!strcmp(opts->scope.data.string.data, "local")) {
|
||||
scope = OPT_LOCAL;
|
||||
} else if (!strcmp(opts->scope.data.string.data, "global")) {
|
||||
scope = OPT_GLOBAL;
|
||||
} else {
|
||||
api_set_error(err, kErrorTypeValidation, "invalid scope: must be 'local' or 'global'");
|
||||
return;
|
||||
}
|
||||
} else if (HAS_KEY(opts->scope)) {
|
||||
api_set_error(err, kErrorTypeValidation, "invalid value for key: scope");
|
||||
return;
|
||||
}
|
||||
|
||||
long numval = 0;
|
||||
char *stringval = NULL;
|
||||
|
||||
switch (value.type) {
|
||||
case kObjectTypeInteger:
|
||||
numval = value.data.integer;
|
||||
break;
|
||||
case kObjectTypeBoolean:
|
||||
numval = value.data.boolean ? 1 : 0;
|
||||
break;
|
||||
case kObjectTypeString:
|
||||
stringval = value.data.string.data;
|
||||
break;
|
||||
case kObjectTypeNil:
|
||||
// Do nothing
|
||||
break;
|
||||
default:
|
||||
api_set_error(err, kErrorTypeValidation, "invalid value for option");
|
||||
return;
|
||||
}
|
||||
|
||||
char *e = set_option_value(name.data, numval, stringval, scope);
|
||||
if (e) {
|
||||
api_set_error(err, kErrorTypeException, "%s", e);
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets the option information for all options.
|
||||
///
|
||||
/// The dictionary has the full option names as keys and option metadata
|
||||
@@ -694,7 +803,7 @@ Dictionary nvim_get_option_info(String name, Error *err)
|
||||
return get_vimoption(name, err);
|
||||
}
|
||||
|
||||
/// Sets an option value.
|
||||
/// Sets the global value of an option.
|
||||
///
|
||||
/// @param channel_id
|
||||
/// @param name Option name
|
||||
|
||||
@@ -4828,7 +4828,7 @@ int get_option_tv(const char **const arg, typval_T *const rettv, const bool eval
|
||||
} else if (opt_type == -1) { // hidden number option
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = 0;
|
||||
} else if (opt_type == 1) { // number option
|
||||
} else if (opt_type == 1 || opt_type == 2) { // number or boolean option
|
||||
rettv->v_type = VAR_NUMBER;
|
||||
rettv->vval.v_number = numval;
|
||||
} else { // string option
|
||||
|
||||
@@ -4771,7 +4771,8 @@ static int findoption(const char *const arg)
|
||||
/// @param stringval NULL when only checking existence
|
||||
///
|
||||
/// @returns:
|
||||
/// Number or Toggle option: 1, *numval gets value.
|
||||
/// Toggle option: 2, *numval gets value.
|
||||
/// Number option: 1, *numval gets value.
|
||||
/// String option: 0, *stringval gets allocated string.
|
||||
/// Hidden Number or Toggle option: -1.
|
||||
/// hidden String option: -2.
|
||||
@@ -4804,16 +4805,18 @@ int get_option_value(const char *name, long *numval, char_u **stringval, int opt
|
||||
}
|
||||
if (options[opt_idx].flags & P_NUM) {
|
||||
*numval = *(long *)varp;
|
||||
} else {
|
||||
// Special case: 'modified' is b_changed, but we also want to consider
|
||||
// it set when 'ff' or 'fenc' changed.
|
||||
if ((int *)varp == &curbuf->b_changed) {
|
||||
*numval = curbufIsChanged();
|
||||
} else {
|
||||
*numval = (long)*(int *)varp; // NOLINT(whitespace/cast)
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 1;
|
||||
|
||||
// Special case: 'modified' is b_changed, but we also want to consider
|
||||
// it set when 'ff' or 'fenc' changed.
|
||||
if ((int *)varp == &curbuf->b_changed) {
|
||||
*numval = curbufIsChanged();
|
||||
} else {
|
||||
*numval = (long)*(int *)varp; // NOLINT(whitespace/cast)
|
||||
}
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
// Returns the option attributes and its value. Unlike the above function it
|
||||
@@ -4909,7 +4912,7 @@ int get_option_value_strict(char *name, int64_t *numval, char **stringval, int o
|
||||
// only getting a pointer, no need to use aucmd_prepbuf()
|
||||
curbuf = (buf_T *)from;
|
||||
curwin->w_buffer = curbuf;
|
||||
varp = get_varp(p);
|
||||
varp = get_varp_scope(p, OPT_LOCAL);
|
||||
curbuf = save_curbuf;
|
||||
curwin->w_buffer = curbuf;
|
||||
}
|
||||
@@ -4917,7 +4920,7 @@ int get_option_value_strict(char *name, int64_t *numval, char **stringval, int o
|
||||
win_T *save_curwin = curwin;
|
||||
curwin = (win_T *)from;
|
||||
curbuf = curwin->w_buffer;
|
||||
varp = get_varp(p);
|
||||
varp = get_varp_scope(p, OPT_LOCAL);
|
||||
curwin = save_curwin;
|
||||
curbuf = curwin->w_buffer;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user