aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2025-01-08 17:56:21 +0000
committerGitHub <noreply@github.com>2025-01-08 17:56:21 +0000
commitc4b658fed8d96a4c4098ce59b01b228ef0bda62e (patch)
tree50f10b101e425a04c646d5970eed88a4318f2069 /src
parent17b46d01e29443452ae8b607017f8f5c585d3f0a (diff)
parent6257270040bc5c61a489f7fb9d4102223c36cf89 (diff)
downloadrneovim-c4b658fed8d96a4c4098ce59b01b228ef0bda62e.tar.gz
rneovim-c4b658fed8d96a4c4098ce59b01b228ef0bda62e.tar.bz2
rneovim-c4b658fed8d96a4c4098ce59b01b228ef0bda62e.zip
Merge pull request #31112 from famiu/refactor/options/set_option_for
refactor(options): set option value for non-current context directly
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/deprecated.c10
-rw-r--r--src/nvim/api/options.c12
-rw-r--r--src/nvim/api/vim.c8
-rw-r--r--src/nvim/autocmd.c172
-rw-r--r--src/nvim/autocmd_defs.h22
-rw-r--r--src/nvim/diff.c4
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/insexpand.c6
-rw-r--r--src/nvim/option.c760
-rw-r--r--src/nvim/option_defs.h18
-rw-r--r--src/nvim/optionstr.c60
-rw-r--r--src/nvim/tag.c2
-rw-r--r--src/nvim/winfloat.c4
13 files changed, 528 insertions, 552 deletions
diff --git a/src/nvim/api/deprecated.c b/src/nvim/api/deprecated.c
index d5eddb74de..47a49436ab 100644
--- a/src/nvim/api/deprecated.c
+++ b/src/nvim/api/deprecated.c
@@ -649,8 +649,8 @@ static Object get_option_from(void *from, OptScope scope, String name, Error *er
OptVal value = NIL_OPTVAL;
if (option_has_scope(opt_idx, scope)) {
- value = get_option_value_for(opt_idx, scope == kOptScopeGlobal ? OPT_GLOBAL : OPT_LOCAL,
- scope, from, err);
+ value = get_option_value_from(opt_idx, option_ctx_from(scope, from),
+ scope == kOptScopeGlobal ? OPT_GLOBAL : OPT_LOCAL);
if (ERROR_SET(err)) {
return (Object)OBJECT_INIT;
}
@@ -701,7 +701,11 @@ static void set_option_to(uint64_t channel_id, void *to, OptScope scope, String
: ((scope == kOptScopeGlobal) ? OPT_GLOBAL : OPT_LOCAL);
WITH_SCRIPT_CONTEXT(channel_id, {
- set_option_value_for(name.data, opt_idx, optval, opt_flags, scope, to, err);
+ const char *errmsg
+ = set_option_value_for(opt_idx, optval, option_ctx_from(scope, to), opt_flags);
+ if (errmsg) {
+ api_set_error(err, kErrorTypeException, "%s", errmsg);
+ }
});
}
diff --git a/src/nvim/api/options.c b/src/nvim/api/options.c
index 64f8a35d54..2bbbdbbe8c 100644
--- a/src/nvim/api/options.c
+++ b/src/nvim/api/options.c
@@ -157,8 +157,8 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
void *from = NULL;
char *filetype = NULL;
- if (!validate_option_value_args(opts, name.data, &opt_idx, &opt_flags, &scope, &from,
- &filetype, err)) {
+ if (!validate_option_value_args(opts, name.data, &opt_idx, &opt_flags, &scope, &from, &filetype,
+ err)) {
return (Object)OBJECT_INIT;
}
@@ -182,7 +182,7 @@ Object nvim_get_option_value(String name, Dict(option) *opts, Error *err)
from = ftbuf;
}
- OptVal value = get_option_value_for(opt_idx, opt_flags, scope, from, err);
+ OptVal value = get_option_value_from(opt_idx, option_ctx_from(scope, from), opt_flags);
if (ftbuf != NULL) {
// restore curwin/curbuf and a few other things
@@ -257,7 +257,11 @@ void nvim_set_option_value(uint64_t channel_id, String name, Object value, Dict(
});
WITH_SCRIPT_CONTEXT(channel_id, {
- set_option_value_for(name.data, opt_idx, optval, opt_flags, scope, to, err);
+ const char *errmsg
+ = set_option_value_for(opt_idx, optval, option_ctx_from(scope, to), opt_flags);
+ if (errmsg) {
+ api_set_error(err, kErrorTypeException, "%s", errmsg);
+ }
});
}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index e3e69f4ff6..46e6b24c75 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -983,10 +983,10 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
if (scratch) {
- set_option_direct_for(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL, 0,
- kOptScopeBuf, buf);
- set_option_direct_for(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL, 0,
- kOptScopeBuf, buf);
+ set_option_direct_for(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"),
+ option_ctx_from(kOptScopeBuf, buf), OPT_LOCAL, 0);
+ set_option_direct_for(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"),
+ option_ctx_from(kOptScopeBuf, buf), OPT_LOCAL, 0);
assert(buf->b_ml.ml_mfp->mf_fd < 0); // ml_open() should not have opened swapfile already
buf->b_p_swf = false;
buf->b_p_ml = false;
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index eb7c8c2880..aab09de6b4 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -1251,56 +1251,82 @@ bool check_nomodeline(char **argp)
return true;
}
-/// Prepare for executing autocommands for (hidden) buffer `buf`.
-/// If the current buffer is not in any visible window, put it in a temporary
-/// floating window using an entry in `aucmd_win[]`.
-/// Set `curbuf` and `curwin` to match `buf`.
+/// Prepare for executing autocommands for (hidden) buffer `buf` on window `win`
+/// If the buffer of `win` is not `buf`, switch the buffer of `win` to `buf` temporarily.
///
-/// @param aco structure to save values in
-/// @param buf new curbuf
-void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
+/// @param aco Structure to save values in.
+/// @param buf New curbuf.
+/// @param win New curwin.
+void aucmd_prepbuf_win(aco_save_T *aco, buf_T *buf, win_T *win)
{
- win_T *win;
- bool need_append = true; // Append `aucmd_win` to the window list.
+ bool need_append = false; // Append `aucmd_win` to the window list.
+ int auc_idx = -1; // Index of aucmd_win[] to use. -1 if not using aucmd_win[].
- // Find a window that is for the new buffer
- if (buf == curbuf) { // be quick when buf is curbuf
- win = curwin;
- } else {
- win = NULL;
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if (wp->w_buffer == buf) {
- win = wp;
- break;
+ aco->save_curtab_handle = -1;
+ aco->save_buf_handle = -1;
+
+ if (win == NULL) {
+ // Window not provided. Find a window that is for the new buffer
+ if (buf == curbuf) { // be quick when buf is curbuf
+ win = curwin;
+ } else {
+ win = NULL;
+ FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
+ if (wp->w_buffer == buf) {
+ win = wp;
+ break;
+ }
}
}
- }
- // Allocate a window when needed.
- win_T *auc_win = NULL;
- int auc_idx = AUCMD_WIN_COUNT;
- if (win == NULL) {
- for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; auc_idx++) {
- if (!aucmd_win[auc_idx].auc_win_used) {
- break;
+ // Allocate a window when needed.
+ if (win == NULL) {
+ for (auc_idx = 0; auc_idx < AUCMD_WIN_COUNT; auc_idx++) {
+ if (!aucmd_win[auc_idx].auc_win_used) {
+ break;
+ }
+ }
+
+ if (auc_idx == AUCMD_WIN_COUNT) {
+ kv_push(aucmd_win_vec, ((aucmdwin_T){
+ .auc_win = NULL,
+ .auc_win_used = false,
+ }));
+ }
+
+ if (aucmd_win[auc_idx].auc_win == NULL) {
+ win_alloc_aucmd_win(auc_idx);
+ } else {
+ need_append = true;
}
+ win = aucmd_win[auc_idx].auc_win;
+ aucmd_win[auc_idx].auc_win_used = true;
}
+ } else {
+ tabpage_T *tp = win_find_tabpage(win);
- if (auc_idx == AUCMD_WIN_COUNT) {
- kv_push(aucmd_win_vec, ((aucmdwin_T){
- .auc_win = NULL,
- .auc_win_used = false,
- }));
+ // If the window is in another tab page, switch to that tab page temporarily.
+ if (tp != curtab) {
+ aco->save_curtab_handle = curtab->handle;
+ unuse_tabpage(curtab);
+ use_tabpage(tp);
}
+ }
- if (aucmd_win[auc_idx].auc_win == NULL) {
- win_alloc_aucmd_win(auc_idx);
- need_append = false;
+ // If the buffer of the window is not the target buffer, switch to it temporarily.
+ if (win->w_buffer != buf) {
+ if (auc_idx == -1) {
+ // No need to store old buffer for aucmd_win[].
+ aco->save_buf_handle = win->w_buffer->handle;
+ win->w_buffer->b_nwindows--;
}
- auc_win = aucmd_win[auc_idx].auc_win;
- aucmd_win[auc_idx].auc_win_used = true;
+
+ win->w_buffer = buf;
+ win->w_s = &buf->b_s;
+ buf->b_nwindows++;
}
+ aco->use_aucmd_win_idx = auc_idx;
aco->save_curwin_handle = curwin->handle;
aco->save_prevwin_handle = prevwin == NULL ? 0 : prevwin->handle;
aco->save_State = State;
@@ -1308,26 +1334,15 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
aco->save_prompt_insert = curbuf->b_prompt_insert;
}
- if (win != NULL) {
- // There is a window for "buf" in the current tab page, make it the
- // curwin. This is preferred, it has the least side effects (esp. if
- // "buf" is curbuf).
- aco->use_aucmd_win_idx = -1;
- curwin = win;
- } else {
- // There is no window for "buf", use "auc_win". To minimize the side
- // effects, insert it in the current tab page.
- // Anything related to a window (e.g., setting folds) may have
- // unexpected results.
- aco->use_aucmd_win_idx = auc_idx;
- auc_win->w_buffer = buf;
- auc_win->w_s = &buf->b_s;
- buf->b_nwindows++;
- win_init_empty(auc_win); // set cursor and topline to safe values
+ if (auc_idx >= 0) {
+ // There is no window for "buf", use "win". To minimize the side effects, insert it in the
+ // current tab page. Anything related to a window (e.g., setting folds) may have unexpected
+ // results.
+ win_init_empty(win); // Set cursor and topline to safe values.
- // Make sure w_localdir, tp_localdir and globaldir are NULL to avoid a
- // chdir() in win_enter_ext().
- XFREE_CLEAR(auc_win->w_localdir);
+ // Make sure w_localdir, tp_localdir and globaldir are NULL to avoid a chdir() in
+ // win_enter_ext().
+ XFREE_CLEAR(win->w_localdir);
aco->tp_localdir = curtab->tp_localdir;
curtab->tp_localdir = NULL;
aco->globaldir = globaldir;
@@ -1335,30 +1350,43 @@ void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
block_autocmds(); // We don't want BufEnter/WinEnter autocommands.
if (need_append) {
- win_append(lastwin, auc_win, NULL);
- pmap_put(int)(&window_handles, auc_win->handle, auc_win);
- win_config_float(auc_win, auc_win->w_config);
+ win_append(lastwin, win, NULL);
+ pmap_put(int)(&window_handles, win->handle, win);
+ win_config_float(win, win->w_config);
}
// Prevent chdir() call in win_enter_ext(), through do_autochdir()
const int save_acd = p_acd;
p_acd = false;
- // no redrawing and don't set the window title
+ // No redrawing and don't set the window title
RedrawingDisabled++;
- win_enter(auc_win, false);
+ win_enter(win, false);
RedrawingDisabled--;
p_acd = save_acd;
unblock_autocmds();
- curwin = auc_win;
}
+
+ curwin = win;
curbuf = buf;
aco->new_curwin_handle = curwin->handle;
set_bufref(&aco->new_curbuf, curbuf);
- // disable the Visual area, the position may be invalid in another buffer
+ // Disable the Visual area, the position may be invalid in another buffer
aco->save_VIsual_active = VIsual_active;
VIsual_active = false;
}
+/// Prepare for executing autocommands for (hidden) buffer `buf`.
+/// If the current buffer is not in any visible window, put it in a temporary
+/// floating window using an entry in `aucmd_win[]`.
+/// Set `curbuf` and `curwin` to match `buf`.
+///
+/// @param aco structure to save values in
+/// @param buf new curbuf
+void aucmd_prepbuf(aco_save_T *aco, buf_T *buf)
+{
+ aucmd_prepbuf_win(aco, buf, NULL);
+}
+
/// Cleanup after executing autocommands for a (hidden) buffer.
/// Restore the window as it was (if possible).
///
@@ -1447,6 +1475,19 @@ win_found:
curwin->w_topfill = 0;
}
} else {
+ // Restore old buffer of new window if it was changed.
+ if (aco->save_buf_handle != -1) {
+ win_T *new_win = win_find_by_handle(aco->new_curwin_handle);
+ buf_T *new_win_buf = handle_get_buffer(aco->save_buf_handle);
+
+ if (new_win != NULL && new_win_buf != NULL) {
+ new_win->w_buffer->b_nwindows--;
+ new_win->w_buffer = new_win_buf;
+ new_win->w_s = &new_win_buf->b_s;
+ new_win_buf->b_nwindows++;
+ }
+ }
+
// Restore curwin. Use the window ID, a window may have been closed
// and the memory re-used for another one.
win_T *const save_curwin = win_find_by_handle(aco->save_curwin_handle);
@@ -1482,6 +1523,13 @@ win_found:
if (VIsual_active) {
check_pos(curbuf, &VIsual);
}
+
+ // Switch back to the original tab page if it was switched.
+ if (aco->save_curtab_handle != -1) {
+ tabpage_T *save_curtab = handle_get_tabpage(aco->save_curtab_handle);
+ unuse_tabpage(curtab);
+ use_tabpage(save_curtab);
+ }
}
/// Execute autocommands for "event" and file name "fname".
diff --git a/src/nvim/autocmd_defs.h b/src/nvim/autocmd_defs.h
index cba947e85f..777ee7b87a 100644
--- a/src/nvim/autocmd_defs.h
+++ b/src/nvim/autocmd_defs.h
@@ -14,16 +14,18 @@
/// Struct to save values in before executing autocommands for a buffer that is
/// not the current buffer.
typedef struct {
- int use_aucmd_win_idx; ///< index in aucmd_win[] if >= 0
- handle_T save_curwin_handle; ///< ID of saved curwin
- handle_T new_curwin_handle; ///< ID of new curwin
- handle_T save_prevwin_handle; ///< ID of saved prevwin
- bufref_T new_curbuf; ///< new curbuf
- char *tp_localdir; ///< saved value of tp_localdir
- char *globaldir; ///< saved value of globaldir
- bool save_VIsual_active; ///< saved VIsual_active
- int save_State; ///< saved State
- int save_prompt_insert; ///< saved b_prompt_insert
+ int use_aucmd_win_idx; ///< index in aucmd_win[] if >= 0
+ handle_T save_curwin_handle; ///< ID of saved curwin
+ handle_T save_curtab_handle; ///< ID of saved curtab. -1 if not switched.
+ handle_T new_curwin_handle; ///< ID of new curwin
+ handle_T save_buf_handle; ///< ID of saved buffer of new curwin. -1 if not switched.
+ handle_T save_prevwin_handle; ///< ID of saved prevwin
+ bufref_T new_curbuf; ///< new curbuf
+ char *tp_localdir; ///< saved value of tp_localdir
+ char *globaldir; ///< saved value of globaldir
+ bool save_VIsual_active; ///< saved VIsual_active
+ int save_State; ///< saved State
+ int save_prompt_insert; ///< saved b_prompt_insert
} aco_save_T;
typedef struct {
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index bd98a31a71..ebeb9ba088 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1391,8 +1391,8 @@ void diff_win_options(win_T *wp, bool addbuf)
}
wp->w_p_fdm_save = xstrdup(wp->w_p_fdm);
}
- set_option_direct_for(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("diff"), OPT_LOCAL, 0,
- kOptScopeWin, wp);
+ set_option_direct_for(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("diff"),
+ option_ctx_from(kOptScopeWin, wp), OPT_LOCAL, 0);
if (!wp->w_p_diff) {
wp->w_p_fen_save = wp->w_p_fen;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 6f9f0f07c9..ceb3a074b4 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -5294,7 +5294,7 @@ static char *findfunc_find_file(char *findarg, size_t findarg_len, int count)
/// Returns NULL on success and an error message on failure.
const char *did_set_findfunc(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
int retval;
if (args->os_flags & OPT_LOCAL) {
diff --git a/src/nvim/insexpand.c b/src/nvim/insexpand.c
index 9b77644085..053d97fd64 100644
--- a/src/nvim/insexpand.c
+++ b/src/nvim/insexpand.c
@@ -2401,7 +2401,7 @@ static void copy_global_to_buflocal_cb(Callback *globcb, Callback *bufcb)
/// lambda expression.
const char *did_set_completefunc(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
if (option_set_callback_func(buf->b_p_cfu, &cfu_cb) == FAIL) {
return e_invarg;
}
@@ -2422,7 +2422,7 @@ void set_buflocal_cfu_callback(buf_T *buf)
/// lambda expression.
const char *did_set_omnifunc(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
if (option_set_callback_func(buf->b_p_ofu, &ofu_cb) == FAIL) {
return e_invarg;
}
@@ -2443,7 +2443,7 @@ void set_buflocal_ofu_callback(buf_T *buf)
/// lambda expression.
const char *did_set_thesaurusfunc(optset_T *args FUNC_ATTR_UNUSED)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
int retval;
if (args->os_flags & OPT_LOCAL) {
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 551ea0be20..2b102fe1bb 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1324,7 +1324,8 @@ static void do_one_set_option(int opt_flags, char **argp, bool *did_show, char *
return;
}
- *errmsg = set_option(opt_idx, newval, opt_flags, 0, false, op == OP_NONE, errbuf, errbuflen);
+ *errmsg = set_option_for(opt_idx, newval, option_ctx(), opt_flags, 0, false,
+ op == OP_NONE, errbuf, errbuflen);
}
/// Parse 'arg' for option settings.
@@ -1844,7 +1845,7 @@ void set_option_sctx(OptIndex opt_idx, int opt_flags, sctx_T script_ctx)
/// Apply the OptionSet autocommand.
static void apply_optionset_autocmd(OptIndex opt_idx, int opt_flags, OptVal oldval, OptVal oldval_g,
- OptVal oldval_l, OptVal newval, const char *errmsg)
+ OptVal oldval_l, OptVal newval, OptCtx ctx, const char *errmsg)
{
// Don't do this while starting up, failure or recursively.
if (starting || errmsg != NULL || *get_vim_var_str(VV_OPTION_TYPE) != NUL) {
@@ -1878,14 +1879,18 @@ static void apply_optionset_autocmd(OptIndex opt_idx, int opt_flags, OptVal oldv
set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1);
set_vim_var_tv(VV_OPTION_OLDLOCAL, &oldval_tv);
}
- apply_autocmds(EVENT_OPTIONSET, options[opt_idx].fullname, NULL, false, NULL);
+
+ WITH_AUCMD_CONTEXT(ctx, {
+ apply_autocmds(EVENT_OPTIONSET, options[opt_idx].fullname, NULL, false, NULL);
+ });
+
reset_v_option_vars();
}
/// Process the updated 'arabic' option value.
static const char *did_set_arabic(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
const char *errmsg = NULL;
if (win->w_p_arab) {
@@ -1954,7 +1959,7 @@ static const char *did_set_autochdir(optset_T *args FUNC_ATTR_UNUSED)
/// Process the updated 'binary' option value.
static const char *did_set_binary(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
// when 'bin' is set also set some other options
set_options_bin((int)args->os_oldval.boolean, buf->b_p_bin, args->os_flags);
@@ -1966,7 +1971,7 @@ static const char *did_set_binary(optset_T *args)
/// Process the updated 'buflisted' option value.
static const char *did_set_buflisted(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
// when 'buflisted' changes, trigger autocommands
if (args->os_oldval.boolean != buf->b_p_bl) {
@@ -2000,7 +2005,7 @@ static const char *did_set_cmdheight(optset_T *args)
/// Process the updated 'diff' option value.
static const char *did_set_diff(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
// May add or remove the buffer from the list of diff buffers.
diff_buf_adjust(win);
if (foldmethodIsDiff(win)) {
@@ -2021,7 +2026,7 @@ static const char *did_set_eof_eol_fixeol_bomb(optset_T *args FUNC_ATTR_UNUSED)
/// Process the updated 'equalalways' option value.
static const char *did_set_equalalways(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
if (p_ea && !args->os_oldval.boolean) {
win_equal(win, false, 0);
}
@@ -2039,7 +2044,7 @@ static const char *did_set_foldlevel(optset_T *args FUNC_ATTR_UNUSED)
/// Process the new 'foldminlines' option value.
static const char *did_set_foldminlines(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
foldUpdateAll(win);
return NULL;
}
@@ -2047,7 +2052,7 @@ static const char *did_set_foldminlines(optset_T *args)
/// Process the new 'foldnestmax' option value.
static const char *did_set_foldnestmax(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
if (foldmethodIsSyntax(win) || foldmethodIsIndent(win)) {
foldUpdateAll(win);
}
@@ -2176,7 +2181,7 @@ static const char *did_set_lines_or_columns(optset_T *args)
/// Process the updated 'lisp' option value.
static const char *did_set_lisp(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
// When 'lisp' option changes include/exclude '-' in keyword characters.
buf_init_chartab(buf, false); // ignore errors
return NULL;
@@ -2194,7 +2199,7 @@ static const char *did_set_modifiable(optset_T *args FUNC_ATTR_UNUSED)
/// Process the updated 'modified' option value.
static const char *did_set_modified(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
if (!args->os_newval.boolean) {
save_file_ff(buf); // Buffer is unchanged
}
@@ -2206,7 +2211,7 @@ static const char *did_set_modified(optset_T *args)
/// Process the updated 'number' or 'relativenumber' option value.
static const char *did_set_number_relativenumber(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
if (*win->w_p_stc != NUL) {
// When 'relativenumber'/'number' is changed and 'statuscolumn' is set, reset width.
win->w_nrwidth_line_count = 0;
@@ -2218,7 +2223,7 @@ static const char *did_set_number_relativenumber(optset_T *args)
/// Process the new 'numberwidth' option value.
static const char *did_set_numberwidth(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
win->w_nrwidth_line_count = 0; // trigger a redraw
return NULL;
@@ -2356,7 +2361,7 @@ static const char *did_set_paste(optset_T *args FUNC_ATTR_UNUSED)
/// Process the updated 'previewwindow' option value.
static const char *did_set_previewwindow(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
if (!win->w_p_pvw) {
return NULL;
@@ -2388,7 +2393,7 @@ static const char *did_set_pumblend(optset_T *args FUNC_ATTR_UNUSED)
/// Process the updated 'readonly' option value.
static const char *did_set_readonly(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
// when 'readonly' is reset globally, also reset readonlymode
if (!buf->b_p_ro && (args->os_flags & OPT_LOCAL) == 0) {
@@ -2408,7 +2413,7 @@ static const char *did_set_readonly(optset_T *args)
/// Process the new 'scrollback' option value.
static const char *did_set_scrollback(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
OptInt old_value = args->os_oldval.number;
OptInt value = args->os_newval.number;
@@ -2422,7 +2427,7 @@ static const char *did_set_scrollback(optset_T *args)
/// Process the updated 'scrollbind' option value.
static const char *did_set_scrollbind(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
// when 'scrollbind' is set: snapshot the current position to avoid a jump
// at the end of normal_cmd()
@@ -2459,8 +2464,8 @@ static const char *did_set_shellslash(optset_T *args FUNC_ATTR_UNUSED)
/// Process the new 'shiftwidth' or the 'tabstop' option value.
static const char *did_set_shiftwidth_tabstop(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
- win_T *win = (win_T *)args->os_win;
+ buf_T *buf = args->os_ctx.buf;
+ win_T *win = args->os_ctx.win;
OptInt *pp = (OptInt *)args->os_varp;
if (foldmethodIsIndent(win)) {
@@ -2486,7 +2491,7 @@ static const char *did_set_showtabline(optset_T *args FUNC_ATTR_UNUSED)
/// Process the updated 'smoothscroll' option value.
static const char *did_set_smoothscroll(optset_T *args FUNC_ATTR_UNUSED)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
if (!win->w_p_sms) {
win->w_skipcol = 0;
}
@@ -2497,7 +2502,7 @@ static const char *did_set_smoothscroll(optset_T *args FUNC_ATTR_UNUSED)
/// Process the updated 'spell' option value.
static const char *did_set_spell(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
if (win->w_p_spell) {
return parse_spelllang(win);
}
@@ -2508,7 +2513,7 @@ static const char *did_set_spell(optset_T *args)
/// Process the updated 'swapfile' option value.
static const char *did_set_swapfile(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
// when 'swf' is set, create swapfile, when reset remove swapfile
if (buf->b_p_swf && p_uc) {
ml_open_file(buf); // create the swap file
@@ -2553,7 +2558,7 @@ static const char *did_set_titlelen(optset_T *args)
/// Process the updated 'undofile' option value.
static const char *did_set_undofile(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
// Only take action when the option was set.
if (!buf->b_p_udf && !p_udf) {
@@ -2604,7 +2609,7 @@ const char *did_set_buflocal_undolevels(buf_T *buf, OptInt value, OptInt old_val
/// Process the new 'undolevels' option value.
static const char *did_set_undolevels(optset_T *args)
{
- buf_T *buf = (buf_T *)args->os_buf;
+ buf_T *buf = args->os_ctx.buf;
OptInt *pp = (OptInt *)args->os_varp;
if (pp == &p_ul) { // global 'undolevels'
@@ -2645,7 +2650,7 @@ static const char *did_set_wildchar(optset_T *args)
/// Process the new 'winblend' option value.
static const char *did_set_winblend(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
OptInt old_value = args->os_oldval.number;
OptInt value = args->os_newval.number;
@@ -2694,7 +2699,7 @@ static const char *did_set_winwidth(optset_T *args)
/// Process the updated 'wrap' option value.
static const char *did_set_wrap(optset_T *args)
{
- win_T *win = (win_T *)args->os_win;
+ win_T *win = args->os_ctx.win;
// Set w_leftcol or w_skipcol to zero.
if (win->w_p_wrap) {
win->w_leftcol = 0;
@@ -3143,12 +3148,6 @@ static OptValType option_get_type(const OptIndex opt_idx)
OptVal optval_from_varp(OptIndex opt_idx, void *varp)
FUNC_ATTR_NONNULL_ARG(2)
{
- // Special case: 'modified' is b_changed, but we also want to consider it set when 'ff' or 'fenc'
- // changed.
- if ((int *)varp == &curbuf->b_changed) {
- return BOOLEAN_OPTVAL(curbufIsChanged());
- }
-
if (option_is_multitype(opt_idx)) {
// Multitype options are stored as OptVal.
return *(OptVal *)varp;
@@ -3381,21 +3380,37 @@ uint32_t get_option_flags(OptIndex opt_idx)
/// Gets the value for an option.
///
/// @param opt_idx Option index in options[] table.
+/// @param ctx Context to get the option value from.
/// @param opt_flags Option flags (can be OPT_LOCAL, OPT_GLOBAL or a combination).
///
/// @return [allocated] Option value. Returns NIL_OPTVAL for invalid option index.
-OptVal get_option_value(OptIndex opt_idx, int opt_flags)
+OptVal get_option_value_from(OptIndex opt_idx, OptCtx ctx, int opt_flags)
{
if (opt_idx == kOptInvalid) { // option not in the options[] table.
return NIL_OPTVAL;
}
- vimoption_T *opt = &options[opt_idx];
- void *varp = get_varp_scope(opt, opt_flags);
+ // Special case: 'modified' is b_changed, but we also want to consider it set when 'ff' or 'fenc'
+ // changed.
+ if (opt_idx == kOptModified) {
+ return BOOLEAN_OPTVAL(bufIsChanged(ctx.buf));
+ }
+ void * const varp = get_varp_scope_from(&options[opt_idx], opt_flags, ctx);
return optval_copy(optval_from_varp(opt_idx, varp));
}
+/// Gets the value for an option in the current context.
+///
+/// @param opt_idx Option index in options[] table.
+/// @param opt_flags Option flags (can be OPT_LOCAL, OPT_GLOBAL or a combination).
+///
+/// @return [allocated] Option value. Returns NIL_OPTVAL for invalid option index.
+OptVal get_option_value(OptIndex opt_idx, int opt_flags)
+{
+ return get_option_value_from(opt_idx, option_ctx(), opt_flags);
+}
+
/// Return information for option at 'opt_idx'
vimoption_T *get_option(OptIndex opt_idx)
{
@@ -3464,6 +3479,8 @@ static bool is_option_local_value_unset(OptIndex opt_idx)
/// @param opt_idx Index in options[] table. Must not be kOptInvalid.
/// @param[in] varp Option variable pointer, cannot be NULL.
/// @param old_value Old option value.
+/// @param new_value New option value.
+/// @param ctx Context in which the option is set.
/// @param opt_flags Option flags (can be OPT_LOCAL, OPT_GLOBAL or a combination).
/// @param set_sid Script ID. Special values:
/// 0: Use current script ID.
@@ -3475,8 +3492,9 @@ static bool is_option_local_value_unset(OptIndex opt_idx)
///
/// @return NULL on success, an untranslated error message on error.
static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value, OptVal new_value,
- int opt_flags, scid_T set_sid, const bool direct,
- const bool value_replaced, char *errbuf, size_t errbuflen)
+ OptCtx ctx, int opt_flags, scid_T set_sid, const bool direct,
+ const bool value_replaced, char *errbuf, // NOLINT(readability-non-const-parameter)
+ size_t errbuflen)
{
vimoption_T *opt = &options[opt_idx];
const char *errmsg = NULL;
@@ -3495,8 +3513,7 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value
.os_restore_chartab = false,
.os_errbuf = errbuf,
.os_errbuflen = errbuflen,
- .os_buf = curbuf,
- .os_win = curwin
+ .os_ctx = ctx,
};
if (direct) {
@@ -3533,7 +3550,7 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value
set_option_varp(opt_idx, varp, old_value, true);
// When resetting some values, need to act on it.
if (restore_chartab) {
- buf_init_chartab(curbuf, true);
+ buf_init_chartab(ctx.buf, true);
}
return errmsg;
@@ -3564,12 +3581,12 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value
if (option_is_global_local(opt_idx)) {
// Global option with local value set to use global value.
// Free the local value and clear it.
- void *varp_local = get_varp_scope(opt, OPT_LOCAL);
+ void *varp_local = get_varp_scope_from(opt, OPT_LOCAL, ctx);
OptVal local_unset_value = get_option_unset_value(opt_idx);
set_option_varp(opt_idx, varp_local, optval_copy(local_unset_value), true);
} else {
// May set global value for local option.
- void *varp_global = get_varp_scope(opt, OPT_GLOBAL);
+ void *varp_global = get_varp_scope_from(opt, OPT_GLOBAL, ctx);
set_option_varp(opt_idx, varp_global, optval_copy(new_value), true);
}
}
@@ -3580,17 +3597,23 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value
}
// Trigger the autocommand only after setting the flags.
- if (varp == &curbuf->b_p_syn) {
- do_syntax_autocmd(curbuf, value_changed);
- } else if (varp == &curbuf->b_p_ft) {
+ if (varp == &ctx.buf->b_p_syn) {
+ WITH_AUCMD_CONTEXT(ctx, {
+ do_syntax_autocmd(ctx.buf, value_changed);
+ });
+ } else if (varp == &ctx.buf->b_p_ft) {
// 'filetype' is set, trigger the FileType autocommand
// Skip this when called from a modeline
// Force autocmd when the filetype was changed
if (!(opt_flags & OPT_MODELINE) || value_changed) {
- do_filetype_autocmd(curbuf, value_changed);
+ WITH_AUCMD_CONTEXT(ctx, {
+ do_filetype_autocmd(ctx.buf, value_changed);
+ });
}
- } else if (varp == &curwin->w_s->b_p_spl) {
- do_spelllang_source(curwin);
+ } else if (varp == &ctx.win->w_s->b_p_spl) {
+ WITH_AUCMD_CONTEXT(ctx, {
+ do_spelllang_source(ctx.win);
+ });
}
// In case 'ruler' or 'showcmd' or 'columns' or 'ls' changed.
@@ -3598,25 +3621,25 @@ static const char *did_set_option(OptIndex opt_idx, void *varp, OptVal old_value
if (varp == &p_mouse) {
setmouse(); // in case 'mouse' changed
- } else if ((varp == &p_flp || varp == &(curbuf->b_p_flp)) && curwin->w_briopt_list) {
+ } else if ((varp == &p_flp || varp == &(ctx.buf->b_p_flp)) && ctx.win->w_briopt_list) {
// Changing Formatlistpattern when briopt includes the list setting:
// redraw
redraw_all_later(UPD_NOT_VALID);
- } else if (varp == &p_wbr || varp == &(curwin->w_p_wbr)) {
+ } else if (varp == &p_wbr || varp == &(ctx.win->w_p_wbr)) {
// add / remove window bars for 'winbar'
set_winbar(true);
}
- if (curwin->w_curswant !