aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorFamiu Haque <famiuhaque@proton.me>2024-02-03 12:57:03 +0600
committerFamiu Haque <famiuhaque@proton.me>2024-03-21 15:41:14 +0600
commit2214f9c19daa46a1fc37bcc14c017c092894a506 (patch)
tree5fd933cd67d5d868a4c876dcc20af263e3d4ddfc /src
parent5aa8c02a9de5c1efa1e2dee60af1ecf58f452d19 (diff)
downloadrneovim-2214f9c19daa46a1fc37bcc14c017c092894a506.tar.gz
rneovim-2214f9c19daa46a1fc37bcc14c017c092894a506.tar.bz2
rneovim-2214f9c19daa46a1fc37bcc14c017c092894a506.zip
refactor(options): remove `set_string_option_direct()`
Problem: `set_string_option_direct()` contains a separate codepath specifically for setting string options. Not only is that unnecessary code duplication, but it's also limited to only string options. Solution: Replace `set_string_option_direct()` with `set_option_direct()` which calls `set_option()` under the hood. This reduces code duplication and allows directly setting an option of any type.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/vim.c6
-rw-r--r--src/nvim/autocmd.c4
-rw-r--r--src/nvim/diff.c3
-rw-r--r--src/nvim/ex_cmds.c8
-rw-r--r--src/nvim/ex_docmd.c4
-rw-r--r--src/nvim/ex_getln.c4
-rw-r--r--src/nvim/fileio.c4
-rw-r--r--src/nvim/help.c6
-rw-r--r--src/nvim/indent.c2
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/option.c71
-rw-r--r--src/nvim/optionstr.c107
-rw-r--r--src/nvim/popupmenu.c3
-rw-r--r--src/nvim/quickfix.c2
-rw-r--r--src/nvim/statusline.c2
15 files changed, 93 insertions, 135 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 43bf4eaf31..2b3ebb7bfb 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -988,8 +988,10 @@ Buffer nvim_create_buf(Boolean listed, Boolean scratch, Error *err)
buf_copy_options(buf, BCO_ENTER | BCO_NOHELP);
if (scratch) {
- set_string_option_direct_in_buf(buf, kOptBufhidden, "hide", OPT_LOCAL, 0);
- set_string_option_direct_in_buf(buf, kOptBuftype, "nofile", OPT_LOCAL, 0);
+ set_option_direct_for(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("hide"), OPT_LOCAL, 0, kOptReqBuf,
+ buf);
+ set_option_direct_for(kOptBuftype, STATIC_CSTR_AS_OPTVAL("nofile"), OPT_LOCAL, 0, kOptReqBuf,
+ buf);
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 285ef538b9..00cfef23c7 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -712,7 +712,7 @@ char *au_event_disable(char *what)
} else {
STRCAT(new_ei, what);
}
- set_string_option_direct(kOptEventignore, new_ei, 0, SID_NONE);
+ set_option_direct(kOptEventignore, CSTR_AS_OPTVAL(new_ei), 0, SID_NONE);
xfree(new_ei);
return save_ei;
}
@@ -720,7 +720,7 @@ char *au_event_disable(char *what)
void au_event_restore(char *old_ei)
{
if (old_ei != NULL) {
- set_string_option_direct(kOptEventignore, old_ei, 0, SID_NONE);
+ set_option_direct(kOptEventignore, CSTR_AS_OPTVAL(old_ei), 0, SID_NONE);
xfree(old_ei);
}
}
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index 39d9e9e978..ea846b46ec 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -1438,7 +1438,8 @@ void diff_win_options(win_T *wp, bool addbuf)
}
wp->w_p_fdm_save = xstrdup(wp->w_p_fdm);
}
- set_string_option_direct_in_win(wp, kOptFoldmethod, "diff", OPT_LOCAL, 0);
+ set_option_direct_for(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("diff"), OPT_LOCAL, 0, kOptReqWin,
+ wp);
if (!wp->w_p_diff) {
wp->w_p_fen_save = wp->w_p_fen;
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c
index 7c49189602..dd30cdbba4 100644
--- a/src/nvim/ex_cmds.c
+++ b/src/nvim/ex_cmds.c
@@ -4294,7 +4294,7 @@ skip:
// Show 'inccommand' preview if there are matched lines.
if (cmdpreview_ns > 0 && !aborting()) {
if (got_quit || profile_passed_limit(timeout)) { // Too slow, disable.
- set_string_option_direct(kOptInccommand, "", 0, SID_NONE);
+ set_option_direct(kOptInccommand, STATIC_CSTR_AS_OPTVAL(""), 0, SID_NONE);
} else if (*p_icm != NUL && pat != NULL) {
if (pre_hl_id == 0) {
pre_hl_id = syn_check_group(S_LEN("Substitute"));
@@ -4574,7 +4574,7 @@ bool prepare_tagpreview(bool undo_sync)
RESET_BINDING(curwin); // don't take over 'scrollbind' and 'cursorbind'
curwin->w_p_diff = false; // no 'diff'
- set_string_option_direct(kOptFoldcolumn, "0", 0, SID_NONE); // no 'foldcolumn'
+ set_option_direct(kOptFoldcolumn, STATIC_CSTR_AS_OPTVAL("0"), 0, SID_NONE); // no 'foldcolumn'
return true;
}
@@ -4593,7 +4593,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
buf_T *cmdpreview_buf = NULL;
// disable file info message
- set_string_option_direct(kOptShortmess, "F", 0, SID_NONE);
+ set_option_direct(kOptShortmess, STATIC_CSTR_AS_OPTVAL("F"), 0, SID_NONE);
// Place cursor on nearest matching line, to undo do_sub() cursor placement.
for (size_t i = 0; i < lines.subresults.size; i++) {
@@ -4694,7 +4694,7 @@ static int show_sub(exarg_T *eap, pos_T old_cusr, PreviewLines *preview_lines, i
xfree(str);
- set_string_option_direct(kOptShortmess, save_shm_p, 0, SID_NONE);
+ set_option_direct(kOptShortmess, CSTR_AS_OPTVAL(save_shm_p), 0, SID_NONE);
xfree(save_shm_p);
return preview ? 2 : 1;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index 6db72ff2d1..2454c77334 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -2697,7 +2697,7 @@ static void apply_cmdmod(cmdmod_T *cmod)
// Set 'eventignore' to "all".
// First save the existing option value for restoring it later.
cmod->cmod_save_ei = xstrdup(p_ei);
- set_string_option_direct(kOptEventignore, "all", 0, SID_NONE);
+ set_option_direct(kOptEventignore, STATIC_CSTR_AS_OPTVAL("all"), 0, SID_NONE);
}
}
@@ -2717,7 +2717,7 @@ void undo_cmdmod(cmdmod_T *cmod)
if (cmod->cmod_save_ei != NULL) {
// Restore 'eventignore' to the value before ":noautocmd".
- set_string_option_direct(kOptEventignore, cmod->cmod_save_ei, 0, SID_NONE);
+ set_option_direct(kOptEventignore, CSTR_AS_OPTVAL(cmod->cmod_save_ei), 0, SID_NONE);
free_string_option(cmod->cmod_save_ei);
cmod->cmod_save_ei = NULL;
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index e5d82cc126..a4501a31c2 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -919,7 +919,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear
need_wait_return = false;
}
- set_string_option_direct(kOptInccommand, s->save_p_icm, 0, SID_NONE);
+ set_option_direct(kOptInccommand, CSTR_AS_OPTVAL(s->save_p_icm), 0, SID_NONE);
State = s->save_State;
if (cmdpreview != save_cmdpreview) {
cmdpreview = save_cmdpreview; // restore preview state
@@ -2554,7 +2554,7 @@ static bool cmdpreview_may_show(CommandLineState *s)
// Open preview buffer if inccommand=split.
if (icm_split && (cmdpreview_buf = cmdpreview_open_buf()) == NULL) {
// Failed to create preview buffer, so disable preview.
- set_string_option_direct(kOptInccommand, "nosplit", 0, SID_NONE);
+ set_option_direct(kOptInccommand, STATIC_CSTR_AS_OPTVAL("nosplit"), 0, SID_NONE);
icm_split = false;
}
// Setup preview namespace if it's not already set.
diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c
index f032604a59..6b50b031a3 100644
--- a/src/nvim/fileio.c
+++ b/src/nvim/fileio.c
@@ -1620,7 +1620,7 @@ failed:
save_file_ff(curbuf);
// If editing a new file: set 'fenc' for the current buffer.
// Also for ":read ++edit file".
- set_string_option_direct(kOptFileencoding, fenc, OPT_LOCAL, 0);
+ set_option_direct(kOptFileencoding, CSTR_AS_OPTVAL(fenc), OPT_LOCAL, 0);
}
if (fenc_alloced) {
xfree(fenc);
@@ -1968,7 +1968,7 @@ void set_forced_fenc(exarg_T *eap)
}
char *fenc = enc_canonize(eap->cmd + eap->force_enc);
- set_string_option_direct(kOptFileencoding, fenc, OPT_LOCAL, 0);
+ set_option_direct(kOptFileencoding, CSTR_AS_OPTVAL(fenc), OPT_LOCAL, 0);
xfree(fenc);
}
diff --git a/src/nvim/help.c b/src/nvim/help.c
index 779772cedf..e9f67ca3e4 100644
--- a/src/nvim/help.c
+++ b/src/nvim/help.c
@@ -613,7 +613,7 @@ void cleanup_help_tags(int num_file, char **file)
void prepare_help_buffer(void)
{
curbuf->b_help = true;
- set_string_option_direct(kOptBuftype, "help", OPT_LOCAL, 0);
+ set_option_direct(kOptBuftype, STATIC_CSTR_AS_OPTVAL("help"), OPT_LOCAL, 0);
// Always set these options after jumping to a help tag, because the
// user may have an autocommand that gets in the way.
@@ -622,13 +622,13 @@ void prepare_help_buffer(void)
// Only set it when needed, buf_init_chartab() is some work.
char *p = "!-~,^*,^|,^\",192-255";
if (strcmp(curbuf->b_p_isk, p) != 0) {
- set_string_option_direct(kOptIskeyword, p, OPT_LOCAL, 0);
+ set_option_direct(kOptIskeyword, CSTR_AS_OPTVAL(p), OPT_LOCAL, 0);
check_buf_options(curbuf);
buf_init_chartab(curbuf, false);
}
// Don't use the global foldmethod.
- set_string_option_direct(kOptFoldmethod, "manual", OPT_LOCAL, 0);
+ set_option_direct(kOptFoldmethod, STATIC_CSTR_AS_OPTVAL("manual"), OPT_LOCAL, 0);
curbuf->b_p_ts = 8; // 'tabstop' is 8.
curwin->w_p_list = false; // No list mode.
diff --git a/src/nvim/indent.c b/src/nvim/indent.c
index 6cbb86866e..d477b466d7 100644
--- a/src/nvim/indent.c
+++ b/src/nvim/indent.c
@@ -1105,7 +1105,7 @@ void ex_retab(exarg_T *eap)
colnr_T *old_vts_ary = curbuf->b_p_vts_array;
if (tabstop_count(old_vts_ary) > 0 || tabstop_count(new_vts_array) > 1) {
- set_string_option_direct(kOptVartabstop, new_ts_str, OPT_LOCAL, 0);
+ set_option_direct(kOptVartabstop, CSTR_AS_OPTVAL(new_ts_str), OPT_LOCAL, 0);
curbuf->b_p_vts_array = new_vts_array;
xfree(old_vts_ary);
} else {
diff --git a/src/nvim/main.c b/src/nvim/main.c
index ea189aaa0c..361d43393b 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -1573,7 +1573,7 @@ static void handle_quickfix(mparm_T *paramp)
{
if (paramp->edit_type == EDIT_QF) {
if (paramp->use_ef != NULL) {
- set_string_option_direct(kOptErrorfile, paramp->use_ef, 0, SID_CARG);
+ set_option_direct(kOptErrorfile, CSTR_AS_OPTVAL(paramp->use_ef), 0, SID_CARG);
}
vim_snprintf(IObuff, IOSIZE, "cfile %s", p_ef);
if (qf_init(NULL, p_ef, p_efm, true, IObuff, p_menc) < 0) {
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 5fb93f9801..73a5af5520 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -430,10 +430,9 @@ static void set_option_default(const OptIndex opt_idx, int opt_flags)
uint32_t flags = opt->flags;
if (varp != NULL) { // skip hidden option, nothing to do for it
if (option_has_type(opt_idx, kOptValTypeString)) {
- // Use set_string_option_direct() for local options to handle freeing and allocating the
- // value.
+ // Use set_option_direct() for local options to handle freeing and allocating the value.
if (opt->indir != PV_NONE) {
- set_string_option_direct(opt_idx, opt->def_val.string, opt_flags, 0);
+ set_option_direct(opt_idx, CSTR_AS_OPTVAL(opt->def_val.string), opt_flags, 0);
} else {
if (flags & P_ALLOCED) {
free_string_option(*(char **)(varp));
@@ -765,7 +764,7 @@ static char *stropt_get_default_val(OptIndex opt_idx, uint64_t flags)
}
/// Copy the new string value into allocated memory for the option.
-/// Can't use set_string_option_direct(), because we need to remove the backslashes.
+/// Can't use set_option_direct(), because we need to remove the backslashes.
static char *stropt_copy_value(char *origval, char **argp, set_op_T op,
uint32_t flags FUNC_ATTR_UNUSED)
{
@@ -3762,6 +3761,68 @@ static const char *set_option(const OptIndex opt_idx, void *varp, OptVal value,
return errmsg;
}
+/// Set option value directly, without processing any side effects.
+///
+/// @param opt_idx Option index in options[] table.
+/// @param value Option value.
+/// @param opt_flags Option flags.
+/// @param set_sid Script ID. Special values:
+/// 0: Use current script ID.
+/// SID_NONE: Don't set script ID.
+void set_option_direct(OptIndex opt_idx, OptVal value, int opt_flags, scid_T set_sid)
+{
+ static char errbuf[IOSIZE];
+
+ vimoption_T *opt = get_option(opt_idx);
+
+ if (opt->var == NULL) {
+ return;
+ }
+
+ const bool scope_both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
+ void *varp = get_varp_scope(opt, scope_both ? OPT_LOCAL : opt_flags);
+
+ set_option(opt_idx, varp, optval_copy(value), opt_flags, set_sid, true, true, errbuf,
+ sizeof(errbuf));
+}
+
+/// Set option value directly for buffer / window, without processing any side effects.
+///
+/// @param opt_idx Option index in options[] table.
+/// @param value Option value.
+/// @param opt_flags Option flags.
+/// @param set_sid Script ID. Special values:
+/// 0: Use current script ID.
+/// SID_NONE: Don't set script ID.
+/// @param req_scope Requested option scope. See OptReqScope in option.h.
+/// @param[in] from Target buffer/window.
+void set_option_direct_for(OptIndex opt_idx, OptVal value, int opt_flags, scid_T set_sid,
+ OptReqScope req_scope, void *const from)
+{
+ buf_T *save_curbuf = curbuf;
+ win_T *save_curwin = curwin;
+
+ // Don't use switch_option_context(), as that calls aucmd_prepbuf(), which may have unintended
+ // side-effects when setting an option directly. Just change the values of curbuf and curwin if
+ // needed, no need to properly switch the window / buffer.
+ switch (req_scope) {
+ case kOptReqGlobal:
+ break;
+ case kOptReqBuf:
+ curbuf = (buf_T *)from;
+ break;
+ case kOptReqWin:
+ curwin = (win_T *)from;
+ curbuf = curwin->w_buffer;
+ break;
+ }
+
+ set_option_direct(opt_idx, value, opt_flags, set_sid);
+
+ curwin = save_curwin;
+ curbuf = save_curbuf;
+}
+
/// Set the value of an option.
///
/// @param opt_idx Index in options[] table. Must not be kOptInvalid.
@@ -6244,7 +6305,7 @@ void set_fileformat(int eol_style, int opt_flags)
// p is NULL if "eol_style" is EOL_UNKNOWN.
if (p != NULL) {
- set_string_option_direct(kOptFileformat, p, opt_flags, 0);
+ set_option_direct(kOptFileformat, CSTR_AS_OPTVAL(p), opt_flags, 0);
}
// This may cause the buffer to become (un)modified.
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index f80926726a..29433ddbb5 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -266,113 +266,6 @@ void check_string_option(char **pp)
}
}
-/// Set global value for string option when it's a local option.
-///
-/// @param opt option
-/// @param varp pointer to option variable
-static void set_string_option_global(vimoption_T *opt, char **varp)
-{
- char **p;
-
- // the global value is always allocated
- if (opt->var == VAR_WIN) {
- p = (char **)GLOBAL_WO(varp);
- } else {
- p = (char **)opt->var;
- }
- if (opt->indir != PV_NONE && p != varp) {
- char *s = xstrdup(*varp);
- free_string_option(*p);
- *p = s;
- }
-}
-
-/// Set a string option to a new value (without checking the effect).
-/// The string is copied into allocated memory.
-/// if ("opt_idx" == kOptInvalid) "name" is used, otherwise "opt_idx" is used.
-/// When "set_sid" is zero set the scriptID to current_sctx.sc_sid. When
-/// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to
-/// "set_sid".
-///
-/// @param opt_flags Option flags.
-///
-/// TODO(famiu): Remove this and its win/buf variants.
-void set_string_option_direct(OptIndex opt_idx, const char *val, int opt_flags, scid_T set_sid)
-{
- vimoption_T *opt = get_option(opt_idx);
-
- if (opt->var == NULL) { // can't set hidden option
- return;
- }
-
- assert(opt->var != &p_shada);
-
- bool both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
- char *s = xstrdup(val);
- char **varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags);
-
- if (opt->flags & P_ALLOCED) {
- free_string_option(*varp);
- }
- *varp = s;
-
- // For buffer/window local option may also set the global value.
- if (both) {
- set_string_option_global(opt, varp);
- }
-
- opt->flags |= P_ALLOCED;
-
- // When setting both values of a global option with a local value,
- // make the local value empty, so that the global value is used.
- if ((opt->indir & PV_BOTH) && both) {
- free_string_option(*varp);
- *varp = empty_string_option;
- }
- if (set_sid != SID_NONE) {
- sctx_T script_ctx;
-
- if (set_sid == 0) {
- script_ctx = current_sctx;
- } else {
- script_ctx.sc_sid = set_sid;
- script_ctx.sc_seq = 0;
- script_ctx.sc_lnum = 0;
- }
- set_option_sctx(opt_idx, opt_flags, script_ctx);
- }
-}
-
-/// Like set_string_option_direct(), but for a window-local option in "wp".
-/// Blocks autocommands to avoid the old curwin becoming invalid.
-void set_string_option_direct_in_win(win_T *wp, OptIndex opt_idx, const char *val, int opt_flags,
- int set_sid)
-{
- win_T *save_curwin = curwin;
-
- block_autocmds();
- curwin = wp;
- curbuf = curwin->w_buffer;
- set_string_option_direct(opt_idx, val, opt_flags, set_sid);
- curwin = save_curwin;
- curbuf = curwin->w_buffer;
- unblock_autocmds();
-}
-
-/// Like set_string_option_direct(), but for a buffer-local option in "buf".
-/// Blocks autocommands to avoid the old curwin becoming invalid.
-void set_string_option_direct_in_buf(buf_T *buf, OptIndex opt_idx, const char *val, int opt_flags,
- int set_sid)
-{
- buf_T *save_curbuf = curbuf;
-
- block_autocmds();
- curbuf = buf;
- set_string_option_direct(opt_idx, val, opt_flags, set_sid);
- curbuf = save_curbuf;
- unblock_autocmds();
-}
-
/// Return true if "val" is a valid 'filetype' name.
/// Also used for 'syntax' and 'keymap'.
static bool valid_filetype(const char *val)
diff --git a/src/nvim/popupmenu.c b/src/nvim/popupmenu.c
index 5e8fb7f5de..bed0a8df4a 100644
--- a/src/nvim/popupmenu.c
+++ b/src/nvim/popupmenu.c
@@ -704,7 +704,8 @@ static win_T *pum_create_float_preview(bool enter)
return NULL;
}
buf_T *buf = find_buffer_by_handle(b, &err);
- set_string_option_direct_in_buf(buf, kOptBufhidden, "wipe", OPT_LOCAL, 0);
+ set_option_direct_for(kOptBufhidden, STATIC_CSTR_AS_OPTVAL("wipe"), OPT_LOCAL, 0, kOptReqBuf,
+ buf);
wp->w_float_is_info = true;
wp->w_p_diff = false;
buf->b_p_bl = false;
diff --git a/src/nvim/quickfix.c b/src/nvim/quickfix.c
index 0f639bf86a..9f431556e8 100644
--- a/src/nvim/quickfix.c
+++ b/src/nvim/quickfix.c
@@ -5154,7 +5154,7 @@ void ex_cfile(exarg_T *eap)
}
}
if (*eap->arg != NUL) {
- set_string_option_direct(kOptErrorfile, eap->arg, 0, 0);
+ set_option_direct(kOptErrorfile, CSTR_AS_OPTVAL(eap->arg), 0, 0);
}
char *enc = (*curbuf->b_p_menc != NUL) ? curbuf->b_p_menc : p_menc;
diff --git a/src/nvim/statusline.c b/src/nvim/statusline.c
index 1d914dd105..ca7083a9e3 100644
--- a/src/nvim/statusline.c
+++ b/src/nvim/statusline.c
@@ -2187,7 +2187,7 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
// matter?
// if (called_emsg > called_emsg_before)
if (opt_idx != kOptInvalid && did_emsg > did_emsg_before) {
- set_string_option_direct(opt_idx, "", opt_scope, SID_ERROR);
+ set_option_direct(opt_idx, STATIC_CSTR_AS_OPTVAL(""), opt_scope, SID_ERROR);
}
// A user function may reset KeyTyped, restore it.