refactor(options): remove .indir, redesign option scopes #31066

Problem:
The way option scopes currently work is inflexible and does not allow for nested
option scopes or easily finding the value of an option at any arbitrary scope
without having to do long handwritten switch-case statements like in
`get_varp()`. `.indir` is also confusing and redundant since option indices for
each scope can be autogenerated.

Solution:
Expand option scopes in such a way that an option can support any amount of
scopes using a set of scope flags, similarly to how it's already done for option
types. Also make options contain information about its index at each scope it
supports. This allows for massively simplifying `get_varp()` and
`get_varp_scope()` in the future by just using a struct for options at each
scope. This would be done by creating a table that stores the offset of an
option's variable at a scope by using the option's index at that scope as a key.
This PR also autogenerates enums for option indices at each scope to remove the
need for `.indir` entirely, and also to allow easily iterating over options all
options that support any scope.

Ref: #29314
This commit is contained in:
Famiu Haque
2024-11-17 02:56:16 +06:00
committed by GitHub
parent be8648f345
commit 29ded88957
20 changed files with 800 additions and 892 deletions

View File

@@ -54,12 +54,20 @@ typedef enum {
kOptValTypeNumber,
kOptValTypeString,
} OptValType;
/// Always update this whenever a new option type is added.
#define kOptValTypeSize (kOptValTypeString + 1)
typedef uint32_t OptTypeFlags;
/// Scopes that an option can support.
typedef enum {
kOptScopeGlobal = 0, ///< Request global option value
kOptScopeWin, ///< Request window-local option value
kOptScopeBuf, ///< Request buffer-local option value
} OptScope;
/// Always update this whenever a new option scope is added.
#define kOptScopeSize (kOptScopeBuf + 1)
typedef uint8_t OptScopeFlags;
typedef union {
// boolean options are actually tri-states because they have a third "None" value.
TriState boolean;
@@ -161,9 +169,26 @@ typedef struct {
/// caller.
typedef int (*opt_expand_cb_T)(optexpand_T *args, int *numMatches, char ***matches);
/// Requested option scopes for various functions in option.c
typedef enum {
kOptReqGlobal = 0, ///< Request global option value
kOptReqWin = 1, ///< Request window-local option value
kOptReqBuf = 2, ///< Request buffer-local option value
} OptReqScope;
typedef struct {
char *fullname; ///< full option name
char *shortname; ///< permissible abbreviation
uint32_t flags; ///< see above
OptTypeFlags type_flags; ///< option type flags, see OptValType
OptScopeFlags scope_flags; ///< option scope flags, see OptScope
void *var; ///< global option: pointer to variable;
///< window-local option: NULL;
///< buffer-local option: global value
ssize_t scope_idx[kOptScopeSize]; ///< index of option at every scope.
bool immutable; ///< option is immutable, trying to set it will give an error.
/// callback function to invoke after an option is modified to validate and
/// apply the new value.
opt_did_set_cb_T opt_did_set_cb;
/// callback function to invoke when expanding possible values on the
/// cmdline. Only useful for string options.
opt_expand_cb_T opt_expand_cb;
OptVal def_val; ///< default value
LastSet last_set; ///< script in which the option was last set
} vimoption_T;