refactor(options): make immutable and hidden options distinct

Problem: Currently, the `immutable` property of options can be applied for options that are hidden and options whose value simply can't be changed. Which is problematic when attempting to convert an option like `'maxcombine'` into an immutable option, because trying to `:set` an immutable option currently gives an error, which is only desired behavior for hidden options, not options that are actually immutable.

Solution: Separate the `immutable` property into two distinct `hidden` and `immutable` properties. Change all options with the `immutable` property to use the `hidden` property instead. Also add `p_mco` as an `immutable` option, as its value cannot be changed, and the underlying variable is not used anywhere.
This commit is contained in:
Famiu Haque 2024-03-25 03:14:00 +06:00 committed by Lewis Russell
parent d3771e68a2
commit de87197fdc
5 changed files with 32 additions and 25 deletions

View File

@ -164,14 +164,19 @@ local function dump_option(i, o)
if o.enable_if then if o.enable_if then
w(get_cond(o.enable_if)) w(get_cond(o.enable_if))
end end
-- Options cannot be both hidden and immutable.
assert(not o.hidden or not o.immutable)
if o.varname then if o.varname then
w(' .var=&' .. o.varname) w(' .var=&' .. o.varname)
-- Immutable options can directly point to the default value. -- Hidden and immutable options can directly point to the default value.
elseif o.immutable then elseif o.hidden or o.immutable then
w((' .var=&options[%u].def_val'):format(i - 1)) w((' .var=&options[%u].def_val'):format(i - 1))
elseif #o.scope == 1 and o.scope[1] == 'window' then elseif #o.scope == 1 and o.scope[1] == 'window' then
w(' .var=VAR_WIN') w(' .var=VAR_WIN')
end end
w(' .hidden=' .. (o.hidden and 'true' or 'false'))
w(' .immutable=' .. (o.immutable and 'true' or 'false')) w(' .immutable=' .. (o.immutable and 'true' or 'false'))
if #o.scope == 1 and o.scope[1] == 'global' then if #o.scope == 1 and o.scope[1] == 'global' then
w(' .indir=PV_NONE') w(' .indir=PV_NONE')

View File

