refactor(options)!: make OptionSet v: values use typval

BREAKING CHANGE: This breaks the OptionSet autocommand, as the `v:` values associated with it (`v:option_new`, `v:option_old`, `v:option_oldlocal` and `v:option_oldglobal`) are now the same type as the option, instead of all option values being converted to strings.
This commit is contained in:
Famiu Haque
2023-10-08 22:13:15 +06:00
parent 93b9c88946
commit 5df4fdf253
8 changed files with 151 additions and 90 deletions

View File

@@ -71,6 +71,10 @@ The following changes may require adaptations in user config or plugins.
defined by LSP, and hence previously parsed snippets might now be considered defined by LSP, and hence previously parsed snippets might now be considered
invalid input. invalid input.
• |OptionSet| autocommand args |v:option_new|, |v:option_old|,
|v:option_oldlocal|, |v:option_oldglobal| now have the type of the option
instead of always being strings.
============================================================================== ==============================================================================
NEW FEATURES *news-features* NEW FEATURES *news-features*

View File

@@ -379,6 +379,9 @@ UI/Display:
Variables: Variables:
|v:progpath| is always absolute ("full") |v:progpath| is always absolute ("full")
|v:windowid| is always available (for use by external UIs) |v:windowid| is always available (for use by external UIs)
|OptionSet| autocommand args |v:option_new|, |v:option_old|,
|v:option_oldlocal|, |v:option_oldglobal| have the type of the option
instead of always being strings.
Vimscript: Vimscript:
|:redir| nested in |execute()| works. |:redir| nested in |execute()| works.

View File

