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.c270
1 files changed, 174 insertions, 96 deletions
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 1bdfcbecb9..a97e9b7c7e 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -2,14 +2,13 @@
// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
#include <assert.h>
-#include <inttypes.h>
#include <stdbool.h>
-#include <stdlib.h>
#include <string.h>
#include "nvim/api/private/helpers.h"
#include "nvim/ascii.h"
#include "nvim/autocmd.h"
+#include "nvim/buffer_defs.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/cursor_shape.h"
@@ -17,27 +16,40 @@
#include "nvim/digraph.h"
#include "nvim/drawscreen.h"
#include "nvim/eval.h"
+#include "nvim/eval/typval_defs.h"
+#include "nvim/eval/userfunc.h"
#include "nvim/eval/vars.h"
#include "nvim/ex_getln.h"
-#include "nvim/hardcopy.h"
+#include "nvim/fold.h"
+#include "nvim/gettext.h"
+#include "nvim/globals.h"
#include "nvim/highlight_group.h"
#include "nvim/indent.h"
#include "nvim/indent_c.h"
#include "nvim/insexpand.h"
#include "nvim/keycodes.h"
+#include "nvim/macros.h"
#include "nvim/mapping.h"
+#include "nvim/mbyte.h"
#include "nvim/memline.h"
+#include "nvim/memory.h"
+#include "nvim/message.h"
#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/option_defs.h"
#include "nvim/optionstr.h"
+#include "nvim/os/os.h"
+#include "nvim/pos.h"
#include "nvim/quickfix.h"
#include "nvim/runtime.h"
+#include "nvim/screen.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
#include "nvim/spellsuggest.h"
#include "nvim/strings.h"
+#include "nvim/tag.h"
#include "nvim/ui.h"
#include "nvim/vim.h"
#include "nvim/window.h"
@@ -75,6 +87,7 @@ static char *(p_ssop_values[]) = { "buffers", "winpos", "resize", "winsize", "lo
// Keep in sync with SWB_ flags in option_defs.h
static char *(p_swb_values[]) = { "useopen", "usetab", "split", "newtab", "vsplit", "uselast",
NULL };
+static char *(p_spk_values[]) = { "cursor", "screen", "topline", NULL };
static char *(p_tc_values[]) = { "followic", "ignore", "match", "followscs", "smart", NULL };
static char *(p_ve_values[]) = { "block", "insert", "all", "onemore", "none", "NONE", NULL };
static char *(p_wop_values[]) = { "tagfile", "pum", NULL };
@@ -107,16 +120,19 @@ static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2", "auto:3", "auto:4"
"auto:6", "auto:7", "auto:8", "auto:9", "0", "1", "2", "3", "4",
"5", "6", "7", "8", "9", NULL };
static char *(p_cb_values[]) = { "unnamed", "unnamedplus", NULL };
+static char *(p_spo_values[]) = { "camel", "noplainbuffer", NULL };
static char *(p_icm_values[]) = { "nosplit", "split", NULL };
static char *(p_jop_values[]) = { "stack", "view", NULL };
static char *(p_tpf_values[]) = { "BS", "HT", "FF", "ESC", "DEL", "C0", "C1", NULL };
static char *(p_rdb_values[]) = { "compositor", "nothrottle", "invalid", "nodelta", NULL };
+static char *(p_sloc_values[]) = { "last", "statusline", "tabline", NULL };
/// All possible flags for 'shm'.
static char SHM_ALL[] = { SHM_RO, SHM_MOD, SHM_FILE, SHM_LAST, SHM_TEXT, SHM_LINES, SHM_NEW,
SHM_WRI, SHM_ABBREVIATIONS, SHM_WRITE, SHM_TRUNC, SHM_TRUNCALL,
SHM_OVER, SHM_OVERALL, SHM_SEARCH, SHM_ATTENTION, SHM_INTRO,
- SHM_COMPLETIONMENU, SHM_RECORDING, SHM_FILEINFO, SHM_SEARCHCOUNT, 0, };
+ SHM_COMPLETIONMENU, SHM_COMPLETIONSCAN, SHM_RECORDING, SHM_FILEINFO,
+ SHM_SEARCHCOUNT, 0, };
/// After setting various option values: recompute variables that depend on
/// option values.
@@ -146,8 +162,8 @@ void didset_string_options(void)
/// "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_optionsset_string(int opt_idx, int opt_flags, char *oldval, char *oldval_l,
- char *oldval_g, char *newval)
+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
@@ -177,7 +193,7 @@ void trigger_optionsset_string(int opt_idx, int opt_flags, char *oldval, char *o
set_vim_var_string(VV_OPTION_COMMAND, "modeline", -1);
set_vim_var_string(VV_OPTION_OLDLOCAL, oldval, -1);
}
- apply_autocmds(EVENT_OPTIONSET, get_option_fullname(opt_idx), NULL, false, NULL);
+ apply_autocmds(EVENT_OPTIONSET, get_option(opt_idx)->fullname, NULL, false, NULL);
reset_v_option_vars();
}
}
@@ -225,6 +241,7 @@ void check_buf_options(buf_T *buf)
check_string_option(&buf->b_p_cink);
check_string_option(&buf->b_p_cino);
parse_cino(buf);
+ check_string_option(&buf->b_p_lop);
check_string_option(&buf->b_p_ft);
check_string_option(&buf->b_p_cinw);
check_string_option(&buf->b_p_cinsd);
@@ -252,7 +269,7 @@ void check_buf_options(buf_T *buf)
/// Free the string allocated for an option.
/// Checks for the string being empty_option. This may happen if we're out of
-/// memory, vim_strsave() returned NULL, which was replaced by empty_option by
+/// memory, xstrdup() returned NULL, which was replaced by empty_option by
/// check_options().
/// Does NOT check for P_ALLOCED flag!
void free_string_option(char *p)
@@ -279,19 +296,19 @@ void check_string_option(char **pp)
/// Set global value for string option when it's a local option.
///
-/// @param opt_idx option index
+/// @param opt option
/// @param varp pointer to option variable
-static void set_string_option_global(int opt_idx, char **varp)
+static void set_string_option_global(vimoption_T *opt, char **varp)
{
char **p;
// the global value is always allocated
- if (is_window_local_option(opt_idx)) {
+ if (opt->var == VAR_WIN) {
p = (char **)GLOBAL_WO(varp);
} else {
- p = (char **)get_option_var(opt_idx);
+ p = (char **)opt->var;
}
- if (!is_global_option(opt_idx) && p != varp) {
+ if (opt->indir != PV_NONE && p != varp) {
char *s = xstrdup(*varp);
free_string_option(*p);
*p = s;
@@ -323,30 +340,32 @@ void set_string_option_direct(const char *name, int opt_idx, const char *val, in
}
}
- if (is_hidden_option(idx)) { // can't set hidden option
+ vimoption_T *opt = get_option(idx);
+
+ if (opt->var == NULL) { // can't set hidden option
return;
}
- assert((void *)get_option_var(idx) != (void *)&p_shada);
+ assert((void *)opt->var != (void *)&p_shada);
s = xstrdup(val);
{
- varp = (char **)get_option_varp_scope(idx, both ? OPT_LOCAL : opt_flags);
- if ((opt_flags & OPT_FREE) && (get_option_flags(idx) & P_ALLOCED)) {
+ varp = (char **)get_varp_scope(opt, both ? OPT_LOCAL : opt_flags);
+ if ((opt_flags & OPT_FREE) && (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(idx, varp);
+ set_string_option_global(opt, varp);
}
- set_option_flag(idx, P_ALLOCED);
+ 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 (is_global_local_option(idx) && both) {
+ if ((opt->indir & PV_BOTH) && both) {
free_string_option(*varp);
*varp = empty_option;
}
@@ -392,24 +411,24 @@ void set_string_option_direct_in_win(win_T *wp, const char *name, int opt_idx, c
char *set_string_option(const int opt_idx, const char *const value, const int opt_flags)
FUNC_ATTR_NONNULL_ARG(2) FUNC_ATTR_WARN_UNUSED_RESULT
{
- if (is_hidden_option(opt_idx)) { // don't set hidden option
+ vimoption_T *opt = get_option(opt_idx);
+
+ if (opt->var == NULL) { // don't set hidden option
return NULL;
}
char *const s = xstrdup(value);
char **const varp
- = (char **)get_option_varp_scope(opt_idx,
- (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
- ? (is_global_local_option(opt_idx)
- ? OPT_GLOBAL : OPT_LOCAL)
- : opt_flags);
+ = (char **)get_varp_scope(opt, ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
+ ? ((opt->indir & PV_BOTH) ? OPT_GLOBAL : OPT_LOCAL)
+ : opt_flags));
char *const oldval = *varp;
char *oldval_l = NULL;
char *oldval_g = NULL;
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0) {
- oldval_l = *(char **)get_option_varp_scope(opt_idx, OPT_LOCAL);
- oldval_g = *(char **)get_option_varp_scope(opt_idx, OPT_GLOBAL);
+ oldval_l = *(char **)get_varp_scope(opt, OPT_LOCAL);
+ oldval_g = *(char **)get_varp_scope(opt, OPT_GLOBAL);
}
*varp = s;
@@ -430,11 +449,11 @@ char *set_string_option(const int opt_idx, const char *const value, const int op
// call autocommand after handling side effects
if (errmsg == NULL) {
if (!starting) {
- trigger_optionsset_string(opt_idx, opt_flags, saved_oldval, saved_oldval_l, saved_oldval_g,
- saved_newval);
+ trigger_optionset_string(opt_idx, opt_flags, saved_oldval, saved_oldval_l, saved_oldval_g,
+ saved_newval);
}
- if (get_option_flags(opt_idx) & P_UI_OPTION) {
- ui_call_option_set(cstr_as_string(get_option_fullname(opt_idx)),
+ if (opt->flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(opt->fullname),
STRING_OBJ(cstr_as_string(saved_newval)));
}
}
@@ -463,7 +482,7 @@ static char *check_mousescroll(char *string)
for (;;) {
char *end = vim_strchr(string, ',');
- size_t length = end ? (size_t)(end - string) : STRLEN(string);
+ size_t length = end ? (size_t)(end - string) : strlen(string);
// Both "ver:" and "hor:" are 4 bytes long.
// They should be followed by at least one digit.
@@ -531,8 +550,8 @@ static int check_signcolumn(char *val)
}
// check for 'auto:<NUMBER>-<NUMBER>'
- if (STRLEN(val) == 8
- && !STRNCMP(val, "auto:", 5)
+ if (strlen(val) == 8
+ && !strncmp(val, "auto:", 5)
&& ascii_isdigit(val[5])
&& val[6] == '-'
&& ascii_isdigit(val[7])) {
@@ -637,20 +656,21 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
char *errmsg = NULL;
char *s, *p;
int did_chartab = false;
- bool free_oldval = (get_option_flags(opt_idx) & P_ALLOCED);
+ vimoption_T *opt = get_option(opt_idx);
+ bool free_oldval = (opt->flags & P_ALLOCED);
bool value_changed = false;
// Get the global option to compare with, otherwise we would have to check
// two values for all local options.
- char **gvarp = (char **)get_option_varp_scope(opt_idx, OPT_GLOBAL);
+ char **gvarp = (char **)get_varp_scope(opt, OPT_GLOBAL);
// Disallow changing some options from secure mode
if ((secure || sandbox != 0)
- && (get_option_flags(opt_idx) & P_SECURE)) {
+ && (opt->flags & P_SECURE)) {
errmsg = e_secure;
- } else if (((get_option_flags(opt_idx) & P_NFNAME)
+ } else if (((opt->flags & P_NFNAME)
&& strpbrk(*varp, (secure ? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL)
- || ((get_option_flags(opt_idx) & P_NDNAME)
+ || ((opt->flags & P_NDNAME)
&& strpbrk(*varp, "*?[|;&<>\r\n") != NULL)) {
// Check for a "normal" directory or file name in some options. Disallow a
// path separator (slash and/or backslash), wildcards and characters that
@@ -682,7 +702,7 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
}
}
} else if (varp == &p_bex || varp == &p_pm) { // 'backupext' and 'patchmode'
- if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
+ if (strcmp(*p_bex == '.' ? p_bex + 1 : p_bex,
*p_pm == '.' ? p_pm + 1 : p_pm) == 0) {
errmsg = e_backupext_and_patchmode_are_equal;
}
@@ -690,6 +710,10 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (briopt_check(curwin) == FAIL) {
errmsg = e_invarg;
}
+ // list setting requires a redraw
+ if (curwin->w_briopt_list) {
+ redraw_all_later(UPD_NOT_VALID);
+ }
} else if (varp == &p_isi
|| varp == &(curbuf->b_p_isk)
|| varp == &p_isp
@@ -718,9 +742,9 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
}
} else if (varp == &curwin->w_p_cc) { // 'colorcolumn'
errmsg = check_colorcolumn(curwin);
- } else if (varp == (char **)&p_hlg) { // 'helplang'
+ } else if (varp == &p_hlg) { // 'helplang'
// Check for "", "ab", "ab,cd", etc.
- for (s = (char *)p_hlg; *s != NUL; s += 3) {
+ for (s = p_hlg; *s != NUL; s += 3) {
if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL)) {
errmsg = e_invarg;
break;
@@ -730,7 +754,7 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
}
}
} else if (varp == &p_hl) { // 'highlight'
- if (STRCMP(*varp, HIGHLIGHT_INIT) != 0) {
+ if (strcmp(*varp, HIGHLIGHT_INIT) != 0) {
errmsg = e_unsupportedoption;
}
} else if (varp == &p_jop) { // 'jumpoptions'
@@ -822,24 +846,19 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
}
if (errmsg == NULL) {
- // canonize the value, so that STRCMP() can be used on it
+ // canonize the value, so that strcmp() can be used on it
p = enc_canonize(*varp);
xfree(*varp);
*varp = p;
if (varp == &p_enc) {
// only encoding=utf-8 allowed
- if (STRCMP(p_enc, "utf-8") != 0) {
+ if (strcmp(p_enc, "utf-8") != 0) {
errmsg = e_unsupportedoption;
} else {
spell_reload();
}
}
}
- } else if (varp == &p_penc) {
- // Canonize printencoding if VIM standard one
- p = enc_canonize(p_penc);
- xfree(p_penc);
- p_penc = p;
} else if (varp == &curbuf->b_p_keymap) {
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
@@ -985,13 +1004,14 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
} else if (varp == &p_shada) { // 'shada'
// TODO(ZyX-I): Remove this code in the future, alongside with &viminfo
// option.
- opt_idx = ((get_option_fullname(opt_idx)[0] == 'v')
+ opt_idx = ((opt->fullname[0] == 'v')
? (shada_idx == -1 ? ((shada_idx = findoption("shada"))) : shada_idx)
: opt_idx);
+ opt = get_option(opt_idx);
// Update free_oldval now that we have the opt_idx for 'shada', otherwise
// there would be a disconnect between the check for P_ALLOCED at the start
// of the function and the set of P_ALLOCED at the end of the function.
- free_oldval = (get_option_flags(opt_idx) & P_ALLOCED);
+ free_oldval = (opt->flags & P_ALLOCED);
for (s = p_shada; *s;) {
// Check it's a valid character
if (vim_strchr("!\"%'/:<@cfhnrs", *s) == NULL) {
@@ -1014,7 +1034,7 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (errbuf != NULL) {
vim_snprintf(errbuf, errbuflen,
_("E526: Missing number after <%s>"),
- transchar_byte(*(s - 1)));
+ transchar_byte((uint8_t)(*(s - 1))));
errmsg = errbuf;
} else {
errmsg = "";
@@ -1045,10 +1065,6 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
}
} else if (varp == &p_guicursor) { // 'guicursor'
errmsg = parse_shape_opt(SHAPE_CURSOR);
- } else if (varp == &p_popt) {
- errmsg = parse_printoptions();
- } else if (varp == &p_pmfn) {
- errmsg = parse_printmbfont();
} else if (varp == &p_langmap) { // 'langmap'
langmap_set();
} else if (varp == &p_breakat) { // 'breakat'
@@ -1090,6 +1106,10 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (opt_strings_flags(p_swb, p_swb_values, &swb_flags, true) != OK) {
errmsg = e_invarg;
}
+ } else if (varp == &p_spk) { // 'splitkeep'
+ if (check_opt_strings(p_spk, p_spk_values, false) != OK) {
+ errmsg = e_invarg;
+ }
} else if (varp == &p_debug) { // 'debug'
if (check_opt_strings(p_debug, p_debug_values, true) != OK) {
errmsg = e_invarg;
@@ -1125,7 +1145,8 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
// When 'spellcapcheck' is set compile the regexp program.
errmsg = compile_cap_prog(curwin->w_s);
} else if (varp == &(curwin->w_s->b_p_spo)) { // 'spelloptions'
- if (**varp != NUL && STRCMP("camel", *varp) != 0) {
+ if (opt_strings_flags(curwin->w_s->b_p_spo, p_spo_values, &(curwin->w_s->b_p_spo_flags),
+ true) != OK) {
errmsg = e_invarg;
}
} else if (varp == &p_sps) { // 'spellsuggest'
@@ -1156,12 +1177,14 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
redraw_titles();
}
} else if (gvarp == &p_stl || gvarp == &p_wbr || varp == &p_tal
- || varp == &p_ruf) {
- // 'statusline', 'winbar', 'tabline' or 'rulerformat'
+ || varp == &p_ruf || varp == &curwin->w_p_stc) {
+ // 'statusline', 'winbar', 'tabline', 'rulerformat' or 'statuscolumn'
int wid;
if (varp == &p_ruf) { // reset ru_wid first
ru_wid = 0;
+ } else if (varp == &curwin->w_p_stc) {
+ curwin->w_nrwidth_line_count = 0;
}
s = *varp;
if (varp == &p_ruf && *s == '%') {
@@ -1176,7 +1199,8 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
errmsg = check_stl_option(p_ruf);
}
} else if (varp == &p_ruf || s[0] != '%' || s[1] != '!') {
- // check 'statusline', 'winbar' or 'tabline' only if it doesn't start with "%!"
+ // check 'statusline', 'winbar', 'tabline' or 'statuscolumn'
+ // only if it doesn't start with "%!"
errmsg = check_stl_option(s);
}
if (varp == &p_ruf && errmsg == NULL) {
@@ -1245,6 +1269,10 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
&& (curwin->w_p_nu || curwin->w_p_rnu)) {
curwin->w_nrwidth_line_count = 0;
}
+ } else if (varp == &p_sloc) { // 'showcmdloc'
+ if (check_opt_strings(p_sloc, p_sloc_values, false) != OK) {
+ errmsg = e_invarg;
+ }
} else if (varp == &curwin->w_p_fdc
|| varp == &curwin->w_allbuf_opt.wo_fdc) {
// 'foldcolumn'
@@ -1256,7 +1284,7 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (*p_pt) {
p = NULL;
(void)replace_termcodes(p_pt,
- STRLEN(p_pt),
+ strlen(p_pt),
&p, REPTERM_FROM_PART | REPTERM_DO_LT, NULL,
CPO_TO_CPO_FLAGS);
if (p != NULL) {
@@ -1312,10 +1340,6 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
newFoldLevel();
}
}
- } else if (varp == &curwin->w_p_fde) { // 'foldexpr'
- if (foldmethodIsExpr(curwin)) {
- foldUpdateAll(curwin);
- }
} else if (gvarp == &curwin->w_allbuf_opt.wo_fmr) { // 'foldmarker'
p = vim_strchr(*varp, ',');
if (p == NULL) {
@@ -1356,33 +1380,20 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
} else {
if (opt_strings_flags(ve, p_ve_values, flags, true) != OK) {
errmsg = e_invarg;
- } else if (STRCMP(p_ve, oldval) != 0) {
+ } else if (strcmp(p_ve, oldval) != 0) {
// Recompute cursor position in case the new 've' setting
// changes something.
validate_virtcol();
coladvance(curwin->w_virtcol);
}
}
- } else if (varp == &p_csqf) {
- if (p_csqf != NULL) {
- p = p_csqf;
- while (*p != NUL) {
- if (vim_strchr(CSQF_CMDS, *p) == NULL
- || p[1] == NUL
- || vim_strchr(CSQF_FLAGS, p[1]) == NULL
- || (p[2] != NUL && p[2] != ',')) {
- errmsg = e_invarg;
- break;
- } else if (p[2] == NUL) {
- break;
- } else {
- p += 3;
- }
- }
- }
} else if (gvarp == &p_cino) { // 'cinoptions'
// TODO(vim): recognize errors
parse_cino(curbuf);
+ } else if (gvarp == &p_lop) { // 'lispoptions'
+ if (**varp != NUL && strcmp(*varp, "expr:0") != 0 && strcmp(*varp, "expr:1") != 0) {
+ errmsg = e_invarg;
+ }
} else if (varp == &p_icm) { // 'inccommand'
if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
errmsg = e_invarg;
@@ -1391,7 +1402,7 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
} else {
- value_changed = STRCMP(oldval, *varp) != 0;
+ value_changed = strcmp(oldval, *varp) != 0;
// Since we check the value, there is no need to set P_INSECURE,
// even when the value comes from a modeline.
@@ -1401,7 +1412,7 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
} else {
- value_changed = STRCMP(oldval, *varp) != 0;
+ value_changed = strcmp(oldval, *varp) != 0;
// Since we check the value, there is no need to set P_INSECURE,
// even when the value comes from a modeline.
@@ -1468,6 +1479,63 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
}
}
}
+ } else if (varp == &p_dex
+ || varp == &curwin->w_p_fde
+ || varp == &curwin->w_p_fdt
+ || gvarp == &p_fex
+ || gvarp == &p_inex
+ || gvarp == &p_inde
+ || varp == &p_pex) { // '*expr' options
+ char **p_opt = NULL;
+
+ // If the option value starts with <SID> or s:, then replace that with
+ // the script identifier.
+
+ if (varp == &p_dex) { // 'diffexpr'
+ p_opt = &p_dex;
+ }
+ if (varp == &curwin->w_p_fde) { // 'foldexpr'
+ p_opt = &curwin->w_p_fde;
+ }
+ if (varp == &curwin->w_p_fdt) { // 'foldtext'
+ p_opt = &curwin->w_p_fdt;
+ }
+ if (gvarp == &p_fex) { // 'formatexpr'
+ p_opt = &curbuf->b_p_fex;
+ }
+ if (gvarp == &p_inex) { // 'includeexpr'
+ p_opt = &curbuf->b_p_inex;
+ }
+ if (gvarp == &p_inde) { // 'indentexpr'
+ p_opt = &curbuf->b_p_inde;
+ }
+ if (varp == &p_pex) { // 'patchexpr'
+ p_opt = &p_pex;
+ }
+
+ if (p_opt != NULL) {
+ char *name = get_scriptlocal_funcname(*p_opt);
+ if (name != NULL) {
+ free_string_option(*p_opt);
+ *p_opt = name;
+ }
+ }
+
+ if (varp == &curwin->w_p_fde && foldmethodIsExpr(curwin)) {
+ foldUpdateAll(curwin);
+ }
+ } else if (gvarp == &p_cfu) { // 'completefunc'
+ if (set_completefunc_option() == FAIL) {
+ errmsg = e_invarg;
+ }
+ } else if (gvarp == &p_ofu) { // 'omnifunc'
+ if (set_omnifunc_option() == FAIL) {
+ errmsg = e_invarg;
+ }
+ } else if (gvarp == &p_tsrfu) { // 'thesaurusfunc'
+ if (set_thesaurusfunc_option() == FAIL) {
+ errmsg = e_invarg;
+ }
} else if (varp == &p_opfunc) { // 'operatorfunc'
if (set_operatorfunc_option() == FAIL) {
errmsg = e_invarg;
@@ -1476,6 +1544,10 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (qf_process_qftf_option() == FAIL) {
errmsg = e_invarg;
}
+ } else if (gvarp == &p_tfu) { // 'tagfunc'
+ if (set_tagfunc_option() == FAIL) {
+ errmsg = e_invarg;
+ }
} else {
// Options that are a list of flags.
p = NULL;
@@ -1520,18 +1592,18 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
if (free_oldval) {
free_string_option(oldval);
}
- set_option_flag(opt_idx, P_ALLOCED);
+ opt->flags |= P_ALLOCED;
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
- && is_global_local_option(opt_idx)) {
+ && (opt->indir & PV_BOTH)) {
// global option with local value set to use global value; free
// the local value and make it empty
- p = get_option_varp_scope(opt_idx, OPT_LOCAL);
+ p = get_varp_scope(opt, OPT_LOCAL);
free_string_option(*(char **)p);
*(char **)p = empty_option;
} else if (!(opt_flags & OPT_LOCAL) && opt_flags != OPT_GLOBAL) {
// May set global value for local option.
- set_string_option_global(opt_idx, varp);
+ set_string_option_global(opt, varp);
}
// Trigger the autocommand only after setting the flags.
@@ -1577,7 +1649,7 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
char *q = curwin->w_s->b_p_spl;
// Skip the first name if it is "cjk".
- if (STRNCMP(q, "cjk,", 4) == 0) {
+ if (strncmp(q, "cjk,", 4) == 0) {
q += 4;
}
@@ -1601,12 +1673,18 @@ char *did_set_string_option(int opt_idx, char **varp, char *oldval, char *errbuf
setmouse(); // in case 'mouse' changed
}
+ // Changing Formatlistpattern when briopt includes the list setting:
+ // redraw
+ if ((varp == &p_flp || varp == &(curbuf->b_p_flp)) && curwin->w_briopt_list) {
+ redraw_all_later(UPD_NOT_VALID);
+ }
+
if (curwin->w_curswant != MAXCOL
- && (get_option_flags(opt_idx) & (P_CURSWANT | P_RALL)) != 0) {
+ && (opt->flags & (P_CURSWANT | P_RALL)) != 0) {
curwin->w_set_curswant = true;
}
- check_redraw(get_option_flags(opt_idx));
+ check_redraw(opt->flags);
return errmsg;
}
@@ -1639,8 +1717,8 @@ static int opt_strings_flags(char *val, char **values, unsigned *flagp, bool lis
return FAIL;
}
- size_t len = STRLEN(values[i]);
- if (STRNCMP(values[i], val, len) == 0
+ size_t len = strlen(values[i]);
+ if (strncmp(values[i], val, len) == 0
&& ((list && val[len] == ',') || val[len] == NUL)) {
val += len + (val[len] == ',');
assert(i < sizeof(1U) * 8);