From de87197fdc3aa8123a060fc3a780e087c8e258ac Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Mon, 25 Mar 2024 03:14:00 +0600 Subject: [PATCH] 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. --- src/nvim/generators/gen_options.lua | 9 +++++++-- src/nvim/option.c | 17 ++++++++--------- src/nvim/option.h | 4 +++- src/nvim/option_vars.h | 4 ++-- src/nvim/options.lua | 23 ++++++++++++----------- 5 files changed, 32 insertions(+), 25 deletions(-) diff --git a/src/nvim/generators/gen_options.lua b/src/nvim/generators/gen_options.lua index 749844e658..c0c0d6e0b4 100644 --- a/src/nvim/generators/gen_options.lua +++ b/src/nvim/generators/gen_options.lua @@ -164,14 +164,19 @@ local function dump_option(i, o) if o.enable_if then w(get_cond(o.enable_if)) end + + -- Options cannot be both hidden and immutable. + assert(not o.hidden or not o.immutable) + if o.varname then w(' .var=&' .. o.varname) - -- Immutable options can directly point to the default value. - elseif o.immutable then + -- Hidden and immutable options can directly point to the default value. + elseif o.hidden or o.immutable then w((' .var=&options[%u].def_val'):format(i - 1)) elseif #o.scope == 1 and o.scope[1] == 'window' then w(' .var=VAR_WIN') end + w(' .hidden=' .. (o.hidden and 'true' or 'false')) w(' .immutable=' .. (o.immutable and 'true' or 'false')) if #o.scope == 1 and o.scope[1] == 'global' then w(' .indir=PV_NONE') diff --git a/src/nvim/option.c b/src/nvim/option.c index 73a5af5520..e4f32ebec4 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -2898,8 +2898,6 @@ static const char *validate_num_option(OptIndex opt_idx, void *varp, OptInt *new } else if (value > p_wiw) { return e_winwidth; } - } else if (varp == &p_mco) { - *newval = MAX_MCO; } else if (varp == &p_titlelen) { if (value < 0) { return e_positive; @@ -3483,11 +3481,11 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value .os_win = curwin }; - if (direct) { - // Don't do any extra processing if setting directly. + if (direct || opt->immutable) { + // Don't do any extra processing if setting directly or if option is immutable. } - // Disallow changing immutable options. - else if (opt->immutable && !optval_equal(old_value, new_value)) { + // Disallow changing hidden options. + else if (opt->hidden && !optval_equal(old_value, new_value)) { errmsg = e_unsupportedoption; } // 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; } - // If an error is detected, restore the previous value and don't do any further processing. - if (errmsg != NULL) { + // If option is immutable or if an error is detected, restore the previous value and don't do any + // further processing. + if (opt->immutable || errmsg != NULL) { set_option_varp(opt_idx, varp, old_value, true); // When resetting some values, need to act on it. if (restore_chartab) { @@ -4227,7 +4226,7 @@ static int optval_default(OptIndex opt_idx, void *varp) vimoption_T *opt = &options[opt_idx]; // Hidden or immutable options always use their default value. - if (varp == NULL || opt->immutable) { + if (varp == NULL || opt->hidden || opt->immutable) { return true; } diff --git a/src/nvim/option.h b/src/nvim/option.h index 7cf880b19b..2357aa68ac 100644 --- a/src/nvim/option.h +++ b/src/nvim/option.h @@ -49,7 +49,9 @@ typedef struct { ///< buffer-local option: global value idopt_T indir; ///< global option: PV_NONE; ///< 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 /// apply the new value. diff --git a/src/nvim/option_vars.h b/src/nvim/option_vars.h index 175f2af896..35cea7c7bc 100644 --- a/src/nvim/option_vars.h +++ b/src/nvim/option_vars.h @@ -129,6 +129,8 @@ #define DFLT_FO_VIM "tcqj" #define FO_ALL "tcro/q2vlb1mMBn,aw]jp" // for do_set() +#define MAX_MCO 6 // fixed value for 'maxcombine' + // characters for the p_cpo option: #define CPO_ALTREAD 'a' // ":read" 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_mps; ///< 'matchpairs' 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_mmd; ///< 'maxmapdepth' EXTERN OptInt p_mmp; ///< 'maxmempattern' diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 9345a1e9f4..26a0c1a3a9 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -7,6 +7,7 @@ --- @field varname? string --- @field pv_name? string --- @field type 'boolean'|'number'|'string' +--- @field hidden? boolean --- @field immutable? boolean --- @field list? 'comma'|'onecomma'|'commacolon'|'onecommacolon'|'flags'|'flagscomma' --- @field scope vim.option_scope[] @@ -1340,7 +1341,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'cpt', @@ -2299,7 +2300,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'emo', @@ -3888,7 +3889,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'hkp', @@ -3897,7 +3898,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'hls', @@ -4295,7 +4296,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'isf', @@ -5141,12 +5142,12 @@ return { }, { abbreviation = 'mco', - defaults = { if_true = 6 }, + defaults = { if_true = imacros('MAX_MCO') }, full_name = 'maxcombine', scope = { 'global' }, short_desc = N_('maximum nr of combining characters displayed'), type = 'number', - varname = 'p_mco', + immutable = true, }, { abbreviation = 'mfd', @@ -6047,7 +6048,7 @@ return { scope = { 'global' }, short_desc = N_('enable prompt in Ex mode'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'pb', @@ -6304,7 +6305,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { defaults = { if_true = 2 }, @@ -8843,7 +8844,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'tw', @@ -9088,7 +9089,7 @@ return { scope = { 'global' }, short_desc = N_('No description'), type = 'boolean', - immutable = true, + hidden = true, }, { abbreviation = 'udir',