mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor: replace unnecessary helper functions in optionstr.c
Replaces unnecessary helper functions in `optionstr.c` such as `get_option_flags()`, `get_option_fullname()`, `set_option_flag()`, `is_global_option()`, etc. with a single `get_option()` helper function that allows direct access to the `options` array. Also refactors `f_exists()` to use `get_varp_scope` instead of using `get_option_tv`. This opens up the path for removing `getoptions_T` altogether later down the line since the hidden option logic is no longer needed.
This commit is contained in:
parent
1d337d4e2f
commit
4b7904d16b
@ -3659,7 +3659,6 @@ static int eval_index(char **arg, typval_T *rettv, int evaluate, int verbose)
|
||||
int get_option_tv(const char **const arg, typval_T *const rettv, const bool evaluate)
|
||||
FUNC_ATTR_NONNULL_ARG(1)
|
||||
{
|
||||
bool working = (**arg == '+'); // has("+option")
|
||||
int opt_flags;
|
||||
|
||||
// Isolate the option name and find its value.
|
||||
@ -3704,10 +3703,6 @@ int get_option_tv(const char **const arg, typval_T *const rettv, const bool eval
|
||||
rettv->v_type = VAR_STRING;
|
||||
rettv->vval.v_string = stringval;
|
||||
}
|
||||
} else if (working && (opt_type == gov_hidden_bool
|
||||
|| opt_type == gov_hidden_number
|
||||
|| opt_type == gov_hidden_string)) {
|
||||
ret = FAIL;
|
||||
}
|
||||
|
||||
*option_end = c; // put back for error messages
|
||||
|
@ -1938,9 +1938,14 @@ static void f_exists(typval_T *argvars, typval_T *rettv, EvalFuncData fptr)
|
||||
xfree(exp);
|
||||
}
|
||||
} else if (*p == '&' || *p == '+') { // Option.
|
||||
n = (get_option_tv(&p, NULL, true) == OK);
|
||||
if (*skipwhite(p) != NUL) {
|
||||
n = false; // Trailing garbage.
|
||||
bool working = (*p == '+'); // whether option needs to be working
|
||||
int opt_flags;
|
||||
|
||||
if (find_option_end(&p, &opt_flags) != NULL) {
|
||||
int opt_idx = findoption(p);
|
||||
n = (opt_idx >= 0 && (!working || get_varp_scope(get_option(opt_idx), opt_flags) != NULL));
|
||||
} else {
|
||||
n = false;
|
||||
}
|
||||
} else if (*p == '*') { // Internal or user defined function.
|
||||
n = function_exists(p + 1, false);
|
||||
|
@ -106,30 +106,6 @@ static char e_number_required_after_equal[]
|
||||
static char e_preview_window_already_exists[]
|
||||
= N_("E590: A preview window already exists");
|
||||
|
||||
// The options that are local to a window or buffer have "indir" set to one of
|
||||
// these values. Special values:
|
||||
// PV_NONE: global option.
|
||||
// PV_WIN is added: window-local option
|
||||
// PV_BUF is added: buffer-local option
|
||||
// PV_BOTH is added: global option which also has a local value.
|
||||
#define PV_BOTH 0x1000
|
||||
#define PV_WIN 0x2000
|
||||
#define PV_BUF 0x4000
|
||||
#define PV_MASK 0x0fff
|
||||
#define OPT_WIN(x) (idopt_T)(PV_WIN + (int)(x))
|
||||
#define OPT_BUF(x) (idopt_T)(PV_BUF + (int)(x))
|
||||
#define OPT_BOTH(x) (idopt_T)(PV_BOTH + (int)(x))
|
||||
|
||||
// WV_ and BV_ values get typecasted to this for the "indir" field
|
||||
typedef enum {
|
||||
PV_NONE = 0,
|
||||
PV_MAXVAL = 0xffff, // to avoid warnings for value out of range
|
||||
} idopt_T;
|
||||
|
||||
// Options local to a window have a value local to a buffer and global to all
|
||||
// buffers. Indicate this by setting "var" to VAR_WIN.
|
||||
#define VAR_WIN ((char_u *)-1)
|
||||
|
||||
static char *p_term = NULL;
|
||||
static char *p_ttytype = NULL;
|
||||
|
||||
@ -147,19 +123,6 @@ static long p_tw_nopaste;
|
||||
static long p_wm_nopaste;
|
||||
static char *p_vsts_nopaste;
|
||||
|
||||
typedef struct vimoption {
|
||||
char *fullname; // full option name
|
||||
char *shortname; // permissible abbreviation
|
||||
uint32_t flags; // see below
|
||||
char_u *var; // global option: pointer to variable;
|
||||
// window-local option: VAR_WIN;
|
||||
// buffer-local option: global value
|
||||
idopt_T indir; // global option: PV_NONE;
|
||||
// local option: indirect option index
|
||||
char *def_val; // default values for variable (neovim!!)
|
||||
LastSet last_set; // script in which the option was last set
|
||||
} vimoption_T;
|
||||
|
||||
// options[] is initialized here.
|
||||
// The order of the options MUST be alphabetic for ":set all" and findoption().
|
||||
// All option names MUST start with a lowercase letter (for findoption()).
|
||||
@ -3047,47 +3010,10 @@ int get_option_value_strict(char *name, int64_t *numval, char **stringval, int o
|
||||
return rv;
|
||||
}
|
||||
|
||||
/// Return the flags for the option at 'opt_idx'.
|
||||
uint32_t get_option_flags(int opt_idx)
|
||||
// Return information for option at 'opt_idx'
|
||||
vimoption_T *get_option(int opt_idx)
|
||||
{
|
||||
return options[opt_idx].flags;
|
||||
}
|
||||
|
||||
/// Set a flag for the option at 'opt_idx'.
|
||||
void set_option_flag(int opt_idx, uint32_t flag)
|
||||
{
|
||||
options[opt_idx].flags |= flag;
|
||||
}
|
||||
|
||||
/// Clear a flag for the option at 'opt_idx'.
|
||||
void clear_option_flag(int opt_idx, uint32_t flag)
|
||||
{
|
||||
options[opt_idx].flags &= ~flag;
|
||||
}
|
||||
|
||||
/// Returns true if the option at 'opt_idx' is a global option
|
||||
bool is_global_option(int opt_idx)
|
||||
{
|
||||
return options[opt_idx].indir == PV_NONE;
|
||||
}
|
||||
|
||||
/// Returns true if the option at 'opt_idx' is a global option which also has a
|
||||
/// local value.
|
||||
int is_global_local_option(int opt_idx)
|
||||
{
|
||||
return options[opt_idx].indir & PV_BOTH;
|
||||
}
|
||||
|
||||
/// Returns true if the option at 'opt_idx' is a window-local option
|
||||
bool is_window_local_option(int opt_idx)
|
||||
{
|
||||
return options[opt_idx].var == VAR_WIN;
|
||||
}
|
||||
|
||||
/// Returns true if the option at 'opt_idx' is a hidden option
|
||||
bool is_hidden_option(int opt_idx)
|
||||
{
|
||||
return options[opt_idx].var == NULL;
|
||||
return &options[opt_idx];
|
||||
}
|
||||
|
||||
/// Set the value of an option
|
||||
@ -3761,7 +3687,7 @@ void unset_global_local_option(char *name, void *from)
|
||||
}
|
||||
|
||||
/// Get pointer to option variable, depending on local or global scope.
|
||||
static char *get_varp_scope(vimoption_T *p, int opt_flags)
|
||||
char *get_varp_scope(vimoption_T *p, int opt_flags)
|
||||
{
|
||||
if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
|
||||
if (p->var == VAR_WIN) {
|
||||
@ -3833,13 +3759,6 @@ static char *get_varp_scope(vimoption_T *p, int opt_flags)
|
||||
return (char *)get_varp(p);
|
||||
}
|
||||
|
||||
/// Get pointer to option variable at 'opt_idx', depending on local or global
|
||||
/// scope.
|
||||
char *get_option_varp_scope(int opt_idx, int opt_flags)
|
||||
{
|
||||
return get_varp_scope(&(options[opt_idx]), opt_flags);
|
||||
}
|
||||
|
||||
/// Get pointer to option variable.
|
||||
static char_u *get_varp(vimoption_T *p)
|
||||
{
|
||||
@ -4149,18 +4068,6 @@ static char_u *get_varp(vimoption_T *p)
|
||||
return (char_u *)&(curbuf->b_p_wm);
|
||||
}
|
||||
|
||||
/// Return a pointer to the variable for option at 'opt_idx'
|
||||
char_u *get_option_var(int opt_idx)
|
||||
{
|
||||
return options[opt_idx].var;
|
||||
}
|
||||
|
||||
/// Return the full name of the option at 'opt_idx'
|
||||
char *get_option_fullname(int opt_idx)
|
||||
{
|
||||
return options[opt_idx].fullname;
|
||||
}
|
||||
|
||||
/// Get the value of 'equalprg', either the buffer-local one or the global one.
|
||||
char_u *get_equalprg(void)
|
||||
{
|
||||
|
@ -990,4 +990,41 @@ typedef struct {
|
||||
uint64_t channel_id; /// Only used when script_id is SID_API_CLIENT.
|
||||
} LastSet;
|
||||
|
||||
// WV_ and BV_ values get typecasted to this for the "indir" field
|
||||
typedef enum {
|
||||
PV_NONE = 0,
|
||||
PV_MAXVAL = 0xffff, // to avoid warnings for value out of range
|
||||
} idopt_T;
|
||||
|
||||
typedef struct vimoption {
|
||||
char *fullname; // full option name
|
||||
char *shortname; // permissible abbreviation
|
||||
uint32_t flags; // see below
|
||||
char_u *var; // global option: pointer to variable;
|
||||
// window-local option: VAR_WIN;
|
||||
// buffer-local option: global value
|
||||
idopt_T indir; // global option: PV_NONE;
|
||||
// local option: indirect option index
|
||||
char *def_val; // default values for variable (neovim!!)
|
||||
LastSet last_set; // script in which the option was last set
|
||||
} vimoption_T;
|
||||
|
||||
// The options that are local to a window or buffer have "indir" set to one of
|
||||
// these values. Special values:
|
||||
// PV_NONE: global option.
|
||||
// PV_WIN is added: window-local option
|
||||
// PV_BUF is added: buffer-local option
|
||||
// PV_BOTH is added: global option which also has a local value.
|
||||
#define PV_BOTH 0x1000
|
||||
#define PV_WIN 0x2000
|
||||
#define PV_BUF 0x4000
|
||||
#define PV_MASK 0x0fff
|
||||
#define OPT_WIN(x) (idopt_T)(PV_WIN + (int)(x))
|
||||
#define OPT_BUF(x) (idopt_T)(PV_BUF + (int)(x))
|
||||
#define OPT_BOTH(x) (idopt_T)(PV_BOTH + (int)(x))
|
||||
|
||||
// Options local to a window have a value local to a buffer and global to all
|
||||
// buffers. Indicate this by setting "var" to VAR_WIN.
|
||||
#define VAR_WIN ((char_u *)-1)
|
||||
|
||||
#endif // NVIM_OPTION_DEFS_H
|
||||
|
@ -178,7 +178,7 @@ void trigger_optionsset_string(int opt_idx, int opt_flags, char *oldval, char *o
|
||||
set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1);
|
||||
set_vim_var_string(VV_OPTION_OLDLOCAL, oldval, -1);
|
||||
}
|
||||
apply_autocmds(EVENT_OPTIONSET, get_option_fullname(opt_idx), NULL, false, NULL);
|
||||
apply_autocmds(EVENT_OPTIONSET, get_option(opt_idx)->fullname, NULL, false, NULL);
|
||||
reset_v_option_vars();
|
||||
}
|
||||
}
|
||||
@ -280,19 +280,19 @@ void check_string_option(char **pp)
|
||||
|
||||
/// Set global value for string option when it's a local option.
|
||||
///
|
||||
/// @param opt_idx option index
|
||||
/// @param opt option
|
||||
/// @param varp pointer to option variable
|
||||
static void set_string_option_global(int opt_idx, char **varp)
|
||||
static void set_string_option_global(vimoption_T *opt, char **varp)
|
||||
{
|
||||
char **p;
|
||||
|
||||
// the global value is always allocated
|
||||
if (is_window_local_option(opt_idx)) {
|
||||
if (opt->var == VAR_WIN) {
|
||||
p = (char **)GLOBAL_WO(varp);
|
||||
} else {
|
||||
p = (char **)get_option_var(opt_idx);
|
||||
p = (char **)opt->var;
|
||||
}
|
||||
if (!is_global_option(opt_idx) && p != varp) {
|
||||
if (opt->indir != PV_NONE && p != varp) {
|
||||
char *s = xstrdup(*varp);
|
||||
free_string_option(*p);
|
||||
*p = s;
|
||||
@ -324,30 +324,32 @@ void set_string_option_direct(const char *name, int opt_idx, const char *val, in
|
||||
}
|
||||
}
|
||||
|
||||
if (is_hidden_option(idx)) { // can't set hidden option
|
||||
vimoption_T *opt = get_option(idx);
|
||||
|
||||
if (opt->var == NULL) { // can't set hidden option
|
||||
return;
|
||||
}
|
||||
|
||||
assert((void *)get_option_var(idx) != (void *)&p_shada);
|
||||
assert((void *)opt->var != (void *)&p_shada);
|
||||
|
||||
s = xstrdup(val);
|
||||
{
|
||||
varp = (char **)get_option_varp_scope(idx, both ? OPT_LOCAL : opt_flags);
|
||||
if ((opt_flags & OPT_FREE) && (get_option_flags(idx) & P_ALLOCED)) {
|
||||
varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags);
|
||||
if ((opt_flags & OPT_FREE) && (opt->flags & P_ALLOCED)) {
|
||||
free_string_option(*varp);
|
||||
}
|
||||
*varp = s;
|
||||
|
||||
// For buffer/window local option may also set the global value.
|
||||
if (both) {
|
||||
set_string_option_global(idx, varp);
|
||||
set_string_option_global(opt, varp);
|
||||
}
|
||||
|
||||
set_option_flag(idx, P_ALLOCED);
|
||||
opt->flags |= P_ALLOCED;
|
||||
|
||||
// When setting both values of a global option with a local value,
|
||||
// make the local value empty, so that the global value is used.
|
||||
if (is_global_local_option(idx) && both) {
|
||||
if ((opt->indir & PV_BOTH) && both) {
|
||||
free_string_option(*varp);
|
||||
*varp = empty_option;
|
||||
}
|
||||
@ -393,24 +395,24 @@ void set_string_option_direct_in_win(win_T *wp, const char *name, int opt_idx, c
|
||||
char *set_string_option(const int opt_idx, const char *const value, const int opt_flags)
|
||||
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_WARN_UNUSED_RESULT
|
||||
{
|
||||
if (is_hidden_option(opt_idx)) { // don't set hidden option
|
||||
vimoption_T *opt = get_option(opt_idx);
|
||||
|
||||
if (opt->var == NULL) { // don't set hidden option
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char *const s = xstrdup(value);
|
||||
char **const varp
|
||||
= (char **)get_option_varp_scope(opt_idx,
|
||||
(opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
|
||||
? (is_global_local_option(opt_idx)
|
||||
? OPT_GLOBAL : OPT_LOCAL)
|
||||
: opt_flags);
|
||||
= (char **)get_varp_scope(opt, ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
|
||||
? ((opt->indir & PV_BOTH) ? OPT_GLOBAL : OPT_LOCAL)
|
||||
: opt_flags));
|
||||
char *const oldval = *varp;
|
||||
char *oldval_l = NULL;
|
||||
char *oldval_g = NULL;
|
||||
|
||||
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
|
||||
oldval_l = *(char **)get_option_varp_scope(opt_idx, OPT_LOCAL);
|
||||
oldval_g = *(char **)get_option_varp_scope(opt_idx, OPT_GLOBAL);
|
||||
oldval_l = *(char **)get_varp_scope(opt, OPT_LOCAL);
|
||||
oldval_g = *(char **)get_varp_scope(opt, OPT_GLOBAL);
|
||||
}
|
||||
|
||||
*varp = s;
|
||||
@ -434,8 +436,8 @@ char *set_string_option(const int opt_idx, const char *const value, const int op
|
||||
trigger_optionsset_string(opt_idx, opt_flags, saved_oldval, saved_oldval_l, saved_oldval_g,
|
||||
saved_newval);
|
||||
}
|
||||
if (get_option_flags(opt_idx) & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(get_option_fullname(opt_idx)),
|
||||
if (opt->flags & P_UI_OPTION) {
|
||||
ui_call_option_set(cstr_as_string(opt->fullname),
|
||||
STRING_OBJ(cstr_as_string(saved_newval)));
|
||||
}
|
||||
}
|
||||
@ -638,20 +640,21 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
|
||||
char *errmsg = NULL;
|
||||
char *s, *p;
|
||||
int did_chartab = false;
|
||||
bool free_oldval = (get_option_flags(opt_idx) & P_ALLOCED);
|
||||
vimoption_T *opt = get_option(opt_idx);
|
||||
bool free_oldval = (opt->flags & P_ALLOCED);
|
||||
bool value_changed = false;
|
||||
|
||||
// Get the global option to compare with, otherwise we would have to check
|
||||
// two values for all local options.
|
||||
char **gvarp = (char **)get_option_varp_scope(opt_idx, OPT_GLOBAL);
|
||||
char **gvarp = (char **)get_varp_scope(opt, OPT_GLOBAL);
|
||||
|
||||
// Disallow changing some options from secure mode
|
||||
if ((secure || sandbox != 0)
|
||||
&& (get_option_flags(opt_idx) & P_SECURE)) {
|
||||
&& (opt->flags & P_SECURE)) {
|
||||
errmsg = e_secure;
|
||||
} else if (((get_option_flags(opt_idx) & P_NFNAME)
|
||||
} else if (((opt->flags & P_NFNAME)
|
||||
&& strpbrk(*varp, (secure ? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL)
|
||||
|| ((get_option_flags(opt_idx) & P_NDNAME)
|
||||
|| ((opt->flags & P_NDNAME)
|
||||
&& strpbrk(*varp, "*?[|;&<>\r\n") != NULL)) {
|
||||
// Check for a "normal" directory or file name in some options. Disallow a
|
||||
// path separator (slash and/or backslash), wildcards and characters that
|
||||
@ -986,13 +989,14 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
|
||||
} else if (varp == &p_shada) { // 'shada'
|
||||
// TODO(ZyX-I): Remove this code in the future, alongside with &viminfo
|
||||
// option.
|
||||
opt_idx = ((get_option_fullname(opt_idx)[0] == 'v')
|
||||
opt_idx = ((opt->fullname[0] == 'v')
|
||||
? (shada_idx == -1 ? ((shada_idx = findoption("shada"))) : shada_idx)
|
||||
: opt_idx);
|
||||
opt = get_option(opt_idx);
|
||||
// Update free_oldval now that we have the opt_idx for 'shada', otherwise
|
||||
// there would be a disconnect between the check for P_ALLOCED at the start
|
||||
// of the function and the set of P_ALLOCED at the end of the function.
|
||||
free_oldval = (get_option_flags(opt_idx) & P_ALLOCED);
|
||||
free_oldval = (opt->flags & P_ALLOCED);
|
||||
for (s = p_shada; *s;) {
|
||||
// Check it's a valid character
|
||||
if (vim_strchr("!\"%'/:<@cfhnrs", *s) == NULL) {
|
||||
@ -1522,18 +1526,18 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
|
||||
if (free_oldval) {
|
||||
free_string_option(oldval);
|
||||
}
|
||||
set_option_flag(opt_idx, P_ALLOCED);
|
||||
opt->flags |= P_ALLOCED;
|
||||
|
||||
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
|
||||
&& is_global_local_option(opt_idx)) {
|
||||
&& (opt->indir & PV_BOTH)) {
|
||||
// global option with local value set to use global value; free
|
||||
// the local value and make it empty
|
||||
p = get_option_varp_scope(opt_idx, OPT_LOCAL);
|
||||
p = get_varp_scope(opt, OPT_LOCAL);
|
||||
free_string_option(*(char **)p);
|
||||
*(char **)p = empty_option;
|
||||
} else if (!(opt_flags & OPT_LOCAL) && opt_flags != OPT_GLOBAL) {
|
||||
// May set global value for local option.
|
||||
set_string_option_global(opt_idx, varp);
|
||||
set_string_option_global(opt, varp);
|
||||
}
|
||||
|
||||
// Trigger the autocommand only after setting the flags.
|
||||
@ -1604,11 +1608,11 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
|
||||
}
|
||||
|
||||
if (curwin->w_curswant != MAXCOL
|
||||
&& (get_option_flags(opt_idx) & (P_CURSWANT | P_RALL)) != 0) {
|
||||
&& (opt->flags & (P_CURSWANT | P_RALL)) != 0) {
|
||||
curwin->w_set_curswant = true;
|
||||
}
|
||||
|
||||
check_redraw(get_option_flags(opt_idx));
|
||||
check_redraw(opt->flags);
|
||||
|
||||
return errmsg;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user