@ -2898,8 +2898,6 @@ static const char *validate_num_option(OptIndex opt_idx, void *varp, OptInt *new
} else if (value > p_wiw) { } else if (value > p_wiw) {
return e_winwidth; return e_winwidth;
} }
} else if (varp == &p_mco) {
*newval = MAX_MCO;
} else if (varp == &p_titlelen) { } else if (varp == &p_titlelen) {
if (value < 0) { if (value < 0) {
return e_positive; return e_positive;
@ -3483,11 +3481,11 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value
.os_win = curwin .os_win = curwin
}; };
if (direct) { if (direct || opt->immutable) {
// Don't do any extra processing if setting directly. // Don't do any extra processing if setting directly or if option is immutable.
} }
// Disallow changing immutable options. // Disallow changing hidden options.
else if (opt->immutable && !optval_equal(old_value, new_value)) { else if (opt->hidden && !optval_equal(old_value, new_value)) {
errmsg = e_unsupportedoption; errmsg = e_unsupportedoption;
} }
// Disallow changing some options from secure mode. // Disallow changing some options from secure mode.
@ -3511,8 +3509,9 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value
restore_chartab = did_set_cb_args.os_restore_chartab; restore_chartab = did_set_cb_args.os_restore_chartab;
} }
// If an error is detected, restore the previous value and don't do any further processing. // If option is immutable or if an error is detected, restore the previous value and don't do any
if (errmsg != NULL) { // further processing.
if (opt->immutable || errmsg != NULL) {
set_option_varp(opt_idx, varp, old_value, true); set_option_varp(opt_idx, varp, old_value, true);
// When resetting some values, need to act on it. // When resetting some values, need to act on it.
if (restore_chartab) { if (restore_chartab) {
@ -4227,7 +4226,7 @@ static int optval_default(OptIndex opt_idx, void *varp)
vimoption_T *opt = &options[opt_idx]; vimoption_T *opt = &options[opt_idx];
// Hidden or immutable options always use their default value. // Hidden or immutable options always use their default value.
if (varp == NULL || opt->immutable) { if (varp == NULL || opt->hidden || opt->immutable) {
return true; return true;
} }

View File

@ -49,7 +49,9 @@ typedef struct {
///< buffer-local option: global value ///< buffer-local option: global value
idopt_T indir; ///< global option: PV_NONE; idopt_T indir; ///< global option: PV_NONE;
///< local option: indirect option index ///< local option: indirect option index
bool immutable; ///< option value cannot be changed from the default value. bool hidden; ///< option is hidden and cannot be set.
bool immutable; ///< option value can be set but any attempt to change the option is
/// ignored.
/// callback function to invoke after an option is modified to validate and /// callback function to invoke after an option is modified to validate and
/// apply the new value. /// apply the new value.

View File

@ -129,6 +129,8 @@
#define DFLT_FO_VIM "tcqj" #define DFLT_FO_VIM "tcqj"
#define FO_ALL "tcro/q2vlb1mMBn,aw]jp" // for do_set() #define FO_ALL "tcro/q2vlb1mMBn,aw]jp" // for do_set()
#define MAX_MCO 6 // fixed value for 'maxcombine'
// characters for the p_cpo option: // characters for the p_cpo option:
#define CPO_ALTREAD 'a' // ":read" sets alternate file name #define CPO_ALTREAD 'a' // ":read" sets alternate file name
#define CPO_ALTWRITE 'A' // ":write" sets alternate file name #define CPO_ALTWRITE 'A' // ":write" sets alternate file name
@ -549,8 +551,6 @@ EXTERN char *p_mef; ///< 'makeef'
EXTERN char *p_mp; ///< 'makeprg' EXTERN char *p_mp; ///< 'makeprg'
EXTERN char *p_mps; ///< 'matchpairs' EXTERN char *p_mps; ///< 'matchpairs'
EXTERN OptInt p_mat; ///< 'matchtime' EXTERN OptInt p_mat; ///< 'matchtime'
EXTERN OptInt p_mco; ///< 'maxcombine'
#define MAX_MCO 6 // fixed value for 'maxcombine'
EXTERN OptInt p_mfd; ///< 'maxfuncdepth' EXTERN OptInt p_mfd; ///< 'maxfuncdepth'
EXTERN OptInt p_mmd; ///< 'maxmapdepth' EXTERN OptInt p_mmd; ///< 'maxmapdepth'
EXTERN OptInt p_mmp; ///< 'maxmempattern' EXTERN OptInt p_mmp; ///< 'maxmempattern'

View File

@ -7,6 +7,7 @@
--- @field varname? string --- @field varname? string
--- @field pv_name? string --- @field pv_name? string
--- @field type 'boolean'|'number'|'string' --- @field type 'boolean'|'number'|'string'
--- @field hidden? boolean
--- @field immutable? boolean --- @field immutable? boolean
--- @field list? 'comma'|'onecomma'|'commacolon'|'onecommacolon'|'flags'|'flagscomma' --- @field list? 'comma'|'onecomma'|'commacolon'|'onecommacolon'|'flags'|'flagscomma'
--- @field scope vim.option_scope[] --- @field scope vim.option_scope[]
@ -1340,7 +1341,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('No description'), short_desc = N_('No description'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
abbreviation = 'cpt', abbreviation = 'cpt',
@ -2299,7 +2300,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('No description'), short_desc = N_('No description'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
abbreviation = 'emo', abbreviation = 'emo',
@ -3888,7 +3889,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('No description'), short_desc = N_('No description'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
abbreviation = 'hkp', abbreviation = 'hkp',
@ -3897,7 +3898,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('No description'), short_desc = N_('No description'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
abbreviation = 'hls', abbreviation = 'hls',
@ -4295,7 +4296,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('No description'), short_desc = N_('No description'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
abbreviation = 'isf', abbreviation = 'isf',
@ -5141,12 +5142,12 @@ return {
}, },
{ {
abbreviation = 'mco', abbreviation = 'mco',
defaults = { if_true = 6 }, defaults = { if_true = imacros('MAX_MCO') },
full_name = 'maxcombine', full_name = 'maxcombine',
scope = { 'global' }, scope = { 'global' },
short_desc = N_('maximum nr of combining characters displayed'), short_desc = N_('maximum nr of combining characters displayed'),
type = 'number', type = 'number',
varname = 'p_mco', immutable = true,
}, },
{ {
abbreviation = 'mfd', abbreviation = 'mfd',
@ -6047,7 +6048,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('enable prompt in Ex mode'), short_desc = N_('enable prompt in Ex mode'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
abbreviation = 'pb', abbreviation = 'pb',
@ -6304,7 +6305,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('No description'), short_desc = N_('No description'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
defaults = { if_true = 2 }, defaults = { if_true = 2 },
@ -8843,7 +8844,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('No description'), short_desc = N_('No description'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
abbreviation = 'tw', abbreviation = 'tw',
@ -9088,7 +9089,7 @@ return {
scope = { 'global' }, scope = { 'global' },
short_desc = N_('No description'), short_desc = N_('No description'),
type = 'boolean', type = 'boolean',
immutable = true, hidden = true,
}, },
{ {
abbreviation = 'udir', abbreviation = 'udir',