aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/optionstr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/optionstr.c')
-rw-r--r--src/nvim/optionstr.c317
1 files changed, 5 insertions, 312 deletions
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 63ceb07b48..b868c90108 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -173,51 +173,7 @@ void didset_string_options(void)
(void)opt_strings_flags(p_cb, p_cb_values, &cb_flags, true);
}
-/// Trigger the OptionSet autocommand.
-/// "opt_idx" is the index of the option being set.
-/// "opt_flags" can be OPT_LOCAL etc.
-/// "oldval" the old value
-/// "oldval_l" the old local value (only non-NULL if global and local value are set)
-/// "oldval_g" the old global value (only non-NULL if global and local value are set)
-/// "newval" the new value
-void trigger_optionset_string(int opt_idx, int opt_flags, char *oldval, char *oldval_l,
- char *oldval_g, char *newval)
-{
- // Don't do this recursively.
- if (oldval == NULL || newval == NULL
- || *get_vim_var_str(VV_OPTION_TYPE) != NUL) {
- return;
- }
-
- char buf_type[7];
-
- vim_snprintf(buf_type, ARRAY_SIZE(buf_type), "%s",
- (opt_flags & OPT_LOCAL) ? "local" : "global");
- set_vim_var_string(VV_OPTION_OLD, oldval, -1);
- set_vim_var_string(VV_OPTION_NEW, newval, -1);
- set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
- if (opt_flags & OPT_LOCAL) {
- set_vim_var_string(VV_OPTION_COMMAND, "setlocal", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, oldval, -1);
- }
- if (opt_flags & OPT_GLOBAL) {
- set_vim_var_string(VV_OPTION_COMMAND, "setglobal", -1);
- set_vim_var_string(VV_OPTION_OLDGLOBAL, oldval, -1);
- }
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
- set_vim_var_string(VV_OPTION_COMMAND, "set", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, oldval_l, -1);
- set_vim_var_string(VV_OPTION_OLDGLOBAL, oldval_g, -1);
- }
- if (opt_flags & OPT_MODELINE) {
- set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1);
- set_vim_var_string(VV_OPTION_OLDLOCAL, oldval, -1);
- }
- apply_autocmds(EVENT_OPTIONSET, get_option(opt_idx)->fullname, NULL, false, NULL);
- reset_v_option_vars();
-}
-
-static char *illegal_char(char *errbuf, size_t errbuflen, int c)
+char *illegal_char(char *errbuf, size_t errbuflen, int c)
{
if (errbuf == NULL) {
return "";
@@ -340,7 +296,9 @@ static void set_string_option_global(vimoption_T *opt, char **varp)
/// "set_sid" is SID_NONE don't set the scriptID. Otherwise set the scriptID to
/// "set_sid".
///
-/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
+/// @param opt_flags OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL.
+///
+/// TODO(famiu): Remove this and its win/buf variants.
void set_string_option_direct(const char *name, int opt_idx, const char *val, int opt_flags,
int set_sid)
{
@@ -431,100 +389,6 @@ void set_string_option_direct_in_buf(buf_T *buf, const char *name, int opt_idx,
unblock_autocmds();
}
-/// Set a string option to a new value, handling the effects
-/// Must not be called with a hidden option!
-///
-/// @param[in] opt_idx Option to set.
-/// @param[in] value New value.
-/// @param[in] opt_flags Option flags: expected to contain #OPT_LOCAL and/or
-/// #OPT_GLOBAL.
-///
-/// @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 int opt_flags,
- const bool new_value, bool *value_checked, char *const errbuf,
- const size_t errbuflen)
- FUNC_ATTR_WARN_UNUSED_RESULT
-{
- vimoption_T *opt = get_option(opt_idx);
-
- char *origval_l = NULL;
- char *origval_g = NULL;
-
- // When using ":set opt=val" for a global option
- // with a local value the local value will be
- // reset, use the global value here.
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
- && ((int)opt->indir & PV_BOTH)) {
- varp = opt->var;
- }
-
- // The old value is kept until we are sure that the new value is valid.
- char *oldval = *(char **)varp;
-
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
- origval_l = *(char **)get_varp_scope(opt, OPT_LOCAL);
- origval_g = *(char **)get_varp_scope(opt, OPT_GLOBAL);
-
- // A global-local string option might have an empty option as value to
- // indicate that the global value should be used.
- if (((int)opt->indir & PV_BOTH) && origval_l == empty_string_option) {
- origval_l = origval_g;
- }
- }
-
- char *origval;
- // When setting the local value of a global option, the old value may be
- // the global value.
- if (((int)opt->indir & PV_BOTH) && (opt_flags & OPT_LOCAL)) {
- origval = *(char **)get_varp_from(opt, curbuf, curwin);
- } else {
- origval = oldval;
- }
-
- *(char **)varp = xstrdup(value != NULL ? value : empty_string_option);
-
- char *const saved_origval = (origval != NULL) ? xstrdup(origval) : NULL;
- char *const saved_oldval_l = (origval_l != NULL) ? xstrdup(origval_l) : 0;
- char *const saved_oldval_g = (origval_g != NULL) ? xstrdup(origval_g) : 0;
-
- // newval (and varp) may become invalid if the buffer is closed by
- // autocommands.
- char *const saved_newval = xstrdup(*(char **)varp);
-
- const int secure_saved = secure;
- const uint32_t *p = insecure_flag(curwin, opt_idx, opt_flags);
-
- // When an option is set in the sandbox, from a modeline or in secure mode, then deal with side
- // effects in secure mode. Also when the value was set with the P_INSECURE flag and is not
- // completely replaced.
- if ((opt_flags & OPT_MODELINE) || sandbox != 0 || (!new_value && (*p & P_INSECURE))) {
- secure = 1;
- }
-
- const char *const errmsg = did_set_string_option(curbuf, curwin, opt_idx, varp, oldval,
- errbuf, errbuflen, opt_flags, value_checked);
-
- secure = secure_saved;
-
- // call autocommand after handling side effects
- if (errmsg == NULL) {
- if (!starting) {
- trigger_optionset_string(opt_idx, opt_flags, saved_origval, saved_oldval_l,
- saved_oldval_g, saved_newval);
- }
- if (opt->flags & P_UI_OPTION) {
- ui_call_option_set(cstr_as_string(opt->fullname),
- CSTR_AS_OBJ(saved_newval));
- }
- }
- xfree(saved_origval);
- xfree(saved_oldval_l);
- xfree(saved_oldval_g);
- xfree(saved_newval);
-
- return errmsg;
-}
-
/// Return true if "val" is a valid 'filetype' name.
/// Also used for 'syntax' and 'keymap'.
static bool valid_filetype(const char *val)
@@ -636,7 +500,7 @@ const char *check_stl_option(char *s)
/// Check for a "normal" directory or file name in some options. Disallow a
/// path separator (slash and/or backslash), wildcards and characters that are
/// often illegal in a file name. Be more permissive if "secure" is off.
-static bool check_illegal_path_names(char *val, uint32_t flags)
+bool check_illegal_path_names(char *val, uint32_t flags)
{
return (((flags & P_NFNAME)
&& strpbrk(val, (secure ? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL)
@@ -2676,177 +2540,6 @@ int expand_set_winhighlight(optexpand_T *args, int *numMatches, char ***matches)
return expand_set_opt_generic(args, get_highlight_name, numMatches, matches);
}
-// When 'syntax' is set, load the syntax of that name
-static void do_syntax_autocmd(buf_T *buf, bool value_changed)
-{
- static int syn_recursive = 0;
-
- syn_recursive++;
- // Only pass true for "force" when the value changed or not used
- // recursively, to avoid endless recurrence.
- apply_autocmds(EVENT_SYNTAX, buf->b_p_syn, buf->b_fname,
- value_changed || syn_recursive == 1, buf);
- buf->b_flags |= BF_SYN_SET;
- syn_recursive--;
-}
-
-static void do_spelllang_source(win_T *win)
-{
- char fname[200];
- char *q = win->w_s->b_p_spl;
-
- // Skip the first name if it is "cjk".
- if (strncmp(q, "cjk,", 4) == 0) {
- q += 4;
- }
-
- // Source the spell/LANG.{vim,lua} in 'runtimepath'.
- // They could set 'spellcapcheck' depending on the language.
- // Use the first name in 'spelllang' up to '_region' or
- // '.encoding'.
- char *p;
- for (p = q; *p != NUL; p++) {
- if (!ASCII_ISALNUM(*p) && *p != '-') {
- break;
- }
- }
- if (p > q) {
- vim_snprintf(fname, sizeof(fname), "spell/%.*s.*", (int)(p - q), q);
- source_runtime_vim_lua(fname, DIP_ALL);
- }
-}
-
-/// Handle string options that need some action to perform when changed.
-/// The new value must be allocated.
-///
-/// @param opt_idx index in options[] table
-/// @param varp pointer to the option variable
-/// @param oldval previous value of the option
-/// @param errbuf buffer for errors, or NULL
-/// @param errbuflen length of errors buffer
-/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
-/// @param op OP_ADDING/OP_PREPENDING/OP_REMOVING
-/// @param value_checked value was checked to be safe, no need to set P_INSECURE
-///
-/// @return NULL for success, or an untranslated error message for an error
-const char *did_set_string_option(buf_T *buf, win_T *win, int opt_idx, char **varp, char *oldval,
- char *errbuf, size_t errbuflen, int opt_flags,
- bool *value_checked)
-{
- const char *errmsg = NULL;
- int restore_chartab = false;
- vimoption_T *opt = get_option(opt_idx);
- bool free_oldval = (opt->flags & P_ALLOCED);
- opt_did_set_cb_T did_set_cb = get_option_did_set_cb(opt_idx);
- bool value_changed = false;
-
- optset_T args = {
- .os_varp = varp,
- .os_idx = opt_idx,
- .os_flags = opt_flags,
- .os_oldval.string = cstr_as_string(oldval),
- .os_newval.string = cstr_as_string(*varp),
- .os_value_checked = false,
- .os_value_changed = false,
- .os_restore_chartab = false,
- .os_errbuf = errbuf,
- .os_errbuflen = errbuflen,
- .os_win = win,
- .os_buf = buf,
- };
-
- // Disallow changing some options from secure mode
- if ((secure || sandbox != 0) && (opt->flags & P_SECURE)) {
- errmsg = e_secure;
- // Check for a "normal" directory or file name in some options.
- } else if (check_illegal_path_names(*varp, opt->flags)) {
- errmsg = e_invarg;
- } else if (did_set_cb != NULL) {
- // Invoke the option specific callback function to validate and apply
- // the new option value.
- errmsg = did_set_cb(&args);
-
- // The 'filetype' and 'syntax' option callback functions may change
- // the os_value_changed field.
- value_changed = args.os_value_changed;
- // The 'keymap', 'filetype' and 'syntax' option callback functions
- // may change the os_value_checked field.
- *value_checked = args.os_value_checked;
- // The 'isident', 'iskeyword', 'isprint' and 'isfname' options may
- // change the character table. On failure, this needs to be restored.
- restore_chartab = args.os_restore_chartab;
- }
-
- // If an error is detected, restore the previous value.
- if (errmsg != NULL) {
- free_string_option(*varp);
- *varp = oldval;
- // When resetting some values, need to act on it.
- if (restore_chartab) {
- (void)buf_init_chartab(buf, true);
- }
- } else {
- // Remember where the option was set.
- set_option_sctx_idx(opt_idx, opt_flags, current_sctx);
- // Free string options that are in allocated memory.
- // Use "free_oldval", because recursiveness may change the flags under
- // our fingers (esp. init_highlight()).
- if (free_oldval) {
- free_string_option(oldval);
- }
- opt->flags |= P_ALLOCED;
-
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
- && (opt->indir & PV_BOTH)) {
- // global option with local value set to use global value; free
- // the local value and make it empty
- char *p = get_varp_scope(opt, OPT_LOCAL);
- free_string_option(*(char **)p);
- *(char **)p = empty_string_option;
- } else if (!(opt_flags & OPT_LOCAL) && opt_flags != OPT_GLOBAL) {
- // May set global value for local option.
- set_string_option_global(opt, varp);
- }
-
- // Trigger the autocommand only after setting the flags.
- if (varp == &buf->b_p_syn) {
- do_syntax_autocmd(buf, value_changed);
- } else if (varp == &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(buf, value_changed);
- }
- } else if (varp == &win->w_s->b_p_spl) {
- do_spelllang_source(win);
- }
- }
-
- if (varp == &p_mouse) {
- setmouse(); // in case 'mouse' changed
- }
-
- if ((varp == &p_flp || varp == &(buf->b_p_flp))
- && 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 == &(win->w_p_wbr)) {
- // add / remove window bars for 'winbar'
- set_winbar(true);
- }
-
- if (win->w_curswant != MAXCOL
- && (opt->flags & (P_CURSWANT | P_RALL)) != 0) {
- win->w_set_curswant = true;
- }
-
- check_redraw_for(buf, win, opt->flags);
-
- return errmsg;
-}
-
/// Check an option that can be a range of string values.
///
/// @param list when true: accept a list of values