@@ -7226,6 +7226,17 @@ void set_vim_var_dict(const VimVarIndex idx, dict_T *const val)
tv_dict_set_keys_readonly(val); tv_dict_set_keys_readonly(val);
} }
/// Set v:variable to tv.
///
/// @param[in] idx Index of variable to set.
/// @param[in,out] val Value to set to. Reference count will be incremented.
/// Also keys of the dictionary will be made read-only.
void set_vim_var_tv(const VimVarIndex idx, typval_T *const tv)
{
tv_clear(&vimvars[idx].vv_di.di_tv);
vimvars[idx].vv_di.di_tv = *tv;
}
/// Set the v:argv list. /// Set the v:argv list.
void set_argv_var(char **argv, int argc) void set_argv_var(char **argv, int argc)
{ {

View File

@@ -20,6 +20,7 @@
#include "nvim/eval/encode.h" #include "nvim/eval/encode.h"
#include "nvim/eval/funcs.h" #include "nvim/eval/funcs.h"
#include "nvim/eval/typval.h" #include "nvim/eval/typval.h"
#include "nvim/eval/typval_defs.h"
#include "nvim/eval/userfunc.h" #include "nvim/eval/userfunc.h"
#include "nvim/eval/vars.h" #include "nvim/eval/vars.h"
#include "nvim/eval/window.h" #include "nvim/eval/window.h"
@@ -1896,6 +1897,45 @@ static OptVal tv_to_optval(typval_T *tv, const char *option, uint32_t flags, boo
return value; return value;
} }
/// Convert an option value to typval.
///
/// @param[in] value Option value to convert.
///
/// @return OptVal converted to typval.
typval_T optval_as_tv(OptVal value)
{
typval_T rettv = { .v_type = VAR_SPECIAL, .vval = { .v_special = kSpecialVarNull } };
switch (value.type) {
case kOptValTypeNil:
break;
case kOptValTypeBoolean:
switch (value.data.boolean) {
case kTrue:
rettv.v_type = VAR_BOOL;
rettv.vval.v_bool = kBoolVarTrue;
break;
case kFalse:
rettv.v_type = VAR_BOOL;
rettv.vval.v_bool = kBoolVarFalse;
break;
case kNone:
break; // return v:null for None boolean value
}
break;
case kOptValTypeNumber:
rettv.v_type = VAR_NUMBER;
rettv.vval.v_number = value.data.number;
break;
case kOptValTypeString:
rettv.v_type = VAR_STRING;
rettv.vval.v_string = value.data.string.data;
break;
}
return rettv;
}
/// Set option "varname" to the value of "varp" for the current buffer/window. /// Set option "varname" to the value of "varp" for the current buffer/window.
static void set_option_from_tv(const char *varname, typval_T *varp) static void set_option_from_tv(const char *varname, typval_T *varp)
{ {

View File

@@ -2,6 +2,7 @@
#define NVIM_EVAL_VARS_H #define NVIM_EVAL_VARS_H
#include "nvim/ex_cmds_defs.h" #include "nvim/ex_cmds_defs.h"
#include "nvim/option_defs.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS #ifdef INCLUDE_GENERATED_DECLARATIONS
# include "eval/vars.h.generated.h" # include "eval/vars.h.generated.h"

View File

@@ -46,6 +46,7 @@
#include "nvim/drawscreen.h" #include "nvim/drawscreen.h"
#include "nvim/eval.h" #include "nvim/eval.h"
#include "nvim/eval/typval.h" #include "nvim/eval/typval.h"
#include "nvim/eval/vars.h"
#include "nvim/ex_cmds_defs.h" #include "nvim/ex_cmds_defs.h"
#include "nvim/ex_docmd.h" #include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h" #include "nvim/ex_getln.h"
@@ -1981,40 +1982,40 @@ void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
} }
/// Apply the OptionSet autocommand. /// Apply the OptionSet autocommand.
static void apply_optionset_autocmd(int opt_idx, int opt_flags, OptInt oldval, OptInt oldval_g, static void apply_optionset_autocmd(int opt_idx, int opt_flags, OptVal oldval, OptVal oldval_g,
OptInt newval, const char *errmsg) OptVal oldval_l, OptVal newval, const char *errmsg)
{ {
// Don't do this while starting up, failure or recursively. // Don't do this while starting up, failure or recursively.
if (starting || errmsg != NULL || *get_vim_var_str(VV_OPTION_TYPE) != NUL) { if (starting || errmsg != NULL || *get_vim_var_str(VV_OPTION_TYPE) != NUL) {
return; return;
} }
char buf_old[12], buf_old_global[12], buf_new[12], buf_type[12]; char buf_type[7];
typval_T oldval_tv = optval_as_tv(oldval);
typval_T oldval_g_tv = optval_as_tv(oldval_g);
typval_T oldval_l_tv = optval_as_tv(oldval_l);
typval_T newval_tv = optval_as_tv(newval);
vim_snprintf(buf_old, sizeof(buf_old), "%" PRId64, oldval); vim_snprintf(buf_type, sizeof(buf_type), "%s", (opt_flags & OPT_LOCAL) ? "local" : "global");
vim_snprintf(buf_old_global, sizeof(buf_old_global), "%" PRId64, oldval_g); set_vim_var_tv(VV_OPTION_NEW, &newval_tv);
vim_snprintf(buf_new, sizeof(buf_new), "%" PRId64, newval); set_vim_var_tv(VV_OPTION_OLD, &oldval_tv);
vim_snprintf(buf_type, sizeof(buf_type), "%s",
(opt_flags & OPT_LOCAL) ? "local" : "global");
set_vim_var_string(VV_OPTION_NEW, buf_new, -1);
set_vim_var_string(VV_OPTION_OLD, buf_old, -1);
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1); set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
if (opt_flags & OPT_LOCAL) { if (opt_flags & OPT_LOCAL) {
set_vim_var_string(VV_OPTION_COMMAND, "setlocal", -1); set_vim_var_string(VV_OPTION_COMMAND, "setlocal", -1);
set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); set_vim_var_tv(VV_OPTION_OLDLOCAL, &oldval_tv);
} }
if (opt_flags & OPT_GLOBAL) { if (opt_flags & OPT_GLOBAL) {
set_vim_var_string(VV_OPTION_COMMAND, "setglobal", -1); set_vim_var_string(VV_OPTION_COMMAND, "setglobal", -1);
set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old, -1); set_vim_var_tv(VV_OPTION_OLDGLOBAL, &oldval_tv);
} }
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) { if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
set_vim_var_string(VV_OPTION_COMMAND, "set", -1); set_vim_var_string(VV_OPTION_COMMAND, "set", -1);
set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); set_vim_var_tv(VV_OPTION_OLDLOCAL, &oldval_l_tv);
set_vim_var_string(VV_OPTION_OLDGLOBAL, buf_old_global, -1); set_vim_var_tv(VV_OPTION_OLDGLOBAL, &oldval_g_tv);
} }
if (opt_flags & OPT_MODELINE) { if (opt_flags & OPT_MODELINE) {
set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1); set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1);
set_vim_var_string(VV_OPTION_OLDLOCAL, buf_old, -1); set_vim_var_tv(VV_OPTION_OLDLOCAL, &oldval_tv);
} }
apply_autocmds(EVENT_OPTIONSET, options[opt_idx].fullname, NULL, false, NULL); apply_autocmds(EVENT_OPTIONSET, options[opt_idx].fullname, NULL, false, NULL);
reset_v_option_vars(); reset_v_option_vars();
@@ -3370,7 +3371,7 @@ static char *optval_to_cstr(OptVal o)
UNREACHABLE; UNREACHABLE;
} }
/// Consume an OptVal and convert it to an API Object. /// Convert an OptVal to an API Object.
Object optval_as_object(OptVal o) Object optval_as_object(OptVal o)
{ {
switch (o.type) { switch (o.type) {
@@ -3393,7 +3394,7 @@ Object optval_as_object(OptVal o)
UNREACHABLE; UNREACHABLE;
} }
/// Consume an API Object and convert it to an OptVal. /// Convert an API Object to an OptVal.
OptVal object_as_optval(Object o, bool *error) OptVal object_as_optval(Object o, bool *error)
{ {
switch (o.type) { switch (o.type) {
@@ -3694,20 +3695,26 @@ static const char *set_option(int opt_idx, void *varp, OptVal value, int opt_fla
goto end; goto end;
} }
OptVal old_value = optval_from_varp(value.type, varp);
OptVal old_global_value = NIL_OPTVAL;
// Disallow changing some options from secure mode. // Disallow changing some options from secure mode.
if ((secure || sandbox != 0) && (options[opt_idx].flags & P_SECURE)) { if ((secure || sandbox != 0) && (options[opt_idx].flags & P_SECURE)) {
return e_secure; return e_secure;
} }
// Save the global value before changing anything. This is needed as for vimoption_T *opt = &options[opt_idx];
// a global-only option setting the "local value" in fact sets the global OptVal old_value = optval_from_varp(value.type, varp);
// value (since there is only one value). OptVal old_global_value = NIL_OPTVAL;
OptVal old_local_value = NIL_OPTVAL;
// Save the local and global values before changing anything. This is needed as for a global-only
// option setting the "local value" in fact sets the global value (since there is only one value).
//
// TODO(famiu): This needs to be changed to use the current type of the old value instead of
// value.type, when multi-type options are added.
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) { if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
old_local_value =
optval_from_varp(value.type, get_varp_scope(opt, OPT_LOCAL));
old_global_value = old_global_value =
optval_from_varp(value.type, get_varp_scope(&(options[opt_idx]), OPT_GLOBAL)); optval_from_varp(value.type, get_varp_scope(opt, OPT_GLOBAL));
} }
if (value.type == kOptValTypeNumber) { if (value.type == kOptValTypeNumber) {
@@ -3725,7 +3732,7 @@ static const char *set_option(int opt_idx, void *varp, OptVal value, int opt_fla
set_option_sctx_idx(opt_idx, opt_flags, current_sctx); set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
// May set global value for local option. // May set global value for local option.
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) { if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
set_option_varp(get_varp_scope(&(options[opt_idx]), OPT_GLOBAL), value); set_option_varp(get_varp_scope(opt, OPT_GLOBAL), value);
} }
// Invoke the option specific callback function to validate and apply the new value. // Invoke the option specific callback function to validate and apply the new value.
@@ -3737,7 +3744,7 @@ static const char *set_option(int opt_idx, void *varp, OptVal value, int opt_fla
} else if ((int *)varp == &p_force_off) { } else if ((int *)varp == &p_force_off) {
did_set_cb = did_set_force_off; did_set_cb = did_set_force_off;
} else { } else {
did_set_cb = options[opt_idx].opt_did_set_cb; did_set_cb = opt->opt_did_set_cb;
} }
if (did_set_cb != NULL) { if (did_set_cb != NULL) {
// TODO(famiu): make os_oldval and os_newval use OptVal. // TODO(famiu): make os_oldval and os_newval use OptVal.
@@ -3774,30 +3781,25 @@ static const char *set_option(int opt_idx, void *varp, OptVal value, int opt_fla
= check_num_option_bounds((OptInt *)varp, old_value.data.number, errbuf, errbuflen, errmsg); = check_num_option_bounds((OptInt *)varp, old_value.data.number, errbuf, errbuflen, errmsg);
} }
// Clean this later when set_string_option() is unified with set_option().
#define NUMERIC_OPTVAL_TO_OPTINT(x) \
(OptInt)((x).type == kOptValTypeNumber ? x.data.number : x.data.boolean)
apply_optionset_autocmd(opt_idx, opt_flags, apply_optionset_autocmd(opt_idx, opt_flags,
NUMERIC_OPTVAL_TO_OPTINT(old_value), old_value,
NUMERIC_OPTVAL_TO_OPTINT(old_global_value), old_global_value,
NUMERIC_OPTVAL_TO_OPTINT(value), old_local_value,
value,
errmsg); errmsg);
#undef NUMERIC_OPTVAL_TO_OPTINT if (opt->flags & P_UI_OPTION) {
if (options[opt_idx].flags & P_UI_OPTION) {
OptVal value_copy = optval_copy(optval_from_varp(value.type, varp)); OptVal value_copy = optval_copy(optval_from_varp(value.type, varp));
ui_call_option_set(cstr_as_string(options[opt_idx].fullname), ui_call_option_set(cstr_as_string(opt->fullname),
optval_as_object(value_copy)); optval_as_object(value_copy));
} }
comp_col(); // in case 'columns' or 'ls' changed comp_col(); // in case 'columns' or 'ls' changed
if (curwin->w_curswant != MAXCOL if (curwin->w_curswant != MAXCOL
&& (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) { && (opt->flags & (P_CURSWANT | P_RALL)) != 0) {
curwin->w_set_curswant = true; curwin->w_set_curswant = true;
} }
check_redraw(options[opt_idx].flags); check_redraw(opt->flags);
end: end:
if (errmsg == NULL) { if (errmsg == NULL) {

View File

@@ -441,9 +441,8 @@ void set_string_option_direct_in_buf(buf_T *buf, const char *name, int opt_idx,
/// #OPT_GLOBAL. /// #OPT_GLOBAL.
/// ///
/// @return NULL on success, an untranslated error message on error. /// @return NULL on success, an untranslated error message on error.
const char *set_string_option(const int opt_idx, void *varp, const char *value, const char *set_string_option(const int opt_idx, void *varp, const char *value, const int opt_flags,
const int opt_flags, bool *value_checked, char *const errbuf, bool *value_checked, char *const errbuf, const size_t errbuflen)
const size_t errbuflen)
FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_WARN_UNUSED_RESULT
{ {
vimoption_T *opt = get_option(opt_idx); vimoption_T *opt = get_option(opt_idx);

View File

@@ -48,10 +48,10 @@ end
local function expected_table(option, oldval, oldval_l, oldval_g, newval, scope, cmd, attr) local function expected_table(option, oldval, oldval_l, oldval_g, newval, scope, cmd, attr)
return { return {
option = option, option = option,
oldval = tostring(oldval), oldval = oldval,
oldval_l = tostring(oldval_l), oldval_l = oldval_l,
oldval_g = tostring(oldval_g), oldval_g = oldval_g,
newval = tostring(newval), newval = newval,
scope = scope, scope = scope,
cmd = cmd, cmd = cmd,
attr = attr, attr = attr,
@@ -129,44 +129,44 @@ describe('au OptionSet', function()
it('should be called in setting number option', function() it('should be called in setting number option', function()
command('set nu') command('set nu')
expected_combination({'number', 0, 0, 0, 1, 'global', 'set'}) expected_combination({'number', false, false, false, true, 'global', 'set'})
command('setlocal nonu') command('setlocal nonu')
expected_combination({'number', 1, 1, '', 0, 'local', 'setlocal'}) expected_combination({'number', true, true, '', false, 'local', 'setlocal'})
command('setglobal nonu') command('setglobal nonu')
expected_combination({'number', 1, '', 1, 0, 'global', 'setglobal'}) expected_combination({'number', true, '', true, false, 'global', 'setglobal'})
end) end)
it('should be called in setting autoindent option',function() it('should be called in setting autoindent option',function()
command('setlocal ai') command('setlocal ai')
expected_combination({'autoindent', 0, 0, '', 1, 'local', 'setlocal'}) expected_combination({'autoindent', false, false, '', true, 'local', 'setlocal'})
command('setglobal ai') command('setglobal ai')
expected_combination({'autoindent', 0, '', 0, 1, 'global', 'setglobal'}) expected_combination({'autoindent', false, '', false, true, 'global', 'setglobal'})
command('set noai') command('set noai')
expected_combination({'autoindent', 1, 1, 1, 0, 'global', 'set'}) expected_combination({'autoindent', true, true, true, false, 'global', 'set'})
end) end)
it('should be called in inverting global autoindent option',function() it('should be called in inverting global autoindent option',function()
command('set ai!') command('set ai!')
expected_combination({'autoindent', 0, 0, 0, 1, 'global', 'set'}) expected_combination({'autoindent', false, false, false, true, 'global', 'set'})
end) end)
it('should be called in being unset local autoindent option',function() it('should be called in being unset local autoindent option',function()
command('setlocal ai') command('setlocal ai')
expected_combination({'autoindent', 0, 0, '', 1, 'local', 'setlocal'}) expected_combination({'autoindent', false, false, '', true, 'local', 'setlocal'})
command('setlocal ai<') command('setlocal ai<')
expected_combination({'autoindent', 1, 1, '', 0, 'local', 'setlocal'}) expected_combination({'autoindent', true, true, '', false, 'local', 'setlocal'})
end) end)
it('should be called in setting global list and number option at the same time',function() it('should be called in setting global list and number option at the same time',function()
command('set list nu') command('set list nu')
expected_combination( expected_combination(
{'list', 0, 0, 0, 1, 'global', 'set'}, {'list', false, false, false, true, 'global', 'set'},
{'number', 0, 0, 0, 1, 'global', 'set'} {'number', false, false, false, true, 'global', 'set'}
) )
end) end)
@@ -177,20 +177,20 @@ describe('au OptionSet', function()
it('should be called in setting local acd', function() it('should be called in setting local acd', function()
command('setlocal acd') command('setlocal acd')
expected_combination({'autochdir', 0, 0, '', 1, 'local', 'setlocal'}) expected_combination({'autochdir', false, false, '', true, 'local', 'setlocal'})
end) end)
it('should be called in setting autoread', function() it('should be called in setting autoread', function()
command('set noar') command('set noar')
expected_combination({'autoread', 1, 1, 1, 0, 'global', 'set'}) expected_combination({'autoread', true, true, true, false, 'global', 'set'})
command('setlocal ar') command('setlocal ar')
expected_combination({'autoread', 0, 0, '', 1, 'local', 'setlocal'}) expected_combination({'autoread', false, false, '', true, 'local', 'setlocal'})
end) end)
it('should be called in inverting global autoread', function() it('should be called in inverting global autoread', function()
command('setglobal invar') command('setglobal invar')
expected_combination({'autoread', 1, '', 1, 0, 'global', 'setglobal'}) expected_combination({'autoread', true, '', true, false, 'global', 'setglobal'})
end) end)
it('should be called in setting backspace option through :let', function() it('should be called in setting backspace option through :let', function()
@@ -208,7 +208,7 @@ describe('au OptionSet', function()
it('should trigger using correct option name', function() it('should trigger using correct option name', function()
command('call setbufvar(1, "&backup", 1)') command('call setbufvar(1, "&backup", 1)')
expected_combination({'backup', 0, 0, '', 1, 'local', 'setlocal'}) expected_combination({'backup', false, false, '', true, 'local', 'setlocal'})
end) end)
it('should trigger if the current buffer is different from the targeted buffer', function() it('should trigger if the current buffer is different from the targeted buffer', function()
@@ -441,105 +441,105 @@ describe('au OptionSet', function()
command('noa setglobal foldcolumn=8') command('noa setglobal foldcolumn=8')
command('noa setlocal foldcolumn=1') command('noa setlocal foldcolumn=1')
command('setglobal foldcolumn=2') command('setglobal foldcolumn=2')
expected_combination({'foldcolumn', 8, '', 8, 2, 'global', 'setglobal'}) expected_combination({'foldcolumn', '8', '', '8', '2', 'global', 'setglobal'})
command('noa setglobal foldcolumn=8') command('noa setglobal foldcolumn=8')
command('noa setlocal foldcolumn=1') command('noa setlocal foldcolumn=1')
command('setlocal foldcolumn=2') command('setlocal foldcolumn=2')
expected_combination({'foldcolumn', 1, 1, '', 2, 'local', 'setlocal'}) expected_combination({'foldcolumn', '1', '1', '', '2', 'local', 'setlocal'})
command('noa setglobal foldcolumn=8') command('noa setglobal foldcolumn=8')
command('noa setlocal foldcolumn=1') command('noa setlocal foldcolumn=1')
command('set foldcolumn=2') command('set foldcolumn=2')
expected_combination({'foldcolumn', 1, 1, 8, 2, 'global', 'set'}) expected_combination({'foldcolumn', '1', '1', '8', '2', 'global', 'set'})
command('noa set foldcolumn=8') command('noa set foldcolumn=8')
command('set foldcolumn=2') command('set foldcolumn=2')
expected_combination({'foldcolumn', 8, 8, 8, 2, 'global', 'set'}) expected_combination({'foldcolumn', '8', '8', '8', '2', 'global', 'set'})
end) end)
it('with boolean global option', function() it('with boolean global option', function()
command('noa setglobal nowrapscan') command('noa setglobal nowrapscan')
command('noa setlocal wrapscan') -- Sets the global(!) value command('noa setlocal wrapscan') -- Sets the global(!) value
command('setglobal nowrapscan') command('setglobal nowrapscan')
expected_combination({'wrapscan', 1, '', 1, 0, 'global', 'setglobal'}) expected_combination({'wrapscan', true, '', true, false, 'global', 'setglobal'})
command('noa setglobal nowrapscan') command('noa setglobal nowrapscan')
command('noa setlocal wrapscan') -- Sets the global(!) value command('noa setlocal wrapscan') -- Sets the global(!) value
command('setlocal nowrapscan') command('setlocal nowrapscan')
expected_combination({'wrapscan', 1, 1, '', 0, 'local', 'setlocal'}) expected_combination({'wrapscan', true, true, '', false, 'local', 'setlocal'})
command('noa setglobal nowrapscan') command('noa setglobal nowrapscan')
command('noa setlocal wrapscan') -- Sets the global(!) value command('noa setlocal wrapscan') -- Sets the global(!) value
command('set nowrapscan') command('set nowrapscan')
expected_combination({'wrapscan', 1, 1, 1, 0, 'global', 'set'}) expected_combination({'wrapscan', true, true, true, false, 'global', 'set'})
command('noa set nowrapscan') command('noa set nowrapscan')
command('set wrapscan') command('set wrapscan')
expected_combination({'wrapscan', 0, 0, 0, 1, 'global', 'set'}) expected_combination({'wrapscan', false, false, false, true, 'global', 'set'})
end) end)
it('with boolean global-local (to buffer) option', function() it('with boolean global-local (to buffer) option', function()
command('noa setglobal noautoread') command('noa setglobal noautoread')
command('noa setlocal autoread') command('noa setlocal autoread')
command('setglobal autoread') command('setglobal autoread')
expected_combination({'autoread', 0, '', 0, 1, 'global', 'setglobal'}) expected_combination({'autoread', false, '', false, true, 'global', 'setglobal'})
command('noa setglobal noautoread') command('noa setglobal noautoread')
command('noa setlocal autoread') command('noa setlocal autoread')
command('setlocal noautoread') command('setlocal noautoread')
expected_combination({'autoread', 1, 1, '', 0, 'local', 'setlocal'}) expected_combination({'autoread', true, true, '', false, 'local', 'setlocal'})
command('noa setglobal noautoread') command('noa setglobal noautoread')
command('noa setlocal autoread') command('noa setlocal autoread')
command('set autoread') command('set autoread')
expected_combination({'autoread', 1, 1, 0, 1, 'global', 'set'}) expected_combination({'autoread', true, true, false, true, 'global', 'set'})
command('noa set noautoread') command('noa set noautoread')
command('set autoread') command('set autoread')
expected_combination({'autoread', 0, 0, 0, 1, 'global', 'set'}) expected_combination({'autoread', false, false, false, true, 'global', 'set'})
end) end)
it('with boolean local (to buffer) option', function() it('with boolean local (to buffer) option', function()
command('noa setglobal nocindent') command('noa setglobal nocindent')
command('noa setlocal cindent') command('noa setlocal cindent')
command('setglobal cindent') command('setglobal cindent')
expected_combination({'cindent', 0, '', 0, 1, 'global', 'setglobal'}) expected_combination({'cindent', false, '', false, true, 'global', 'setglobal'})
command('noa setglobal nocindent') command('noa setglobal nocindent')
command('noa setlocal cindent') command('noa setlocal cindent')
command('setlocal nocindent') command('setlocal nocindent')
expected_combination({'cindent', 1, 1, '', 0, 'local', 'setlocal'}) expected_combination({'cindent', true, true, '', false, 'local', 'setlocal'})
command('noa setglobal nocindent') command('noa setglobal nocindent')
command('noa setlocal cindent') command('noa setlocal cindent')
command('set cindent') command('set cindent')
expected_combination({'cindent', 1, 1, 0, 1, 'global', 'set'}) expected_combination({'cindent', true, true, false, true, 'global', 'set'})
command('noa set nocindent') command('noa set nocindent')
command('set cindent') command('set cindent')
expected_combination({'cindent', 0, 0, 0, 1, 'global', 'set'}) expected_combination({'cindent', false, false, false, true, 'global', 'set'})
end) end)
it('with boolean local (to window) option', function() it('with boolean local (to window) option', function()
command('noa setglobal nocursorcolumn') command('noa setglobal nocursorcolumn')
command('noa setlocal cursorcolumn') command('noa setlocal cursorcolumn')
command('setglobal cursorcolumn') command('setglobal cursorcolumn')
expected_combination({'cursorcolumn', 0, '', 0, 1, 'global', 'setglobal'}) expected_combination({'cursorcolumn', false, '', false, true, 'global', 'setglobal'})
command('noa setglobal nocursorcolumn') command('noa setglobal nocursorcolumn')
command('noa setlocal cursorcolumn') command('noa setlocal cursorcolumn')
command('setlocal nocursorcolumn') command('setlocal nocursorcolumn')
expected_combination({'cursorcolumn', 1, 1, '', 0, 'local', 'setlocal'}) expected_combination({'cursorcolumn', true, true, '', false, 'local', 'setlocal'})
command('noa setglobal nocursorcolumn') command('noa setglobal nocursorcolumn')
command('noa setlocal cursorcolumn') command('noa setlocal cursorcolumn')
command('set cursorcolumn') command('set cursorcolumn')
expected_combination({'cursorcolumn', 1, 1, 0, 1, 'global', 'set'}) expected_combination({'cursorcolumn', true, true, false, true, 'global', 'set'})
command('noa set nocursorcolumn') command('noa set nocursorcolumn')
command('set cursorcolumn') command('set cursorcolumn')
expected_combination({'cursorcolumn', 0, 0, 0, 1, 'global', 'set'}) expected_combination({'cursorcolumn', false, false, false, true, 'global', 'set'})
end) end)
end) end)
@@ -559,13 +559,13 @@ describe('au OptionSet', function()
expected_empty() expected_empty()
command('setlocal ro') command('setlocal ro')
expected_combination({'readonly', 0, 0, '', 1, 'local', 'setlocal'}) expected_combination({'readonly', false, false, '', true, 'local', 'setlocal'})
command('setglobal ro') command('setglobal ro')
expected_combination({'readonly', 0, '', 0, 1, 'global', 'setglobal'}) expected_combination({'readonly', false, '', false, true, 'global', 'setglobal'})
command('set noro') command('set noro')
expected_combination({'readonly', 1, 1, 1, 0, 'global', 'set'}) expected_combination({'readonly', true, true, true, false, 'global', 'set'})
end) end)
describe('being set by setbufvar()', function() describe('being set by setbufvar()', function()
@@ -580,7 +580,7 @@ describe('au OptionSet', function()
set_hook('backup') set_hook('backup')
command('call setbufvar(1, "&backup", 1)') command('call setbufvar(1, "&backup", 1)')
expected_combination({'backup', 0, 0, '', 1, 'local', 'setlocal'}) expected_combination({'backup', false, false, '', true, 'local', 'setlocal'})
end) end)
it('should trigger if the current buffer is different from the targeted buffer', function() it('should trigger if the current buffer is different from the targeted buffer', function()
@@ -590,7 +590,8 @@ describe('au OptionSet', function()
local new_bufnr = buf.get_number(new_buffer) local new_bufnr = buf.get_number(new_buffer)
command('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")') command('call setbufvar(' .. new_bufnr .. ', "&buftype", "nofile")')
expected_combination({'buftype', '', '', '', 'nofile', 'local', 'setlocal', {bufnr = new_bufnr}}) expected_combination({ 'buftype', '', '', '', 'nofile', 'local', 'setlocal',
{ bufnr = new_bufnr } })
end) end)
end) end)
@@ -606,7 +607,7 @@ describe('au OptionSet', function()
set_hook('backup') set_hook('backup')
command('call setwinvar(1, "&backup", 1)') command('call setwinvar(1, "&backup", 1)')
expected_combination({'backup', 0, 0, '', 1, 'local', 'setlocal'}) expected_combination({'backup', false, false, '', true, 'local', 'setlocal'})
end) end)
it('should not trigger if the current window is different from the targeted window', function() it('should not trigger if the current window is different from the targeted window', function()
@@ -615,7 +616,7 @@ describe('au OptionSet', function()
local new_winnr = get_new_window_number() local new_winnr = get_new_window_number()
command('call setwinvar(' .. new_winnr .. ', "&cursorcolumn", 1)') command('call setwinvar(' .. new_winnr .. ', "&cursorcolumn", 1)')
-- expected_combination({'cursorcolumn', 0, 1, 'local', {winnr = new_winnr}}) -- expected_combination({'cursorcolumn', false, true, 'local', {winnr = new_winnr}})
expected_empty() expected_empty()
end) end)
end) end)
@@ -626,7 +627,7 @@ describe('au OptionSet', function()
nvim.set_option_value('autochdir', true, {scope='global'}) nvim.set_option_value('autochdir', true, {scope='global'})
eq(true, nvim.get_option_value('autochdir', {scope='global'})) eq(true, nvim.get_option_value('autochdir', {scope='global'}))
expected_combination({'autochdir', 0, '', 0, 1, 'global', 'setglobal'}) expected_combination({'autochdir', false, '', false, true, 'global', 'setglobal'})
end) end)
it('should trigger if a number option be set globally', function() it('should trigger if a number option be set globally', function()