aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/option.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/option.c')
-rw-r--r--src/nvim/option.c3365
1 files changed, 397 insertions, 2968 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 4958c10220..9bc5409ff9 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -27,18 +27,18 @@
#include <stdlib.h>
#include <string.h>
+#include "nvim/arglist.h"
#include "nvim/ascii.h"
#include "nvim/buffer.h"
+#include "nvim/change.h"
#include "nvim/charset.h"
-#include "nvim/cursor.h"
#include "nvim/cursor_shape.h"
+#include "nvim/decoration_provider.h"
#include "nvim/diff.h"
-#include "nvim/digraph.h"
+#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
-#include "nvim/eval/vars.h"
-#include "nvim/ex_cmds2.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
#include "nvim/ex_session.h"
@@ -49,9 +49,10 @@
#include "nvim/hardcopy.h"
#include "nvim/highlight.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/locale.h"
#include "nvim/macros.h"
#include "nvim/mapping.h"
#include "nvim/mbyte.h"
@@ -62,16 +63,19 @@
#include "nvim/mouse.h"
#include "nvim/move.h"
#include "nvim/normal.h"
+#include "nvim/ops.h"
#include "nvim/option.h"
+#include "nvim/optionstr.h"
#include "nvim/os/os.h"
#include "nvim/os_unix.h"
#include "nvim/path.h"
-#include "nvim/popupmnu.h"
+#include "nvim/popupmenu.h"
#include "nvim/regexp.h"
-#include "nvim/runtime.h"
#include "nvim/screen.h"
+#include "nvim/search.h"
#include "nvim/spell.h"
#include "nvim/spellfile.h"
+#include "nvim/spellsuggest.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
@@ -82,11 +86,25 @@
#ifdef WIN32
# include "nvim/os/pty_conpty_win.h"
#endif
+#include "nvim/api/extmark.h"
#include "nvim/api/private/helpers.h"
+#include "nvim/api/vim.h"
#include "nvim/lua/executor.h"
#include "nvim/os/input.h"
#include "nvim/os/lang.h"
-#include "nvim/quickfix.h"
+
+static char e_unknown_option[]
+ = N_("E518: Unknown option");
+static char e_not_allowed_in_modeline[]
+ = N_("E520: Not allowed in a modeline");
+static char e_not_allowed_in_modeline_when_modelineexpr_is_off[]
+ = N_("E992: Not allowed in a modeline when 'modelineexpr' is off");
+static char e_key_code_not_set[]
+ = N_("E846: Key code not set");
+static char e_number_required_after_equal[]
+ = N_("E521: Number required after =");
+static char e_preview_window_already_exists[]
+ = N_("E590: A preview window already exists");
/*
* The options that are local to a window or buffer have "indir" set to one of
@@ -119,74 +137,6 @@ typedef enum {
static char *p_term = NULL;
static char *p_ttytype = NULL;
-/*
- * These are the global values for options which are also local to a buffer.
- * Only to be used in option.c!
- */
-static int p_ai;
-static int p_bin;
-static int p_bomb;
-static char_u *p_bh;
-static char_u *p_bt;
-static int p_bl;
-static long p_channel;
-static int p_ci;
-static int p_cin;
-static char_u *p_cink;
-static char_u *p_cino;
-static char_u *p_cinw;
-static char_u *p_cinsd;
-static char_u *p_com;
-static char_u *p_cms;
-static char_u *p_cpt;
-static char_u *p_cfu;
-static char_u *p_ofu;
-static char_u *p_tfu;
-static char_u *p_umf;
-static int p_eol;
-static int p_fixeol;
-static int p_et;
-static char_u *p_fenc;
-static char_u *p_ff;
-static char_u *p_fo;
-static char_u *p_flp;
-static char_u *p_ft;
-static long p_iminsert;
-static long p_imsearch;
-static char_u *p_inex;
-static char_u *p_inde;
-static char_u *p_indk;
-static char_u *p_fex;
-static int p_inf;
-static char_u *p_isk;
-static int p_lisp;
-static int p_ml;
-static int p_ma;
-static int p_mod;
-static char_u *p_mps;
-static char_u *p_nf;
-static int p_pi;
-static char_u *p_qe;
-static int p_ro;
-static int p_si;
-static long p_sts;
-static char_u *p_sua;
-static long p_sw;
-static int p_swf;
-static long p_smc;
-static char_u *p_syn;
-static char_u *p_spc;
-static char_u *p_spf;
-static char_u *p_spl;
-static char_u *p_spo;
-static long p_ts;
-static long p_tw;
-static int p_udf;
-static long p_wm;
-static char_u *p_vsts;
-static char_u *p_vts;
-static char_u *p_keymap;
-
// Saved values for when 'bin' is set.
static int p_et_nobin;
static int p_ml_nobin;
@@ -199,7 +149,7 @@ static int p_et_nopaste;
static long p_sts_nopaste;
static long p_tw_nopaste;
static long p_wm_nopaste;
-static char_u *p_vsts_nopaste;
+static char *p_vsts_nopaste;
typedef struct vimoption {
char *fullname; // full option name
@@ -215,64 +165,6 @@ typedef struct vimoption {
} vimoption_T;
/*
- * Flags
- */
-#define P_BOOL 0x01U // the option is boolean
-#define P_NUM 0x02U // the option is numeric
-#define P_STRING 0x04U // the option is a string
-#define P_ALLOCED 0x08U // the string option is in allocated memory,
- // must use free_string_option() when
- // assigning new value. Not set if default is
- // the same.
-#define P_EXPAND 0x10U // environment expansion. NOTE: P_EXPAND can
- // never be used for local or hidden options
-#define P_NODEFAULT 0x40U // don't set to default value
-#define P_DEF_ALLOCED 0x80U // default value is in allocated memory, must
- // use free() when assigning new value
-#define P_WAS_SET 0x100U // option has been set/reset
-#define P_NO_MKRC 0x200U // don't include in :mkvimrc output
-
-// when option changed, what to display:
-#define P_RSTAT 0x1000U ///< redraw status lines
-#define P_RWIN 0x2000U ///< redraw current window and recompute text
-#define P_RBUF 0x4000U ///< redraw current buffer and recompute text
-#define P_RALL 0x6000U ///< redraw all windows
-#define P_RCLR 0x7000U ///< clear and redraw all
-
-#define P_COMMA 0x8000U ///< comma separated list
-#define P_ONECOMMA 0x18000U ///< P_COMMA and cannot have two consecutive
- ///< commas
-#define P_NODUP 0x20000U ///< don't allow duplicate strings
-#define P_FLAGLIST 0x40000U ///< list of single-char flags
-
-#define P_SECURE 0x80000U ///< cannot change in modeline or secure mode
-#define P_GETTEXT 0x100000U ///< expand default value with _()
-#define P_NOGLOB 0x200000U ///< do not use local value for global vimrc
-#define P_NFNAME 0x400000U ///< only normal file name chars allowed
-#define P_INSECURE 0x800000U ///< option was set from a modeline
-#define P_PRI_MKRC 0x1000000U ///< priority for :mkvimrc (setting option
- ///< has side effects)
-#define P_NO_ML 0x2000000U ///< not allowed in modeline
-#define P_CURSWANT 0x4000000U ///< update curswant required; not needed
- ///< when there is a redraw flag
-#define P_NO_DEF_EXP 0x8000000U ///< Do not expand default value.
-
-#define P_RWINONLY 0x10000000U ///< only redraw current window
-#define P_NDNAME 0x20000000U ///< only normal dir name chars allowed
-#define P_UI_OPTION 0x40000000U ///< send option to remote ui
-#define P_MLE 0x80000000U ///< under control of 'modelineexpr'
-
-#define HIGHLIGHT_INIT \
- "8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText,d:Directory,e:ErrorMsg," \
- "i:IncSearch,l:Search,y:CurSearch,m:MoreMsg,M:ModeMsg,n:LineNr,a:LineNrAbove,b:LineNrBelow," \
- "N:CursorLineNr,G:CursorLineSign,O:CursorLineFold" \
- "r:Question,s:StatusLine,S:StatusLineNC,c:VertSplit,t:Title,v:Visual,V:VisualNOS,w:WarningMsg," \
- "W:WildMenu,f:Folded,F:FoldColumn,A:DiffAdd,C:DiffChange,D:DiffDelete,T:DiffText,>:SignColumn," \
- "-:Conceal,B:SpellBad,P:SpellCap,R:SpellRare,L:SpellLocal,+:Pmenu,=:PmenuSel,x:PmenuSbar," \
- "X:PmenuThumb,*:TabLine,#:TabLineSel,_:TabLineFill,!:CursorColumn,.:CursorLine,o:ColorColumn," \
- "q:QuickFixLine,0:Whitespace,I:NormalNC"
-
-/*
* options[] is initialized here.
* The order of the options MUST be alphabetic for ":set all" and findoption().
* All option names MUST start with a lowercase letter (for findoption()).
@@ -287,59 +179,6 @@ typedef struct vimoption {
#define OPTION_COUNT ARRAY_SIZE(options)
-static char *(p_ambw_values[]) = { "single", "double", NULL };
-static char *(p_bg_values[]) = { "light", "dark", NULL };
-static char *(p_nf_values[]) = { "bin", "octal", "hex", "alpha",
- "unsigned", NULL };
-static char *(p_ff_values[]) = { FF_UNIX, FF_DOS, FF_MAC, NULL };
-static char *(p_wak_values[]) = { "yes", "menu", "no", NULL };
-static char *(p_mousem_values[]) = { "extend", "popup", "popup_setpos",
- "mac", NULL };
-static char *(p_sel_values[]) = { "inclusive", "exclusive", "old", NULL };
-static char *(p_slm_values[]) = { "mouse", "key", "cmd", NULL };
-static char *(p_km_values[]) = { "startsel", "stopsel", NULL };
-static char *(p_scbopt_values[]) = { "ver", "hor", "jump", NULL };
-static char *(p_debug_values[]) = { "msg", "throw", "beep", NULL };
-static char *(p_ead_values[]) = { "both", "ver", "hor", NULL };
-static char *(p_buftype_values[]) = { "nofile", "nowrite", "quickfix",
- "help", "acwrite", "terminal",
- "prompt", NULL };
-
-static char *(p_bufhidden_values[]) = { "hide", "unload", "delete",
- "wipe", NULL };
-static char *(p_bs_values[]) = { "indent", "eol", "start", "nostop", NULL };
-static char *(p_fdm_values[]) = { "manual", "expr", "marker", "indent",
- "syntax", "diff", NULL };
-static char *(p_fcl_values[]) = { "all", NULL };
-static char *(p_cot_values[]) = { "menu", "menuone", "longest", "preview",
- "noinsert", "noselect", NULL };
-#ifdef BACKSLASH_IN_FILENAME
-static char *(p_csl_values[]) = { "slash", "backslash", NULL };
-#endif
-static char *(p_icm_values[]) = { "nosplit", "split", NULL };
-static char *(p_scl_values[]) = { "yes", "no", "auto", "auto:1", "auto:2",
- "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8",
- "auto:9",
- "yes:1", "yes:2", "yes:3", "yes:4", "yes:5", "yes:6",
- "yes:7", "yes:8",
- "yes:9", "number", NULL };
-static char *(p_fdc_values[]) = { "auto", "auto:1", "auto:2",
- "auto:3", "auto:4", "auto:5", "auto:6", "auto:7", "auto:8",
- "auto:9",
- "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", NULL };
-
-/// All possible flags for 'shm'.
-static char_u 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,
-};
-
-static char e_unclosed_expression_sequence[] = N_("E540: Unclosed expression sequence");
-static char e_unbalanced_groups[] = N_("E542: unbalanced groups");
-
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "option.c.generated.h"
#endif
@@ -580,7 +419,7 @@ void set_init_1(bool clean_arg)
// NOTE: mlterm's author is being asked to 'set' a variable
// instead of an environment variable due to inheritance.
if (os_env_exists("MLTERM")) {
- set_option_value("tbidi", 1L, NULL, 0);
+ set_option_value_give_err("tbidi", 1L, NULL, 0);
}
didset_options2();
@@ -600,7 +439,7 @@ void set_init_1(bool clean_arg)
#ifdef HAVE_WORKING_LIBINTL
// GNU gettext 0.10.37 supports this feature: set the codeset used for
// translated messages independently from the current locale.
- (void)bind_textdomain_codeset(PROJECT_NAME, (char *)p_enc);
+ (void)bind_textdomain_codeset(PROJECT_NAME, p_enc);
#endif
// Set the default for 'helplang'.
@@ -616,7 +455,7 @@ static void set_option_default(int opt_idx, int opt_flags)
char_u *varp; // pointer to variable for current option
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
- varp = get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
+ varp = (char_u *)get_varp_scope(&(options[opt_idx]), both ? OPT_LOCAL : opt_flags);
uint32_t flags = options[opt_idx].flags;
if (varp != NULL) { // skip hidden option, nothing to do for it
if (flags & P_STRING) {
@@ -627,7 +466,7 @@ static void set_option_default(int opt_idx, int opt_flags)
(char *)options[opt_idx].def_val, opt_flags, 0);
} else {
if ((opt_flags & OPT_FREE) && (flags & P_ALLOCED)) {
- free_string_option(*(char_u **)(varp));
+ free_string_option(*(char **)(varp));
}
*(char_u **)varp = options[opt_idx].def_val;
options[opt_idx].flags &= ~P_ALLOCED;
@@ -766,16 +605,17 @@ void free_all_options(void)
if (options[i].indir == PV_NONE) {
// global option: free value and default value.
if ((options[i].flags & P_ALLOCED) && options[i].var != NULL) {
- free_string_option(*(char_u **)options[i].var);
+ free_string_option(*(char **)options[i].var);
}
if (options[i].flags & P_DEF_ALLOCED) {
- free_string_option(options[i].def_val);
+ free_string_option((char *)options[i].def_val);
}
} else if (options[i].var != VAR_WIN && (options[i].flags & P_STRING)) {
// buffer-local option: free global value
- clear_string_option((char_u **)options[i].var);
+ clear_string_option((char **)options[i].var);
}
}
+ free_operatorfunc_option();
}
#endif
@@ -835,12 +675,12 @@ void set_init_3(void)
if (FNAMECMP(p, "csh") == 0
|| FNAMECMP(p, "tcsh") == 0) {
if (do_sp) {
- p_sp = (char_u *)"|& tee";
- options[idx_sp].def_val = p_sp;
+ p_sp = "|& tee";
+ options[idx_sp].def_val = (char_u *)p_sp;
}
if (do_srr) {
- p_srr = (char_u *)">&";
- options[idx_srr].def_val = p_srr;
+ p_srr = ">&";
+ options[idx_srr].def_val = (char_u *)p_srr;
}
} else if (FNAMECMP(p, "sh") == 0
|| FNAMECMP(p, "ksh") == 0
@@ -854,12 +694,12 @@ void set_init_3(void)
|| FNAMECMP(p, "dash") == 0) {
// Always use POSIX shell style redirection if we reach this
if (do_sp) {
- p_sp = (char_u *)"2>&1| tee";
- options[idx_sp].def_val = p_sp;
+ p_sp = "2>&1| tee";
+ options[idx_sp].def_val = (char_u *)p_sp;
}
if (do_srr) {
- p_srr = (char_u *)">%s 2>&1";
- options[idx_srr].def_val = p_srr;
+ p_srr = ">%s 2>&1";
+ options[idx_srr].def_val = (char_u *)p_srr;
}
}
xfree(p);
@@ -892,7 +732,7 @@ void set_helplang_default(const char *lang)
int idx = findoption("hlg");
if (idx >= 0 && !(options[idx].flags & P_WAS_SET)) {
if (options[idx].flags & P_ALLOCED) {
- free_string_option(p_hlg);
+ free_string_option((char *)p_hlg);
}
p_hlg = (char_u *)xmemdupz(lang, lang_len);
// zh_CN becomes "cn", zh_TW becomes "tw".
@@ -970,7 +810,7 @@ int do_set(char *arg, int opt_flags)
int opt_idx;
char *errmsg;
char errbuf[80];
- char_u *startarg;
+ char *startarg;
int prefix; // 1: nothing, 0: "no", 2: "inv" in front of name
char_u nextchar; // next non-white char after option name
int afterchar; // character just after option name
@@ -979,7 +819,7 @@ int do_set(char *arg, int opt_flags)
varnumber_T value;
int key;
uint32_t flags; // flags for current option
- char_u *varp = NULL; // pointer to variable for current option
+ char *varp = NULL; // pointer to variable for current option
int did_show = false; // already showed one value
int adding; // "opt+=arg"
int prepending; // "opt^=arg"
@@ -993,7 +833,7 @@ int do_set(char *arg, int opt_flags)
while (*arg != NUL) { // loop to process all options
errmsg = NULL;
- startarg = (char_u *)arg; // remember for error message
+ startarg = arg; // remember for error message
if (STRNCMP(arg, "all", 3) == 0 && !isalpha(arg[3])
&& !(opt_flags & OPT_MODELINE)) {
@@ -1009,7 +849,7 @@ int do_set(char *arg, int opt_flags)
didset_options();
didset_options2();
ui_refresh_options();
- redraw_all_later(CLEAR);
+ redraw_all_later(UPD_CLEAR);
} else {
showoptions(1, opt_flags);
did_show = true;
@@ -1090,7 +930,7 @@ int do_set(char *arg, int opt_flags)
nextchar = (uint8_t)arg[len];
if (opt_idx == -1 && key == 0) { // found a mismatch: skip
- errmsg = N_("E518: Unknown option");
+ errmsg = e_unknown_option;
goto skip;
}
@@ -1101,7 +941,7 @@ int do_set(char *arg, int opt_flags)
if (vim_strchr("=:!&<", nextchar) == NULL
&& (!(options[opt_idx].flags & P_BOOL)
|| nextchar == '?')) {
- errmsg = _(e_unsupportedoption);
+ errmsg = e_unsupportedoption;
}
goto skip;
}
@@ -1128,11 +968,11 @@ int do_set(char *arg, int opt_flags)
// Disallow changing some options from modelines.
if (opt_flags & OPT_MODELINE) {
if (flags & (P_SECURE | P_NO_ML)) {
- errmsg = N_("E520: Not allowed in a modeline");
+ errmsg = e_not_allowed_in_modeline;
goto skip;
}
if ((flags & P_MLE) && !p_mle) {
- errmsg = N_("E992: Not allowed in a modeline when 'modelineexpr' is off");
+ errmsg = e_not_allowed_in_modeline_when_modelineexpr_is_off;
goto skip;
}
// In diff mode some options are overruled. This avoids that
@@ -1189,7 +1029,7 @@ int do_set(char *arg, int opt_flags)
showoneopt(&options[opt_idx], opt_flags);
if (p_verbose > 0) {
// Mention where the option was last set.
- if (varp == options[opt_idx].var) {
+ if (varp == (char *)options[opt_idx].var) {
option_last_set_msg(options[opt_idx].last_set);
} else if ((int)options[opt_idx].indir & PV_WIN) {
option_last_set_msg(curwin->w_p_script_ctx[
@@ -1200,7 +1040,7 @@ int do_set(char *arg, int opt_flags)
}
}
} else {
- errmsg = N_("E846: Key code not set");
+ errmsg = e_key_code_not_set;
goto skip;
}
if (nextchar != '?'
@@ -1251,8 +1091,7 @@ int do_set(char *arg, int opt_flags)
}
}
- errmsg = set_bool_option(opt_idx, varp, (int)value,
- opt_flags);
+ errmsg = set_bool_option(opt_idx, (char_u *)varp, (int)value, opt_flags);
} else { // Numeric or string.
if (vim_strchr("=:&<", nextchar) == NULL
|| prefix != 1) {
@@ -1294,11 +1133,11 @@ int do_set(char *arg, int opt_flags)
// Allow negative, octal and hex numbers.
vim_str2nr((char_u *)arg, NULL, &i, STR2NR_ALL, &value, NULL, 0, true);
if (i == 0 || (arg[i] != NUL && !ascii_iswhite(arg[i]))) {
- errmsg = N_("E521: Number required after =");
+ errmsg = e_number_required_after_equal;
goto skip;
}
} else {
- errmsg = N_("E521: Number required after =");
+ errmsg = e_number_required_after_equal;
goto skip;
}
@@ -1311,7 +1150,7 @@ int do_set(char *arg, int opt_flags)
if (removing) {
value = *(long *)varp - value;
}
- errmsg = set_num_option(opt_idx, varp, (long)value,
+ errmsg = set_num_option(opt_idx, (char_u *)varp, (long)value,
errbuf, sizeof(errbuf),
opt_flags);
} else if (opt_idx >= 0) { // String.
@@ -1334,7 +1173,7 @@ int do_set(char *arg, int opt_flags)
// reset, use the global value here.
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
&& ((int)options[opt_idx].indir & PV_BOTH)) {
- varp = options[opt_idx].var;
+ varp = (char *)options[opt_idx].var;
}
// The old value is kept until we are sure that the
@@ -1348,7 +1187,7 @@ int do_set(char *arg, int opt_flags)
// A global-local string option might have an empty
// option as value to indicate that the global
// value should be used.
- if (((int)options[opt_idx].indir & PV_BOTH) && origval_l == empty_option) {
+ if (((int)options[opt_idx].indir & PV_BOTH) && origval_l == (char_u *)empty_option) {
origval_l = origval_g;
}
}
@@ -1368,7 +1207,7 @@ int do_set(char *arg, int opt_flags)
// required when an environment variable was set
// later
if (newval == NULL) {
- newval = empty_option;
+ newval = (char_u *)empty_option;
} else if (!(options[opt_idx].flags & P_NO_DEF_EXP)) {
s = option_expand(opt_idx, newval);
if (s == NULL) {
@@ -1383,27 +1222,20 @@ int do_set(char *arg, int opt_flags)
} else {
arg++; // jump to after the '=' or ':'
- /*
- * Set 'keywordprg' to ":help" if an empty
- * value was passed to :set by the user.
- * Misuse errbuf[] for the resulting string.
- */
- if (varp == (char_u *)&p_kp
- && (*arg == NUL || *arg == ' ')) {
+ // Set 'keywordprg' to ":help" if an empty
+ // value was passed to :set by the user.
+ // Misuse errbuf[] for the resulting string.
+ if (varp == (char *)&p_kp && (*arg == NUL || *arg == ' ')) {
STRCPY(errbuf, ":help");
save_arg = (char_u *)arg;
arg = errbuf;
- }
- /*
- * Convert 'backspace' number to string, for
- * adding, prepending and removing string.
- */
- else if (varp == (char_u *)&p_bs
- && ascii_isdigit(**(char_u **)varp)) {
+ } else if (varp == (char *)&p_bs && ascii_isdigit(**(char_u **)varp)) {
+ // Convert 'backspace' number to string, for
+ // adding, prepending and removing string.
i = getdigits_int((char **)varp, true, 0);
switch (i) {
case 0:
- *(char_u **)varp = empty_option;
+ *(char **)varp = empty_option;
break;
case 1:
*(char_u **)varp = vim_strsave((char_u *)"indent,eol");
@@ -1426,14 +1258,10 @@ int do_set(char *arg, int opt_flags)
origval_g = *(char_u **)varp;
}
oldval = *(char_u **)varp;
- }
- /*
- * Convert 'whichwrap' number to string, for
- * backwards compatibility with Vim 3.0.
- * Misuse errbuf[] for the resulting string.
- */
- else if (varp == (char_u *)&p_ww
- && ascii_isdigit(*arg)) {
+ } else if (varp == (char *)&p_ww && ascii_isdigit(*arg)) {
+ // Convert 'whichwrap' number to string, for
+ // backwards compatibility with Vim 3.0.
+ // Misuse errbuf[] for the resulting string.
*errbuf = NUL;
i = getdigits_int(&arg, true, 0);
if (i & 1) {
@@ -1453,14 +1281,11 @@ int do_set(char *arg, int opt_flags)
}
save_arg = (char_u *)arg;
arg = errbuf;
- }
- /*
- * Remove '>' before 'dir' and 'bdir', for
- * backwards compatibility with version 3.0
- */
- else if (*arg == '>'
- && (varp == (char_u *)&p_dir
- || varp == (char_u *)&p_bdir)) {
+ } else if (*arg == '>'
+ && (varp == (char *)&p_dir
+ || varp == (char *)&p_bdir)) {
+ // Remove '>' before 'dir' and 'bdir', for
+ // backwards compatibility with version 3.0
arg++;
}
@@ -1658,7 +1483,7 @@ int do_set(char *arg, int opt_flags)
// for ":set" on local options. Note: when setting
// 'syntax' or 'filetype' autocommands may be
// triggered that can cause havoc.
- errmsg = did_set_string_option(opt_idx, (char_u **)varp, oldval,
+ errmsg = did_set_string_option(opt_idx, (char **)varp, (char *)oldval,
errbuf, sizeof(errbuf),
opt_flags, &value_checked);
@@ -1718,17 +1543,17 @@ skip:
if (errmsg != NULL) {
STRLCPY(IObuff, _(errmsg), IOSIZE);
i = (int)STRLEN(IObuff) + 2;
- if (i + ((char_u *)arg - startarg) < IOSIZE) {
+ if (i + (arg - startarg) < IOSIZE) {
// append the argument with the error
STRCAT(IObuff, ": ");
- assert((char_u *)arg >= startarg);
- memmove(IObuff + i, startarg, (size_t)((char_u *)arg - startarg));
- IObuff[i + ((char_u *)arg - startarg)] = NUL;
+ assert(arg >= startarg);
+ memmove(IObuff + i, startarg, (size_t)(arg - startarg));
+ IObuff[i + (arg - startarg)] = NUL;
}
// make sure all characters are printable
trans_characters((char *)IObuff, IOSIZE);
- no_wait_return++; // wait_return done later
+ no_wait_return++; // wait_return() done later
emsg((char *)IObuff); // show error highlighted
no_wait_return--;
@@ -1758,7 +1583,7 @@ theend:
/// @param opt_flags possibly with OPT_MODELINE
/// @param new_value value was replaced completely
/// @param value_checked value was checked to be safe, no need to set P_INSECURE
-static void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked)
+void did_set_option(int opt_idx, int opt_flags, int new_value, int value_checked)
{
options[opt_idx].flags |= P_WAS_SET;
@@ -1775,19 +1600,9 @@ static void did_set_option(int opt_idx, int opt_flags, int new_value, int value_
}
}
-static char *illegal_char(char *errbuf, size_t errbuflen, int c)
-{
- if (errbuf == NULL) {
- return "";
- }
- vim_snprintf(errbuf, errbuflen, _("E539: Illegal character <%s>"),
- (char *)transchar(c));
- return errbuf;
-}
-
/// Convert a key name or string into a key value.
/// Used for 'wildchar' and 'cedit' options.
-static int string_to_key(char_u *arg)
+int string_to_key(char_u *arg)
{
if (*arg == '<') {
return find_key_option(arg + 1, true);
@@ -1798,29 +1613,11 @@ static int string_to_key(char_u *arg)
return *arg;
}
-/// Check value of 'cedit' and set cedit_key.
-/// Returns NULL if value is OK, error message otherwise.
-static char *check_cedit(void)
-{
- int n;
-
- if (*p_cedit == NUL) {
- cedit_key = -1;
- } else {
- n = string_to_key(p_cedit);
- if (vim_isprintc(n)) {
- return e_invarg;
- }
- cedit_key = n;
- }
- return NULL;
-}
-
// When changing 'title', 'titlestring', 'icon' or 'iconstring', call
// maketitle() to create and display it.
// When switching the title or icon off, call ui_set_{icon,title}(NULL) to get
// the old value back.
-static void did_set_title(void)
+void did_set_title(void)
{
if (starting != NO_SCREEN) {
maketitle();
@@ -1902,16 +1699,14 @@ int get_shada_parameter(int type)
/// Return NULL if the parameter is not specified in the string.
char_u *find_shada_parameter(int type)
{
- char_u *p;
-
- for (p = p_shada; *p; p++) {
+ for (char *p = p_shada; *p; p++) {
if (*p == type) {
- return p + 1;
+ return (char_u *)p + 1;
}
if (*p == 'n') { // 'n' is always the last one
break;
}
- p = (char_u *)vim_strchr((char *)p, ','); // skip until next ','
+ p = vim_strchr(p, ','); // skip until next ','
if (p == NULL) { // hit the end without finding parameter
break;
}
@@ -1946,35 +1741,15 @@ static char_u *option_expand(int opt_idx, char_u *val)
* names.
* For 'spellsuggest' expand after "file:".
*/
- expand_env_esc(val, NameBuff, MAXPATHL,
+ expand_env_esc(val, (char_u *)NameBuff, MAXPATHL,
(char_u **)options[opt_idx].var == &p_tags, false,
- (char_u **)options[opt_idx].var == &p_sps ? (char_u *)"file:" :
+ (char_u **)options[opt_idx].var == (char_u **)&p_sps ? (char_u *)"file:" :
NULL);
if (STRCMP(NameBuff, val) == 0) { // they are the same
return NULL;
}
- return NameBuff;
-}
-
-/// After setting various option values: recompute variables that depend on
-/// option values.
-static void didset_string_options(void)
-{
- (void)opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, true);
- (void)opt_strings_flags(p_bkc, p_bkc_values, &bkc_flags, true);
- (void)opt_strings_flags(p_bo, p_bo_values, &bo_flags, true);
- (void)opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, true);
- (void)opt_strings_flags(p_vop, p_ssop_values, &vop_flags, true);
- (void)opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, true);
- (void)opt_strings_flags(p_dy, p_dy_values, &dy_flags, true);
- (void)opt_strings_flags(p_rdb, p_rdb_values, &rdb_flags, true);
- (void)opt_strings_flags(p_tc, p_tc_values, &tc_flags, false);
- (void)opt_strings_flags(p_tpf, p_tpf_values, &tpf_flags, true);
- (void)opt_strings_flags(p_ve, p_ve_values, &ve_flags, true);
- (void)opt_strings_flags(p_swb, p_swb_values, &swb_flags, true);
- (void)opt_strings_flags(p_wop, p_wop_values, &wop_flags, true);
- (void)opt_strings_flags(p_jop, p_jop_values, &jop_flags, true);
+ return (char_u *)NameBuff;
}
/// After setting various option values: recompute variables that depend on
@@ -1994,7 +1769,7 @@ static void didset_options(void)
(void)check_cedit();
// initialize the table for 'breakat'.
fill_breakat_flags();
- didset_window_options(curwin);
+ didset_window_options(curwin, true);
}
// More side effects of setting options.
@@ -2003,9 +1778,6 @@ static void didset_options2(void)
// Initialize the highlight_attr[] table.
highlight_changed();
- // Parse default for 'clipboard'.
- (void)opt_strings_flags(p_cb, p_cb_values, &cb_flags, true);
-
// Parse default for 'fillchars'.
(void)set_chars_option(curwin, &curwin->w_p_fcs, true);
@@ -2027,96 +1799,11 @@ void check_options(void)
for (opt_idx = 0; options[opt_idx].fullname != NULL; opt_idx++) {
if ((options[opt_idx].flags & P_STRING) && options[opt_idx].var != NULL) {
- check_string_option((char_u **)get_varp(&(options[opt_idx])));
+ check_string_option((char **)get_varp(&(options[opt_idx])));
}
}
}
-/// Check string options in a buffer for NULL value.
-void check_buf_options(buf_T *buf)
-{
- check_string_option(&buf->b_p_bh);
- check_string_option(&buf->b_p_bt);
- check_string_option(&buf->b_p_fenc);
- check_string_option(&buf->b_p_ff);
- check_string_option(&buf->b_p_def);
- check_string_option(&buf->b_p_inc);
- check_string_option(&buf->b_p_inex);
- check_string_option(&buf->b_p_inde);
- check_string_option(&buf->b_p_indk);
- check_string_option(&buf->b_p_fp);
- check_string_option(&buf->b_p_fex);
- check_string_option(&buf->b_p_kp);
- check_string_option(&buf->b_p_mps);
- check_string_option(&buf->b_p_fo);
- check_string_option(&buf->b_p_flp);
- check_string_option(&buf->b_p_isk);
- check_string_option(&buf->b_p_com);
- check_string_option(&buf->b_p_cms);
- check_string_option(&buf->b_p_nf);
- check_string_option(&buf->b_p_qe);
- check_string_option(&buf->b_p_syn);
- check_string_option(&buf->b_s.b_syn_isk);
- check_string_option(&buf->b_s.b_p_spc);
- check_string_option(&buf->b_s.b_p_spf);
- check_string_option(&buf->b_s.b_p_spl);
- check_string_option(&buf->b_s.b_p_spo);
- check_string_option(&buf->b_p_sua);
- check_string_option(&buf->b_p_cink);
- check_string_option(&buf->b_p_cino);
- parse_cino(buf);
- check_string_option(&buf->b_p_ft);
- check_string_option(&buf->b_p_cinw);
- check_string_option(&buf->b_p_cinsd);
- check_string_option(&buf->b_p_cpt);
- check_string_option(&buf->b_p_cfu);
- check_string_option(&buf->b_p_ofu);
- check_string_option(&buf->b_p_keymap);
- check_string_option(&buf->b_p_gp);
- check_string_option(&buf->b_p_mp);
- check_string_option(&buf->b_p_efm);
- check_string_option(&buf->b_p_ep);
- check_string_option(&buf->b_p_path);
- check_string_option(&buf->b_p_tags);
- check_string_option(&buf->b_p_tfu);
- check_string_option(&buf->b_p_tc);
- check_string_option(&buf->b_p_dict);
- check_string_option(&buf->b_p_tsr);
- check_string_option(&buf->b_p_tsrfu);
- check_string_option(&buf->b_p_lw);
- check_string_option(&buf->b_p_bkc);
- check_string_option(&buf->b_p_menc);
- check_string_option(&buf->b_p_vsts);
- check_string_option(&buf->b_p_vts);
-}
-
-/// 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
-/// check_options().
-/// Does NOT check for P_ALLOCED flag!
-void free_string_option(char_u *p)
-{
- if (p != empty_option) {
- xfree(p);
- }
-}
-
-void clear_string_option(char_u **pp)
-{
- if (*pp != empty_option) {
- xfree(*pp);
- }
- *pp = empty_option;
-}
-
-static void check_string_option(char_u **pp)
-{
- if (*pp == NULL) {
- *pp = empty_option;
- }
-}
-
/// Return true when option "opt" was set from a modeline or in secure mode.
/// Return false when it wasn't.
/// Return -1 for an unknown option.
@@ -2163,172 +1850,18 @@ static uint32_t *insecure_flag(win_T *const wp, int opt_idx, int opt_flags)
}
/// Redraw the window title and/or tab page text later.
-static void redraw_titles(void)
+void redraw_titles(void)
{
need_maketitle = true;
redraw_tabline = true;
}
-static int shada_idx = -1;
-
-/// Set a string option to a new value (without checking the effect).
-/// The string is copied into allocated memory.
-/// if ("opt_idx" == -1) "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 OPT_FREE, OPT_LOCAL and/or OPT_GLOBAL
-void set_string_option_direct(const char *name, int opt_idx, const char *val, int opt_flags,
- int set_sid)
-{
- char *s;
- char **varp;
- int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
- int idx = opt_idx;
-
- if (idx == -1) { // Use name.
- idx = findoption(name);
- if (idx < 0) { // Not found (should not happen).
- internal_error("set_string_option_direct()");
- siemsg(_("For option %s"), name);
- return;
- }
- }
-
- if (options[idx].var == NULL) { // can't set hidden option
- return;
- }
-
- assert((void *)options[idx].var != (void *)&p_shada);
-
- s = xstrdup(val);
- {
- varp = (char **)get_varp_scope(&(options[idx]), both ? OPT_LOCAL : opt_flags);
- if ((opt_flags & OPT_FREE) && (options[idx].flags & P_ALLOCED)) {
- free_string_option((char_u *)(*varp));
- }
- *varp = s;
-
- // For buffer/window local option may also set the global value.
- if (both) {
- set_string_option_global(idx, (char_u **)varp);
- }
-
- options[idx].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 (((int)options[idx].indir & PV_BOTH) && both) {
- free_string_option((char_u *)(*varp));
- *varp = (char *)empty_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_idx(idx, opt_flags, script_ctx);
- }
- }
-}
-
-/// Set global value for string option when it's a local option.
-///
-/// @param opt_idx option index
-/// @param varp pointer to option variable
-static void set_string_option_global(int opt_idx, char_u **varp)
-{
- char_u **p, *s;
-
- // the global value is always allocated
- if (options[opt_idx].var == VAR_WIN) {
- p = (char_u **)GLOBAL_WO(varp);
- } else {
- p = (char_u **)options[opt_idx].var;
- }
- if (options[opt_idx].indir != PV_NONE && p != varp) {
- s = vim_strsave(*varp);
- free_string_option(*p);
- *p = s;
- }
-}
-
-/// Set a string option to a new value, handling the effects
-///
-/// @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, error message on error.
-static 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 (options[opt_idx].var == NULL) { // don't set hidden option
- return NULL;
- }
-
- char *const s = xstrdup(value);
- char **const varp = (char **)get_varp_scope(&(options[opt_idx]),
- ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
- ? (((int)options[opt_idx].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_varp_scope(&(options[opt_idx]), OPT_LOCAL);
- oldval_g = *(char **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
- }
-
- *varp = s;
-
- char *const saved_oldval = xstrdup(oldval);
- char *const saved_oldval_l = (oldval_l != NULL) ? xstrdup(oldval_l) : 0;
- char *const saved_oldval_g = (oldval_g != NULL) ? xstrdup(oldval_g) : 0;
- char *const saved_newval = xstrdup(s);
-
- int value_checked = false;
- char *const r = did_set_string_option(opt_idx, (char_u **)varp, (char_u *)oldval,
- NULL, 0,
- opt_flags, &value_checked);
- if (r == NULL) {
- did_set_option(opt_idx, opt_flags, true, value_checked);
- }
-
- // call autocommand after handling side effects
- if (r == NULL) {
- if (!starting) {
- trigger_optionsset_string(opt_idx, opt_flags, saved_oldval, saved_oldval_l, saved_oldval_g,
- saved_newval);
- }
- if (options[opt_idx].flags & P_UI_OPTION) {
- ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
- STRING_OBJ(cstr_as_string(saved_newval)));
- }
- }
- xfree(saved_oldval);
- xfree(saved_oldval_l);
- xfree(saved_oldval_g);
- xfree(saved_newval);
-
- return r;
-}
-
/// Return true if "val" is a valid name: only consists of alphanumeric ASCII
/// characters or characters in "allowed".
-static bool valid_name(const char_u *val, const char *allowed)
+bool valid_name(const char *val, const char *allowed)
FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
- for (const char_u *s = val; *s != NUL; s++) {
+ for (const char_u *s = (char_u *)val; *s != NUL; s++) {
if (!ASCII_ISALNUM(*s)
&& vim_strchr(allowed, *s) == NULL) {
return false;
@@ -2337,1632 +1870,36 @@ static bool valid_name(const char_u *val, const char *allowed)
return true;
}
-/// Return true if "val" is a valid 'filetype' name.
-/// Also used for 'syntax' and 'keymap'.
-static bool valid_filetype(const char_u *val)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- return valid_name(val, ".-_");
-}
-
-/// Return true if "val" is a valid 'spelllang' value.
-bool valid_spelllang(const char_u *val)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- return valid_name(val, ".-_,@");
-}
-
-/// Return true if "val" is a valid 'spellfile' value.
-static bool valid_spellfile(const char_u *val)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- for (const char_u *s = val; *s != NUL; s++) {
- if (!vim_isfilec(*s) && *s != ',' && *s != ' ') {
- return false;
- }
- }
- return true;
-}
-
-/// Handle setting 'mousescroll'.
-/// @return error message, NULL if it's OK.
-static char *check_mousescroll(char *string)
-{
- long vertical = -1;
- long horizontal = -1;
-
- for (;;) {
- char *end = vim_strchr(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.
- if (length <= 4) {
- return e_invarg;
- }
-
- long *direction;
-
- if (memcmp(string, "ver:", 4) == 0) {
- direction = &vertical;
- } else if (memcmp(string, "hor:", 4) == 0) {
- direction = &horizontal;
- } else {
- return e_invarg;
- }
-
- // If the direction has already been set, this is a duplicate.
- if (*direction != -1) {
- return e_invarg;
- }
-
- // Verify that only digits follow the colon.
- for (size_t i = 4; i < length; i++) {
- if (!ascii_isdigit(string[i])) {
- return N_("E548: digit expected");
- }
- }
-
- string += 4;
- *direction = getdigits_int(&string, false, -1);
-
- // Num options are generally kept within the signed int range.
- // We know this number won't be negative because we've already checked for
- // a minus sign. We'll allow 0 as a means of disabling mouse scrolling.
- if (*direction == -1) {
- return e_invarg;
- }
-
- if (!end) {
- break;
- }
-
- string = end + 1;
- }
-
- // If a direction wasn't set, fallback to the default value.
- p_mousescroll_vert = (vertical == -1) ? MOUSESCROLL_VERT_DFLT : vertical;
- p_mousescroll_hor = (horizontal == -1) ? MOUSESCROLL_HOR_DFLT : horizontal;
-
- return NULL;
-}
-
-/// Handle string options that need some action to perform when changed.
-/// The new value must be allocated.
-/// Returns NULL for success, or an error message for an error.
-///
-/// @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 value_checked value was checked to be safe, no need to set P_INSECURE
-static char *did_set_string_option(int opt_idx, char_u **varp, char_u *oldval, char *errbuf,
- size_t errbuflen, int opt_flags, int *value_checked)
-{
- char *errmsg = NULL;
- char_u *s, *p;
- int did_chartab = false;
- char_u **gvarp;
- bool free_oldval = (options[opt_idx].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. */
- gvarp = (char_u **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
-
- // Disallow changing some options from secure mode
- if ((secure || sandbox != 0)
- && (options[opt_idx].flags & P_SECURE)) {
- errmsg = e_secure;
- } else if (((options[opt_idx].flags & P_NFNAME)
- && strpbrk((char *)(*varp),
- (secure ? "/\\*?[|;&<>\r\n" : "/\\*?[<>\r\n")) != NULL)
- || ((options[opt_idx].flags & P_NDNAME)
- && strpbrk((char *)(*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
- // are often illegal in a file name. Be more permissive if "secure" is off.
- errmsg = e_invarg;
- } else if (gvarp == &p_bkc) { // 'backupcopy'
- char_u *bkc = p_bkc;
- unsigned int *flags = &bkc_flags;
-
- if (opt_flags & OPT_LOCAL) {
- bkc = curbuf->b_p_bkc;
- flags = &curbuf->b_bkc_flags;
- }
-
- if ((opt_flags & OPT_LOCAL) && *bkc == NUL) {
- // make the local value empty: use the global value
- *flags = 0;
- } else {
- if (opt_strings_flags(bkc, p_bkc_values, flags, true) != OK) {
- errmsg = e_invarg;
- }
-
- if (((*flags & BKC_AUTO) != 0)
- + ((*flags & BKC_YES) != 0)
- + ((*flags & BKC_NO) != 0) != 1) {
- // Must have exactly one of "auto", "yes" and "no".
- (void)opt_strings_flags(oldval, p_bkc_values, flags, true);
- errmsg = e_invarg;
- }
- }
- } else if (varp == &p_bex || varp == &p_pm) { // 'backupext' and 'patchmode'
- if (STRCMP(*p_bex == '.' ? p_bex + 1 : p_bex,
- *p_pm == '.' ? p_pm + 1 : p_pm) == 0) {
- errmsg = N_("E589: 'backupext' and 'patchmode' are equal");
- }
- } else if (varp == &curwin->w_p_briopt) { // 'breakindentopt'
- if (briopt_check(curwin) == FAIL) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_isi
- || varp == &(curbuf->b_p_isk)
- || varp == &p_isp
- || varp == &p_isf) {
- // 'isident', 'iskeyword', 'isprint or 'isfname' option: refill g_chartab[]
- // If the new option is invalid, use old value. 'lisp' option: refill
- // g_chartab[] for '-' char
- if (init_chartab() == FAIL) {
- did_chartab = true; // need to restore it below
- errmsg = e_invarg; // error in value
- }
- } else if (varp == &p_hf) { // 'helpfile'
- // May compute new values for $VIM and $VIMRUNTIME
- if (didset_vim) {
- os_setenv("VIM", "", 1);
- didset_vim = false;
- }
- if (didset_vimruntime) {
- os_setenv("VIMRUNTIME", "", 1);
- didset_vimruntime = false;
- }
- } else if (varp == &p_rtp || varp == &p_pp) { // 'runtimepath' 'packpath'
- runtime_search_path_invalidate();
- } else if (varp == &curwin->w_p_culopt
- || gvarp == &curwin->w_allbuf_opt.wo_culopt) { // 'cursorlineopt'
- if (**varp == NUL || fill_culopt_flags(*varp, curwin) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &curwin->w_p_cc) { // 'colorcolumn'
- errmsg = check_colorcolumn(curwin);
- } else if (varp == &p_hlg) { // 'helplang'
- // Check for "", "ab", "ab,cd", etc.
- for (s = p_hlg; *s != NUL; s += 3) {
- if (s[1] == NUL || ((s[2] != ',' || s[3] == NUL) && s[2] != NUL)) {
- errmsg = e_invarg;
- break;
- }
- if (s[2] == NUL) {
- break;
- }
- }
- } else if (varp == &p_hl) {
- // 'highlight'
- if (STRCMP(*varp, HIGHLIGHT_INIT) != 0) {
- errmsg = e_unsupportedoption;
- }
- } else if (varp == &p_jop) { // 'jumpoptions'
- if (opt_strings_flags(p_jop, p_jop_values, &jop_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (gvarp == &p_nf) { // 'nrformats'
- if (check_opt_strings(*varp, p_nf_values, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_ssop) { // 'sessionoptions'
- if (opt_strings_flags(p_ssop, p_ssop_values, &ssop_flags, true) != OK) {
- errmsg = e_invarg;
- }
- if ((ssop_flags & SSOP_CURDIR) && (ssop_flags & SSOP_SESDIR)) {
- // Don't allow both "sesdir" and "curdir".
- (void)opt_strings_flags(oldval, p_ssop_values, &ssop_flags, true);
- errmsg = e_invarg;
- }
- } else if (varp == &p_vop) { // 'viewoptions'
- if (opt_strings_flags(p_vop, p_ssop_values, &vop_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_rdb) { // 'redrawdebug'
- if (opt_strings_flags(p_rdb, p_rdb_values, &rdb_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == (char_u **)&p_sbo) { // 'scrollopt'
- if (check_opt_strings((char_u *)p_sbo, p_scbopt_values, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_ambw || (int *)varp == &p_emoji) {
- // 'ambiwidth'
- if (check_opt_strings(p_ambw, p_ambw_values, false) != OK) {
- errmsg = e_invarg;
- } else {
- FOR_ALL_TAB_WINDOWS(tp, wp) {
- if (set_chars_option(wp, &wp->w_p_lcs, true) != NULL) {
- errmsg = _("E834: Conflicts with value of 'listchars'");
- goto ambw_end;
- }
- if (set_chars_option(wp, &wp->w_p_fcs, true) != NULL) {
- errmsg = _("E835: Conflicts with value of 'fillchars'");
- goto ambw_end;
- }
- }
-ambw_end:
- {} // clint prefers {} over ; as an empty statement
- }
- } else if (varp == &p_bg) { // 'background'
- if (check_opt_strings(p_bg, p_bg_values, false) == OK) {
- int dark = (*p_bg == 'd');
-
- init_highlight(false, false);
-
- if (dark != (*p_bg == 'd') && get_var_value("g:colors_name") != NULL) {
- // The color scheme must have set 'background' back to another
- // value, that's not what we want here. Disable the color
- // scheme and set the colors again.
- do_unlet(S_LEN("g:colors_name"), true);
- free_string_option(p_bg);
- p_bg = vim_strsave((char_u *)(dark ? "dark" : "light"));
- check_string_option(&p_bg);
- init_highlight(false, false);
- }
- } else {
- errmsg = e_invarg;
- }
- } else if (varp == &p_wim) { // 'wildmode'
- if (check_opt_wim() == FAIL) {
- errmsg = e_invarg;
- }
- // 'wildoptions'
- } else if (varp == &p_wop) {
- if (opt_strings_flags(p_wop, p_wop_values, &wop_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_wak) { // 'winaltkeys'
- if (*p_wak == NUL
- || check_opt_strings(p_wak, p_wak_values, false) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_ei) { // 'eventignore'
- if (check_ei() == FAIL) {
- errmsg = e_invarg;
- }
- // 'encoding', 'fileencoding' and 'makeencoding'
- } else if (varp == &p_enc || gvarp == &p_fenc || gvarp == &p_menc) {
- if (gvarp == &p_fenc) {
- if (!MODIFIABLE(curbuf) && opt_flags != OPT_GLOBAL) {
- errmsg = e_modifiable;
- } else if (vim_strchr((char *)(*varp), ',') != NULL) {
- // No comma allowed in 'fileencoding'; catches confusing it
- // with 'fileencodings'.
- errmsg = e_invarg;
- } else {
- // May show a "+" in the title now.
- redraw_titles();
- // Add 'fileencoding' to the swap file.
- ml_setflags(curbuf);
- }
- }
-
- if (errmsg == NULL) {
- // 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) {
- 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;
- } else {
- int secure_save = secure;
-
- // Reset the secure flag, since the value of 'keymap' has
- // been checked to be safe.
- secure = 0;
-
- // load or unload key mapping tables
- errmsg = keymap_init();
-
- secure = secure_save;
-
- // Since we check the value, there is no need to set P_INSECURE,
- // even when the value comes from a modeline.
- *value_checked = true;
- }
-
- if (errmsg == NULL) {
- if (*curbuf->b_p_keymap != NUL) {
- // Installed a new keymap, switch on using it.
- curbuf->b_p_iminsert = B_IMODE_LMAP;
- if (curbuf->b_p_imsearch != B_IMODE_USE_INSERT) {
- curbuf->b_p_imsearch = B_IMODE_LMAP;
- }
- } else {
- // Cleared the keymap, may reset 'iminsert' and 'imsearch'.
- if (curbuf->b_p_iminsert == B_IMODE_LMAP) {
- curbuf->b_p_iminsert = B_IMODE_NONE;
- }
- if (curbuf->b_p_imsearch == B_IMODE_LMAP) {
- curbuf->b_p_imsearch = B_IMODE_USE_INSERT;
- }
- }
- if ((opt_flags & OPT_LOCAL) == 0) {
- set_iminsert_global();
- set_imsearch_global();
- }
- status_redraw_curbuf();
- }
- } else if (gvarp == &p_ff) { // 'fileformat'
- if (!MODIFIABLE(curbuf) && !(opt_flags & OPT_GLOBAL)) {
- errmsg = e_modifiable;
- } else if (check_opt_strings(*varp, p_ff_values, false) != OK) {
- errmsg = e_invarg;
- } else {
- redraw_titles();
- // update flag in swap file
- ml_setflags(curbuf);
- /* Redraw needed when switching to/from "mac": a CR in the text
- * will be displayed differently. */
- if (get_fileformat(curbuf) == EOL_MAC || *oldval == 'm') {
- redraw_curbuf_later(NOT_VALID);
- }
- }
- } else if (varp == (char_u **)&p_ffs) { // 'fileformats'
- if (check_opt_strings((char_u *)p_ffs, p_ff_values, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (gvarp == &p_mps) { // 'matchpairs'
- for (p = *varp; *p != NUL; p++) {
- int x2 = -1;
- int x3 = -1;
-
- p += utfc_ptr2len((char *)p);
- if (*p != NUL) {
- x2 = *p++;
- }
- if (*p != NUL) {
- x3 = utf_ptr2char((char *)p);
- p += utfc_ptr2len((char *)p);
- }
- if (x2 != ':' || x3 == -1 || (*p != NUL && *p != ',')) {
- errmsg = e_invarg;
- break;
- }
- if (*p == NUL) {
- break;
- }
- }
- } else if (gvarp == &p_com) { // 'comments'
- for (s = *varp; *s;) {
- while (*s && *s != ':') {
- if (vim_strchr(COM_ALL, *s) == NULL
- && !ascii_isdigit(*s) && *s != '-') {
- errmsg = illegal_char(errbuf, errbuflen, *s);
- break;
- }
- s++;
- }
- if (*s++ == NUL) {
- errmsg = N_("E524: Missing colon");
- } else if (*s == ',' || *s == NUL) {
- errmsg = N_("E525: Zero length string");
- }
- if (errmsg != NULL) {
- break;
- }
- while (*s && *s != ',') {
- if (*s == '\\' && s[1] != NUL) {
- s++;
- }
- s++;
- }
- s = skip_to_option_part(s);
- }
- } else if (varp == &p_lcs) { // global 'listchars'
- errmsg = set_chars_option(curwin, varp, false);
- if (errmsg == NULL) {
- // The current window is set to use the global 'listchars' value.
- // So clear the window-local value.
- if (!(opt_flags & OPT_GLOBAL)) {
- clear_string_option(&curwin->w_p_lcs);
- }
- FOR_ALL_TAB_WINDOWS(tp, wp) {
- // If no error was returned above, we don't expect an error
- // here, so ignore the return value.
- (void)set_chars_option(wp, &wp->w_p_lcs, true);
- }
- redraw_all_later(NOT_VALID);
- }
- } else if (varp == &curwin->w_p_lcs) { // local 'listchars'
- errmsg = set_chars_option(curwin, varp, true);
- } else if (varp == &p_fcs) { // global 'fillchars'
- errmsg = set_chars_option(curwin, varp, false);
- if (errmsg == NULL) {
- // The current window is set to use the global 'fillchars' value.
- // So clear the window-local value.
- if (!(opt_flags & OPT_GLOBAL)) {
- clear_string_option(&curwin->w_p_fcs);
- }
- FOR_ALL_TAB_WINDOWS(tp, wp) {
- // If no error was returned above, we don't expect an error
- // here, so ignore the return value.
- (void)set_chars_option(wp, &wp->w_p_fcs, true);
- }
- redraw_all_later(NOT_VALID);
- }
- } else if (varp == &curwin->w_p_fcs) { // local 'fillchars'
- errmsg = set_chars_option(curwin, varp, true);
- } else if (varp == &p_cedit) { // 'cedit'
- errmsg = check_cedit();
- } else if (varp == &p_vfile) { // 'verbosefile'
- verbose_stop();
- if (*p_vfile != NUL && verbose_open() == FAIL) {
- errmsg = e_invarg;
- }
- // 'shada'
- } else if (varp == &p_shada) {
- // TODO(ZyX-I): Remove this code in the future, alongside with &viminfo
- // option.
- opt_idx = ((options[opt_idx].fullname[0] == 'v')
- ? (shada_idx == -1
- ? ((shada_idx = findoption("shada")))
- : shada_idx)
- : 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 = (options[opt_idx].flags & P_ALLOCED);
- for (s = p_shada; *s;) {
- // Check it's a valid character
- if (vim_strchr("!\"%'/:<@cfhnrs", *s) == NULL) {
- errmsg = illegal_char(errbuf, errbuflen, *s);
- break;
- }
- if (*s == 'n') { // name is always last one
- break;
- } else if (*s == 'r') { // skip until next ','
- while (*++s && *s != ',') {}
- } else if (*s == '%') {
- // optional number
- while (ascii_isdigit(*++s)) {}
- } else if (*s == '!' || *s == 'h' || *s == 'c') {
- s++; // no extra chars
- } else { // must have a number
- while (ascii_isdigit(*++s)) {}
-
- if (!ascii_isdigit(*(s - 1))) {
- if (errbuf != NULL) {
- vim_snprintf(errbuf, errbuflen,
- _("E526: Missing number after <%s>"),
- transchar_byte(*(s - 1)));
- errmsg = errbuf;
- } else {
- errmsg = "";
- }
- break;
- }
- }
- if (*s == ',') {
- s++;
- } else if (*s) {
- if (errbuf != NULL) {
- errmsg = N_("E527: Missing comma");
- } else {
- errmsg = "";
- }
- break;
- }
- }
- if (*p_shada && errmsg == NULL && get_shada_parameter('\'') < 0) {
- errmsg = N_("E528: Must specify a ' value");
- }
- } else if (gvarp == &p_sbr) { // 'showbreak'
- for (s = *varp; *s;) {
- if (ptr2cells((char *)s) != 1) {
- errmsg = N_("E595: 'showbreak' contains unprintable or wide character");
- }
- MB_PTR_ADV(s);
- }
- } 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'
- fill_breakat_flags();
- } else if (varp == &p_titlestring || varp == &p_iconstring) {
- // 'titlestring' and 'iconstring'
- int flagval = (varp == &p_titlestring) ? STL_IN_TITLE : STL_IN_ICON;
-
- // NULL => statusline syntax
- if (vim_strchr((char *)(*varp), '%') && check_stl_option((char *)(*varp)) == NULL) {
- stl_syntax |= flagval;
- } else {
- stl_syntax &= ~flagval;
- }
- did_set_title();
- } else if (varp == &p_sel) { // 'selection'
- if (*p_sel == NUL
- || check_opt_strings(p_sel, p_sel_values, false) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_slm) { // 'selectmode'
- if (check_opt_strings(p_slm, p_slm_values, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_km) { // 'keymodel'
- if (check_opt_strings(p_km, p_km_values, true) != OK) {
- errmsg = e_invarg;
- } else {
- km_stopsel = (vim_strchr((char *)p_km, 'o') != NULL);
- km_startsel = (vim_strchr((char *)p_km, 'a') != NULL);
- }
- } else if (varp == &p_mousem) { // 'mousemodel'
- if (check_opt_strings(p_mousem, p_mousem_values, false) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_mousescroll) { // 'mousescroll'
- errmsg = check_mousescroll((char *)p_mousescroll);
- } else if (varp == &p_swb) { // 'switchbuf'
- if (opt_strings_flags(p_swb, p_swb_values, &swb_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_debug) { // 'debug'
- if (check_opt_strings(p_debug, p_debug_values, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_dy) { // 'display'
- if (opt_strings_flags(p_dy, p_dy_values, &dy_flags, true) != OK) {
- errmsg = e_invarg;
- } else {
- (void)init_chartab();
- msg_grid_validate();
- }
- } else if (varp == &p_ead) { // 'eadirection'
- if (check_opt_strings(p_ead, p_ead_values, false) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_cb) { // 'clipboard'
- if (opt_strings_flags(p_cb, p_cb_values, &cb_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &(curwin->w_s->b_p_spl) // 'spell'
- || varp == &(curwin->w_s->b_p_spf)) {
- // When 'spelllang' or 'spellfile' is set and there is a window for this
- // buffer in which 'spell' is set load the wordlists.
- const bool is_spellfile = varp == &(curwin->w_s->b_p_spf);
-
- if ((is_spellfile && !valid_spellfile(*varp))
- || (!is_spellfile && !valid_spelllang(*varp))) {
- errmsg = e_invarg;
- } else {
- errmsg = did_set_spell_option(is_spellfile);
- }
- } else if (varp == &(curwin->w_s->b_p_spc)) {
- // 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) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_sps) { // 'spellsuggest'
- if (spell_check_sps() != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_msm) { // 'mkspellmem'
- if (spell_check_msm() != OK) {
- errmsg = e_invarg;
- }
- } else if (gvarp == &p_bh) {
- // When 'bufhidden' is set, check for valid value.
- if (check_opt_strings(curbuf->b_p_bh, p_bufhidden_values, false) != OK) {
- errmsg = e_invarg;
- }
- } else if (gvarp == &p_bt) {
- // When 'buftype' is set, check for valid value.
- if ((curbuf->terminal && curbuf->b_p_bt[0] != 't')
- || (!curbuf->terminal && curbuf->b_p_bt[0] == 't')
- || check_opt_strings(curbuf->b_p_bt, p_buftype_values, false) != OK) {
- errmsg = e_invarg;
- } else {
- if (curwin->w_status_height || global_stl_height()) {
- curwin->w_redr_status = true;
- redraw_later(curwin, VALID);
- }
- curbuf->b_help = (curbuf->b_p_bt[0] == 'h');
- redraw_titles();
- }
- } else if (gvarp == &p_stl || gvarp == (char_u **)&p_wbr || varp == &p_tal || varp == &p_ruf) {
- // 'statusline', 'winbar', 'tabline' or 'rulerformat'
- int wid;
-
- if (varp == &p_ruf) { // reset ru_wid first
- ru_wid = 0;
- }
- s = *varp;
- if (varp == &p_ruf && *s == '%') {
- // set ru_wid if 'ruf' starts with "%99("
- if (*++s == '-') { // ignore a '-'
- s++;
- }
- wid = getdigits_int((char **)&s, true, 0);
- if (wid && *s == '(' && (errmsg = check_stl_option((char *)p_ruf)) == NULL) {
- ru_wid = wid;
- } else {
- errmsg = check_stl_option((char *)p_ruf);
- }
- } else if (varp == &p_ruf || s[0] != '%' || s[1] != '!') {
- // check 'statusline', 'winbar' or 'tabline' only if it doesn't start with "%!"
- errmsg = check_stl_option((char *)s);
- }
- if (varp == &p_ruf && errmsg == NULL) {
- comp_col();
- }
- // add / remove window bars for 'winbar'
- if (gvarp == (char_u **)&p_wbr) {
- set_winbar(true);
- }
- } else if (gvarp == &p_cpt) {
- // check if it is a valid value for 'complete' -- Acevedo
- for (s = *varp; *s;) {
- while (*s == ',' || *s == ' ') {
- s++;
- }
- if (!*s) {
- break;
- }
- if (vim_strchr(".wbuksid]tU", *s) == NULL) {
- errmsg = illegal_char(errbuf, errbuflen, *s);
- break;
- }
- if (*++s != NUL && *s != ',' && *s != ' ') {
- if (s[-1] == 'k' || s[-1] == 's') {
- // skip optional filename after 'k' and 's'
- while (*s && *s != ',' && *s != ' ') {
- if (*s == '\\' && s[1] != NUL) {
- s++;
- }
- s++;
- }
- } else {
- if (errbuf != NULL) {
- vim_snprintf(errbuf, errbuflen,
- _("E535: Illegal character after <%c>"),
- *--s);
- errmsg = errbuf;
- } else {
- errmsg = "";
- }
- break;
- }
- }
- }
- } else if (varp == &p_cot) { // 'completeopt'
- if (check_opt_strings(p_cot, p_cot_values, true) != OK) {
- errmsg = e_invarg;
- } else {
- completeopt_was_set();
- }
-#ifdef BACKSLASH_IN_FILENAME
- } else if (gvarp == &p_csl) { // 'completeslash'
- if (check_opt_strings(p_csl, p_csl_values, false) != OK
- || check_opt_strings(curbuf->b_p_csl, p_csl_values, false) != OK) {
- errmsg = e_invarg;
- }
-#endif
- } else if (varp == &curwin->w_p_scl) {
- // 'signcolumn'
- if (check_signcolumn(*varp) != OK) {
- errmsg = e_invarg;
- }
- // When changing the 'signcolumn' to or from 'number', recompute the
- // width of the number column if 'number' or 'relativenumber' is set.
- if (((*oldval == 'n' && *(oldval + 1) == 'u')
- || (*curwin->w_p_scl == 'n' && *(curwin->w_p_scl + 1) == 'u'))
- && (curwin->w_p_nu || curwin->w_p_rnu)) {
- curwin->w_nrwidth_line_count = 0;
- }
- } else if (varp == &curwin->w_p_fdc || varp == &curwin->w_allbuf_opt.wo_fdc) {
- // 'foldcolumn'
- if (**varp == NUL || check_opt_strings(*varp, p_fdc_values, false) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_pt) {
- // 'pastetoggle': translate key codes like in a mapping
- if (*p_pt) {
- p = NULL;
- (void)replace_termcodes((char *)p_pt,
- STRLEN(p_pt),
- (char **)&p, REPTERM_FROM_PART | REPTERM_DO_LT, NULL,
- CPO_TO_CPO_FLAGS);
- if (p != NULL) {
- free_string_option(p_pt);
- p_pt = p;
- }
- }
- } else if (varp == &p_bs) { // 'backspace'
- if (ascii_isdigit(*p_bs)) {
- if (*p_bs > '3' || p_bs[1] != NUL) {
- errmsg = e_invarg;
- }
- } else if (check_opt_strings(p_bs, p_bs_values, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_bo) {
- if (opt_strings_flags(p_bo, p_bo_values, &bo_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (gvarp == &p_tc) { // 'tagcase'
- unsigned int *flags;
-
- if (opt_flags & OPT_LOCAL) {
- p = curbuf->b_p_tc;
- flags = &curbuf->b_tc_flags;
- } else {
- p = p_tc;
- flags = &tc_flags;
- }
-
- if ((opt_flags & OPT_LOCAL) && *p == NUL) {
- // make the local value empty: use the global value
- *flags = 0;
- } else if (*p == NUL
- || opt_strings_flags(p, p_tc_values, flags, false) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_cmp) { // 'casemap'
- if (opt_strings_flags(p_cmp, p_cmp_values, &cmp_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_dip) { // 'diffopt'
- if (diffopt_changed() == FAIL) {
- errmsg = e_invarg;
- }
- } else if (gvarp == &curwin->w_allbuf_opt.wo_fdm) { // 'foldmethod'
- if (check_opt_strings(*varp, p_fdm_values, false) != OK
- || *curwin->w_p_fdm == NUL) {
- errmsg = e_invarg;
- } else {
- foldUpdateAll(curwin);
- if (foldmethodIsDiff(curwin)) {
- 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 = (char_u *)vim_strchr((char *)(*varp), ',');
- if (p == NULL) {
- errmsg = N_("E536: comma required");
- } else if (p == *varp || p[1] == NUL) {
- errmsg = e_invarg;
- } else if (foldmethodIsMarker(curwin)) {
- foldUpdateAll(curwin);
- }
- } else if (gvarp == &p_cms) { // 'commentstring'
- if (**varp != NUL && strstr((char *)(*varp), "%s") == NULL) {
- errmsg = N_("E537: 'commentstring' must be empty or contain %s");
- }
- } else if (varp == &p_fdo) { // 'foldopen'
- if (opt_strings_flags(p_fdo, p_fdo_values, &fdo_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_fcl) { // 'foldclose'
- if (check_opt_strings(p_fcl, p_fcl_values, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (gvarp == &curwin->w_allbuf_opt.wo_fdi) { // 'foldignore'
- if (foldmethodIsIndent(curwin)) {
- foldUpdateAll(curwin);
- }
- } else if (gvarp == &p_ve) { // 'virtualedit'
- char_u *ve = p_ve;
- unsigned int *flags = &ve_flags;
-
- if (opt_flags & OPT_LOCAL) {
- ve = curwin->w_p_ve;
- flags = &curwin->w_ve_flags;
- }
-
- if ((opt_flags & OPT_LOCAL) && *ve == NUL) {
- // make the local value empty: use the global value
- *flags = 0;
- } else {
- if (opt_strings_flags(ve, p_ve_values, flags, true) != OK) {
- errmsg = e_invarg;
- } 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);
- // inccommand
- } else if (varp == &p_icm) {
- if (check_opt_strings(p_icm, p_icm_values, false) != OK) {
- errmsg = e_invarg;
- }
- } else if (gvarp == &p_ft) {
- if (!valid_filetype(*varp)) {
- errmsg = e_invarg;
- } else {
- 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.
- *value_checked = true;
- }
- } else if (gvarp == &p_syn) {
- if (!valid_filetype(*varp)) {
- errmsg = e_invarg;
- } else {
- 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.
- *value_checked = true;
- }
- } else if (varp == &curwin->w_p_winhl) {
- if (!parse_winhl_opt(curwin)) {
- errmsg = e_invarg;
- }
- } else if (varp == &p_tpf) {
- if (opt_strings_flags(p_tpf, p_tpf_values, &tpf_flags, true) != OK) {
- errmsg = e_invarg;
- }
- } else if (varp == &(curbuf->b_p_vsts)) { // 'varsofttabstop'
- char_u *cp;
-
- if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1])) {
- XFREE_CLEAR(curbuf->b_p_vsts_array);
- } else {
- for (cp = *varp; *cp; cp++) {
- if (ascii_isdigit(*cp)) {
- continue;
- }
- if (*cp == ',' && cp > *varp && *(cp - 1) != ',') {
- continue;
- }
- errmsg = e_invarg;
- break;
- }
- if (errmsg == NULL) {
- long *oldarray = curbuf->b_p_vsts_array;
- if (tabstop_set(*varp, &(curbuf->b_p_vsts_array))) {
- xfree(oldarray);
- } else {
- errmsg = e_invarg;
- }
- }
- }
- } else if (varp == &(curbuf->b_p_vts)) { // 'vartabstop'
- char_u *cp;
-
- if (!(*varp)[0] || ((*varp)[0] == '0' && !(*varp)[1])) {
- XFREE_CLEAR(curbuf->b_p_vts_array);
- } else {
- for (cp = *varp; *cp; cp++) {
- if (ascii_isdigit(*cp)) {
- continue;
- }
- if (*cp == ',' && cp > *varp && *(cp - 1) != ',') {
- continue;
- }
- errmsg = e_invarg;
- break;
- }
- if (errmsg == NULL) {
- long *oldarray = curbuf->b_p_vts_array;
- if (tabstop_set(*varp, &(curbuf->b_p_vts_array))) {
- xfree(oldarray);
- if (foldmethodIsIndent(curwin)) {
- foldUpdateAll(curwin);
- }
- } else {
- errmsg = e_invarg;
- }
- }
- }
- } else if (varp == &p_qftf) {
- if (!qf_process_qftf_option()) {
- errmsg = e_invarg;
- }
- } else {
- // Options that are a list of flags.
- p = NULL;
- if (varp == &p_ww) { // 'whichwrap'
- p = (char_u *)WW_ALL;
- }
- if (varp == &p_shm) { // 'shortmess'
- p = (char_u *)SHM_ALL;
- } else if (varp == (char_u **)&(p_cpo)) { // 'cpoptions'
- p = (char_u *)CPO_VI;
- } else if (varp == &(curbuf->b_p_fo)) { // 'formatoptions'
- p = (char_u *)FO_ALL;
- } else if (varp == &curwin->w_p_cocu) { // 'concealcursor'
- p = (char_u *)COCU_ALL;
- } else if (varp == &p_mouse) { // 'mouse'
- p = (char_u *)MOUSE_ALL;
- }
- if (p != NULL) {
- for (s = *varp; *s; s++) {
- if (vim_strchr((char *)p, *s) == NULL) {
- errmsg = illegal_char(errbuf, errbuflen, *s);
- break;
- }
- }
- }
- }
-
- /*
- * If error detected, restore the previous value.
- */
- if (errmsg != NULL) {
- free_string_option(*varp);
- *varp = oldval;
- /*
- * When resetting some values, need to act on it.
- */
- if (did_chartab) {
- (void)init_chartab();
- }
- } 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);
- }
- options[opt_idx].flags |= P_ALLOCED;
-
- if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0
- && ((int)options[opt_idx].indir & PV_BOTH)) {
- /* global option with local value set to use global value; free
- * the local value and make it empty */
- p = get_varp_scope(&(options[opt_idx]), OPT_LOCAL);
- free_string_option(*(char_u **)p);
- *(char_u **)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);
- }
-
- /*
- * Trigger the autocommand only after setting the flags.
- */
- // When 'syntax' is set, load the syntax of that name
- if (varp == &(curbuf->b_p_syn)) {
- 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, (char *)curbuf->b_p_syn, curbuf->b_fname,
- value_changed || syn_recursive == 1, curbuf);
- curbuf->b_flags |= BF_SYN_SET;
- syn_recursive--;
- } else if (varp == &(curbuf->b_p_ft)) {
- // 'filetype' is set, trigger the FileType autocommand
- // Skip this when called from a modeline and the filetype was
- // already set to this value.
- if (!(opt_flags & OPT_MODELINE) || value_changed) {
- static int ft_recursive = 0;
- int secure_save = secure;
-
- // Reset the secure flag, since the value of 'filetype' has
- // been checked to be safe.
- secure = 0;
-
- ft_recursive++;
- did_filetype = true;
- // Only pass true for "force" when the value changed or not
- // used recursively, to avoid endless recurrence.
- apply_autocmds(EVENT_FILETYPE, (char *)curbuf->b_p_ft, curbuf->b_fname,
- value_changed || ft_recursive == 1, curbuf);
- ft_recursive--;
- // Just in case the old "curbuf" is now invalid
- if (varp != &(curbuf->b_p_ft)) {
- varp = NULL;
- }
- secure = secure_save;
- }
- }
- if (varp == &(curwin->w_s->b_p_spl)) {
- char_u fname[200];
- char_u *q = curwin->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 in 'runtimepath'.
- * They could set 'spellcapcheck' depending on the language.
- * Use the first name in 'spelllang' up to '_region' or
- * '.encoding'.
- */
- for (p = q; *p != NUL; p++) {
- if (!ASCII_ISALNUM(*p) && *p != '-') {
- break;
- }
- }
- if (p > q) {
- vim_snprintf((char *)fname, sizeof(fname), "spell/%.*s.vim",
- (int)(p - q), q);
- source_runtime((char *)fname, DIP_ALL);
- }
- }
- }
-
- if (varp == &p_mouse) {
- setmouse(); // in case 'mouse' changed
- }
-
- if (curwin->w_curswant != MAXCOL
- && (options[opt_idx].flags & (P_CURSWANT | P_RALL)) != 0) {
- curwin->w_set_curswant = true;
- }
-
- check_redraw(options[opt_idx].flags);
-
- return errmsg;
-}
-
-/// Simple int comparison function for use with qsort()
-static int int_cmp(const void *a, const void *b)
-{
- return *(const int *)a - *(const int *)b;
-}
-
-/// Handle setting 'signcolumn' for value 'val'
-///
-/// @return OK when the value is valid, FAIL otherwise
-int check_signcolumn(char_u *val)
-{
- if (*val == NUL) {
- return FAIL;
- }
- // check for basic match
- if (check_opt_strings(val, p_scl_values, false) == OK) {
- return OK;
- }
-
- // check for 'auto:<NUMBER>-<NUMBER>'
- if (STRLEN(val) == 8
- && !STRNCMP(val, "auto:", 5)
- && ascii_isdigit(val[5])
- && val[6] == '-'
- && ascii_isdigit(val[7])) {
- int min = val[5] - '0';
- int max = val[7] - '0';
- if (min < 1 || max < 2 || min > 8 || max > 9 || min >= max) {
- return FAIL;
- }
- return OK;
- }
-
- return FAIL;
-}
-
-/// Handle setting 'colorcolumn' or 'textwidth' in window "wp".
-///
-/// @return error message, NULL if it's OK.
-char *check_colorcolumn(win_T *wp)
-{
- char_u *s;
- int col;
- unsigned int count = 0;
- int color_cols[256];
- int j = 0;
-
- if (wp->w_buffer == NULL) {
- return NULL; // buffer was closed
- }
-
- for (s = wp->w_p_cc; *s != NUL && count < 255;) {
- if (*s == '-' || *s == '+') {
- // -N and +N: add to 'textwidth'
- col = (*s == '-') ? -1 : 1;
- s++;
- if (!ascii_isdigit(*s)) {
- return e_invarg;
- }
- col = col * getdigits_int((char **)&s, true, 0);
- if (wp->w_buffer->b_p_tw == 0) {
- goto skip; // 'textwidth' not set, skip this item
- }
- assert((col >= 0
- && wp->w_buffer->b_p_tw <= INT_MAX - col
- && wp->w_buffer->b_p_tw + col >= INT_MIN)
- || (col < 0
- && wp->w_buffer->b_p_tw >= INT_MIN - col
- && wp->w_buffer->b_p_tw + col <= INT_MAX));
- col += (int)wp->w_buffer->b_p_tw;
- if (col < 0) {
- goto skip;
- }
- } else if (ascii_isdigit(*s)) {
- col = getdigits_int((char **)&s, true, 0);
- } else {
- return e_invarg;
- }
- color_cols[count++] = col - 1; // 1-based to 0-based
-skip:
- if (*s == NUL) {
- break;
- }
- if (*s != ',') {
- return e_invarg;
- }
- if (*++s == NUL) {
- return e_invarg; // illegal trailing comma as in "set cc=80,"
- }
- }
-
- xfree(wp->w_p_cc_cols);
- if (count == 0) {
- wp->w_p_cc_cols = NULL;
- } else {
- wp->w_p_cc_cols = xmalloc(sizeof(int) * (count + 1));
- /* sort the columns for faster usage on screen redraw inside
- * win_line() */
- qsort(color_cols, count, sizeof(int), int_cmp);
-
- for (unsigned int i = 0; i < count; i++) {
- // skip duplicates
- if (j == 0 || wp->w_p_cc_cols[j - 1] != color_cols[i]) {
- wp->w_p_cc_cols[j++] = color_cols[i];
- }
- }
- wp->w_p_cc_cols[j] = -1; // end marker
- }
-
- return NULL; // no error
-}
-
void check_blending(win_T *wp)
{
wp->w_grid_alloc.blending =
wp->w_p_winbl > 0 || (wp->w_floating && wp->w_float_config.shadow);
}
-/// Calls mb_cptr2char_adv(p) and returns the character.
-/// If "p" starts with "\x", "\u" or "\U" the hex or unicode value is used.
-/// Returns 0 for invalid hex or invalid UTF-8 byte.
-static int get_encoded_char_adv(char_u **p)
-{
- char_u *s = *p;
-
- if (s[0] == '\\' && (s[1] == 'x' || s[1] == 'u' || s[1] == 'U')) {
- int64_t num = 0;
- int bytes;
- int n;
- for (bytes = s[1] == 'x' ? 1 : s[1] == 'u' ? 2 : 4; bytes > 0; bytes--) {
- *p += 2;
- n = hexhex2nr(*p);
- if (n < 0) {
- return 0;
- }
- num = num * 256 + n;
- }
- *p += 2;
- return (int)num;
- }
-
- // TODO(bfredl): use schar_T representation and utfc_ptr2len
- int clen = utf_ptr2len((char *)s);
- int c = mb_cptr2char_adv((const char_u **)p);
- if (clen == 1 && c > 127) { // Invalid UTF-8 byte
- return 0;
- }
- return c;
-}
-
-/// Handle setting 'listchars' or 'fillchars'.
-/// Assume monocell characters
-///
-/// @param varp either &curwin->w_p_lcs or &curwin->w_p_fcs
-/// @return error message, NULL if it's OK.
-static char *set_chars_option(win_T *wp, char_u **varp, bool set)
-{
- int round, i, len, len2, entries;
- char_u *p, *s;
- int c1;
- int c2 = 0;
- int c3 = 0;
- char_u *last_multispace = NULL; // Last occurrence of "multispace:"
- char_u *last_lmultispace = NULL; // Last occurrence of "leadmultispace:"
- int multispace_len = 0; // Length of lcs-multispace string
- int lead_multispace_len = 0; // Length of lcs-leadmultispace string
-
- struct chars_tab {
- int *cp; ///< char value
- char *name; ///< char id
- int def; ///< default value
- };
- struct chars_tab *tab;
-
- struct chars_tab fcs_tab[] = {
- { &wp->w_p_fcs_chars.stl, "stl", ' ' },
- { &wp->w_p_fcs_chars.stlnc, "stlnc", ' ' },
- { &wp->w_p_fcs_chars.wbr, "wbr", ' ' },
- { &wp->w_p_fcs_chars.horiz, "horiz", 9472 }, // ─
- { &wp->w_p_fcs_chars.horizup, "horizup", 9524 }, // â”´
- { &wp->w_p_fcs_chars.horizdown, "horizdown", 9516 }, // ┬
- { &wp->w_p_fcs_chars.vert, "vert", 9474 }, // │
- { &wp->w_p_fcs_chars.vertleft, "vertleft", 9508 }, // ┤
- { &wp->w_p_fcs_chars.vertright, "vertright", 9500 }, // ├
- { &wp->w_p_fcs_chars.verthoriz, "verthoriz", 9532 }, // ┼
- { &wp->w_p_fcs_chars.fold, "fold", 183 }, // ·
- { &wp->w_p_fcs_chars.foldopen, "foldopen", '-' },
- { &wp->w_p_fcs_chars.foldclosed, "foldclose", '+' },
- { &wp->w_p_fcs_chars.foldsep, "foldsep", 9474 }, // │
- { &wp->w_p_fcs_chars.diff, "diff", '-' },
- { &wp->w_p_fcs_chars.msgsep, "msgsep", ' ' },
- { &wp->w_p_fcs_chars.eob, "eob", '~' },
- };
- struct chars_tab lcs_tab[] = {
- { &wp->w_p_lcs_chars.eol, "eol", NUL },
- { &wp->w_p_lcs_chars.ext, "extends", NUL },
- { &wp->w_p_lcs_chars.nbsp, "nbsp", NUL },
- { &wp->w_p_lcs_chars.prec, "precedes", NUL },
- { &wp->w_p_lcs_chars.space, "space", NUL },
- { &wp->w_p_lcs_chars.tab2, "tab", NUL },
- { &wp->w_p_lcs_chars.lead, "lead", NUL },
- { &wp->w_p_lcs_chars.trail, "trail", NUL },
- { &wp->w_p_lcs_chars.conceal, "conceal", NUL },
- };
-
- if (varp == &p_lcs || varp == &wp->w_p_lcs) {
- tab = lcs_tab;
- entries = ARRAY_SIZE(lcs_tab);
- if (varp == &wp->w_p_lcs && wp->w_p_lcs[0] == NUL) {
- varp = &p_lcs;
- }
- } else {
- tab = fcs_tab;
- entries = ARRAY_SIZE(fcs_tab);
- if (varp == &wp->w_p_fcs && wp->w_p_fcs[0] == NUL) {
- varp = &p_fcs;
- }
- if (*p_ambw == 'd') {
- // XXX: If ambiwidth=double then some characters take 2 columns,
- // which is forbidden (TUI limitation?). Set old defaults.
- fcs_tab[3].def = '-';
- fcs_tab[4].def = '-';
- fcs_tab[5].def = '-';
- fcs_tab[6].def = '|';
- fcs_tab[7].def = '|';
- fcs_tab[8].def = '|';
- fcs_tab[9].def = '+';
- fcs_tab[10].def = '-';
- fcs_tab[13].def = '|';
- }
- }
-
- // first round: check for valid value, second round: assign values
- for (round = 0; round <= (set ? 1 : 0); round++) {
- if (round > 0) {
- // After checking that the value is valid: set defaults
- for (i = 0; i < entries; i++) {
- if (tab[i].cp != NULL) {
- *(tab[i].cp) = tab[i].def;
- }
- }
- if (varp == &p_lcs || varp == &wp->w_p_lcs) {
- wp->w_p_lcs_chars.tab1 = NUL;
- wp->w_p_lcs_chars.tab3 = NUL;
-
- xfree(wp->w_p_lcs_chars.multispace);
- if (multispace_len > 0) {
- wp->w_p_lcs_chars.multispace = xmalloc(((size_t)multispace_len + 1) * sizeof(int));
- wp->w_p_lcs_chars.multispace[multispace_len] = NUL;
- } else {
- wp->w_p_lcs_chars.multispace = NULL;
- }
-
- xfree(wp->w_p_lcs_chars.leadmultispace);
- if (lead_multispace_len > 0) {
- wp->w_p_lcs_chars.leadmultispace
- = xmalloc(((size_t)lead_multispace_len + 1) * sizeof(int));
- wp->w_p_lcs_chars.leadmultispace[lead_multispace_len] = NUL;
- } else {
- wp->w_p_lcs_chars.leadmultispace = NULL;
- }
- }
- }
- p = *varp;
- while (*p) {
- for (i = 0; i < entries; i++) {
- len = (int)STRLEN(tab[i].name);
- if (STRNCMP(p, tab[i].name, len) == 0
- && p[len] == ':'
- && p[len + 1] != NUL) {
- c2 = c3 = 0;
- s = p + len + 1;
- c1 = get_encoded_char_adv(&s);
- if (c1 == 0 || char2cells(c1) > 1) {
- return e_invarg;
- }
- if (tab[i].cp == &wp->w_p_lcs_chars.tab2) {
- if (*s == NUL) {
- return e_invarg;
- }
- c2 = get_encoded_char_adv(&s);
- if (c2 == 0 || char2cells(c2) > 1) {
- return e_invarg;
- }
- if (!(*s == ',' || *s == NUL)) {
- c3 = get_encoded_char_adv(&s);
- if (c3 == 0 || char2cells(c3) > 1) {
- return e_invarg;
- }
- }
- }
- if (*s == ',' || *s == NUL) {
- if (round > 0) {
- if (tab[i].cp == &wp->w_p_lcs_chars.tab2) {
- wp->w_p_lcs_chars.tab1 = c1;
- wp->w_p_lcs_chars.tab2 = c2;
- wp->w_p_lcs_chars.tab3 = c3;
- } else if (tab[i].cp != NULL) {
- *(tab[i].cp) = c1;
- }
- }
- p = s;
- break;
- }
- }
- }
-
- if (i == entries) {
- len = (int)STRLEN("multispace");
- len2 = (int)STRLEN("leadmultispace");
- if ((varp == &p_lcs || varp == &wp->w_p_lcs)
- && STRNCMP(p, "multispace", len) == 0
- && p[len] == ':'
- && p[len + 1] != NUL) {
- s = p + len + 1;
- if (round == 0) {
- // Get length of lcs-multispace string in the first round
- last_multispace = p;
- multispace_len = 0;
- while (*s != NUL && *s != ',') {
- c1 = get_encoded_char_adv(&s);
- if (c1 == 0 || char2cells(c1) > 1) {
- return e_invarg;
- }
- multispace_len++;
- }
- if (multispace_len == 0) {
- // lcs-multispace cannot be an empty string
- return e_invarg;
- }
- p = s;
- } else {
- int multispace_pos = 0;
- while (*s != NUL && *s != ',') {
- c1 = get_encoded_char_adv(&s);
- if (p == last_multispace) {
- wp->w_p_lcs_chars.multispace[multispace_pos++] = c1;
- }
- }
- p = s;
- }
- } else if ((varp == &p_lcs || varp == &wp->w_p_lcs)
- && STRNCMP(p, "leadmultispace", len2) == 0
- && p[len2] == ':'
- && p[len2 + 1] != NUL) {
- s = p + len2 + 1;
- if (round == 0) {
- // get length of lcs-leadmultispace string in first round
- last_lmultispace = p;
- lead_multispace_len = 0;
- while (*s != NUL && *s != ',') {
- c1 = get_encoded_char_adv(&s);
- if (c1 == 0 || char2cells(c1) > 1) {
- return e_invarg;
- }
- lead_multispace_len++;
- }
- if (lead_multispace_len == 0) {
- // lcs-leadmultispace cannot be an empty string
- return e_invarg;
- }
- p = s;
- } else {
- int multispace_pos = 0;
- while (*s != NUL && *s != ',') {
- c1 = get_encoded_char_adv(&s);
- if (p == last_lmultispace) {
- wp->w_p_lcs_chars.leadmultispace[multispace_pos++] = c1;
- }
- }
- p = s;
- }
- } else {
- return e_invarg;
- }
- }
- if (*p == ',') {
- p++;
- }
- }
- }
-
- return NULL; // no error
-}
-
-/// Check validity of options with the 'statusline' format.
-/// Return an untranslated error message or NULL.
-char *check_stl_option(char *s)
-{
- int groupdepth = 0;
- static char errbuf[80];
-
- while (*s) {
- // Check for valid keys after % sequences
- while (*s && *s != '%') {
- s++;
- }
- if (!*s) {
- break;
- }
- s++;
- if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_SEPARATE) {
- s++;
- continue;
- }
- if (*s == ')') {
- s++;
- if (--groupdepth < 0) {
- break;
- }
- continue;
- }
- if (*s == '-') {
- s++;
- }
- while (ascii_isdigit(*s)) {
- s++;
- }
- if (*s == STL_USER_HL) {
- continue;
- }
- if (*s == '.') {
- s++;
- while (*s && ascii_isdigit(*s)) {
- s++;
- }
- }
- if (*s == '(') {
- groupdepth++;
- continue;
- }
- if (vim_strchr(STL_ALL, *s) == NULL) {
- return illegal_char(errbuf, sizeof(errbuf), *s);
- }
- if (*s == '{') {
- bool reevaluate = (*++s == '%');
-
- if (reevaluate && *++s == '}') {
- // "}" is not allowed immediately after "%{%"
- return illegal_char(errbuf, sizeof(errbuf), '}');
- }
- while ((*s != '}' || (reevaluate && s[-1] != '%')) && *s) {
- s++;
- }
- if (*s != '}') {
- return e_unclosed_expression_sequence;
- }
- }
- }
- if (groupdepth != 0) {
- return e_unbalanced_groups;
- }
- return NULL;
-}
-
-static char *did_set_spell_option(bool is_spellfile)
+/// Handle setting `winhighlight' in window "wp"
+bool parse_winhl_opt(win_T *wp)
{
- char *errmsg = NULL;
+ const char *p = (const char *)wp->w_p_winhl;
- if (is_spellfile) {
- int l = (int)STRLEN(curwin->w_s->b_p_spf);
- if (l > 0
- && (l < 4 || STRCMP(curwin->w_s->b_p_spf + l - 4, ".add") != 0)) {
- errmsg = e_invarg;
+ if (!*p) {
+ if (wp->w_ns_hl_winhl && wp->w_ns_hl == wp->w_ns_hl_winhl) {
+ wp->w_ns_hl = 0;
+ wp->w_hl_needs_update = true;
}
- }
- if (errmsg == NULL) {
- FOR_ALL_WINDOWS_IN_TAB(wp, curtab) {
- if (wp->w_buffer == curbuf && wp->w_p_spell) {
- errmsg = did_set_spelllang(wp);
- break;
- }
- }
+ return true;
}
- return errmsg;
-}
-
-/// Set curbuf->b_cap_prog to the regexp program for 'spellcapcheck'.
-/// Return error message when failed, NULL when OK.
-static char *compile_cap_prog(synblock_T *synblock)
- FUNC_ATTR_NONNULL_ALL
-{
- regprog_T *rp = synblock->b_cap_prog;
- char_u *re;
-
- if (synblock->b_p_spc == NULL || *synblock->b_p_spc == NUL) {
- synblock->b_cap_prog = NULL;
+ if (wp->w_ns_hl_winhl == 0) {
+ wp->w_ns_hl_winhl = (int)nvim_create_namespace(NULL_STRING);
} else {
- // Prepend a ^ so that we only match at one column
- re = concat_str((char_u *)"^", synblock->b_p_spc);
- synblock->b_cap_prog = vim_regcomp((char *)re, RE_MAGIC);
- xfree(re);
- if (synblock->b_cap_prog == NULL) {
- synblock->b_cap_prog = rp; // restore the previous program
- return e_invarg;
- }
+ // namespace already exist. invalidate existing items
+ DecorProvider *dp = get_decor_provider(wp->w_ns_hl_winhl, true);
+ dp->hl_valid++;
}
+ wp->w_ns_hl = wp->w_ns_hl_winhl;
+ int ns_hl = wp->w_ns_hl;
- vim_regfree(rp);
- return NULL;
-}
-
-/// Handle setting `winhighlight' in window "wp"
-static bool parse_winhl_opt(win_T *wp)
-{
- int w_hl_id_normal = 0;
- int w_hl_ids[HLF_COUNT] = { 0 };
- int hlf;
-
- const char *p = (const char *)wp->w_p_winhl;
while (*p) {
char *colon = strchr(p, ':');
if (!colon) {
@@ -3973,34 +1910,22 @@ static bool parse_winhl_opt(win_T *wp)
char *commap = xstrchrnul(hi, ',');
size_t len = (size_t)(commap - hi);
int hl_id = len ? syn_check_group(hi, len) : -1;
+ int hl_id_link = nlen ? syn_check_group(p, nlen) : 0;
- if (strncmp("Normal", p, nlen) == 0) {
- w_hl_id_normal = hl_id;
- } else {
- for (hlf = 0; hlf < HLF_COUNT; hlf++) {
- if (strlen(hlf_names[hlf]) == nlen
- && strncmp(hlf_names[hlf], p, nlen) == 0) {
- w_hl_ids[hlf] = hl_id;
- break;
- }
- }
- if (hlf == HLF_COUNT) {
- return false;
- }
- }
+ HlAttrs attrs = HLATTRS_INIT;
+ attrs.rgb_ae_attr |= HL_GLOBAL;
+ ns_hl_def(ns_hl, hl_id_link, attrs, hl_id, NULL);
p = *commap ? commap + 1 : "";
}
- wp->w_hl_id_normal = w_hl_id_normal;
- memcpy(wp->w_hl_ids, w_hl_ids, sizeof(w_hl_ids));
wp->w_hl_needs_update = true;
return true;
}
-// Set the script_ctx for an option, taking care of setting the buffer- or
-// window-local value.
-static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
+/// Set the script_ctx for an option, taking care of setting the buffer- or
+/// window-local value.
+void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
{
int both = (opt_flags & (OPT_LOCAL | OPT_GLOBAL)) == 0;
int indir = (int)options[opt_idx].indir;
@@ -4009,7 +1934,7 @@ static void set_option_sctx_idx(int opt_idx, int opt_flags, sctx_T script_ctx)
.script_ctx = {
script_ctx.sc_sid,
script_ctx.sc_seq,
- script_ctx.sc_lnum + sourcing_lnum
+ script_ctx.sc_lnum + SOURCING_LNUM
},
current_channel_id
};
@@ -4041,6 +1966,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
{
int old_value = *(int *)varp;
int old_global_value = 0;
+ char *errmsg = NULL;
// Disallow changing some options from secure mode
if ((secure || sandbox != 0)
@@ -4145,7 +2071,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
paste_option_changed();
} else if ((int *)varp == &p_ic && p_hls) {
// when 'ignorecase' is set or reset and 'hlsearch' is set, redraw
- redraw_all_later(SOME_VALID);
+ redraw_all_later(UPD_SOME_VALID);
} else if ((int *)varp == &p_hls) {
// when 'hlsearch' is set or reset: reset no_hlsearch
set_no_hlsearch(false);
@@ -4162,7 +2088,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
FOR_ALL_WINDOWS_IN_TAB(win, curtab) {
if (win->w_p_pvw && win != curwin) {
curwin->w_p_pvw = false;
- return N_("E590: A preview window already exists");
+ return e_preview_window_already_exists;
}
}
}
@@ -4221,10 +2147,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
}
} else if ((int *)varp == &curwin->w_p_spell) { // 'spell'
if (curwin->w_p_spell) {
- char *errmsg = did_set_spelllang(curwin);
- if (errmsg != NULL) {
- emsg(_(errmsg));
- }
+ errmsg = did_set_spelllang(curwin);
}
}
@@ -4243,7 +2166,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
// Enable Arabic shaping (major part of what Arabic requires)
if (!p_arshape) {
p_arshape = true;
- redraw_all_later(NOT_VALID);
+ redraw_all_later(UPD_NOT_VALID);
}
}
@@ -4261,7 +2184,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
p_deco = true;
// Force-set the necessary keymap for arabic.
- set_option_value("keymap", 0L, "arabic", OPT_LOCAL);
+ errmsg = set_option_value("keymap", 0L, "arabic", OPT_LOCAL);
} else {
/*
* 'arabic' is reset, handle various sub-settings.
@@ -4341,7 +2264,7 @@ static char *set_bool_option(const int opt_idx, char_u *const varp, const int va
}
check_redraw(options[opt_idx].flags);
- return NULL;
+ return errmsg;
}
/// Set the value of a number option, taking care of side effects
@@ -4785,51 +2708,8 @@ static char *set_num_option(int opt_idx, char_u *varp, long value, char *errbuf,
return errmsg;
}
-/// 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
-static void trigger_optionsset_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) {
- 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, options[opt_idx].fullname, NULL, false, NULL);
- reset_v_option_vars();
- }
-}
-
/// Called after an option changed: check if something needs to be redrawn.
-static void check_redraw(uint32_t flags)
+void check_redraw(uint32_t flags)
{
// Careful: P_RCLR and P_RALL are a combination of other P_ flags
bool doclear = (flags & P_RCLR) == P_RCLR;
@@ -4843,15 +2723,15 @@ static void check_redraw(uint32_t flags)
changed_window_setting();
}
if (flags & P_RBUF) {
- redraw_curbuf_later(NOT_VALID);
+ redraw_curbuf_later(UPD_NOT_VALID);
}
if (flags & P_RWINONLY) {
- redraw_later(curwin, NOT_VALID);
+ redraw_later(curwin, UPD_NOT_VALID);
}
if (doclear) {
- redraw_all_later(CLEAR);
+ redraw_all_later(UPD_CLEAR);
} else if (all) {
- redraw_all_later(NOT_VALID);
+ redraw_all_later(UPD_NOT_VALID);
}
}
@@ -5001,7 +2881,7 @@ bool set_tty_option(const char *name, char *value)
void set_tty_background(const char *value)
{
- if (option_was_set("bg") || strequal((char *)p_bg, value)) {
+ if (option_was_set("bg") || strequal(p_bg, value)) {
// background is already set... ignore
return;
}
@@ -5011,7 +2891,7 @@ void set_tty_background(const char *value)
? "autocmd VimEnter * ++once ++nested set bg=light"
: "autocmd VimEnter * ++once ++nested set bg=dark");
} else {
- set_option_value("bg", 0L, value, 0);
+ set_option_value_give_err("bg", 0L, value, 0);
reset_option_was_set("bg");
}
}
@@ -5021,7 +2901,7 @@ void set_tty_background(const char *value)
/// @param[in] arg Option name.
///
/// @return Option index or -1 if option was not found.
-static int findoption(const char *const arg)
+int findoption(const char *const arg)
FUNC_ATTR_NONNULL_ALL
{
return findoption_len(arg, strlen(arg));
@@ -5050,14 +2930,14 @@ getoption_T get_option_value(const char *name, long *numval, char **stringval, i
return gov_unknown;
}
- char_u *varp = get_varp_scope(&(options[opt_idx]), opt_flags);
+ char_u *varp = (char_u *)get_varp_scope(&(options[opt_idx]), opt_flags);
if (options[opt_idx].flags & P_STRING) {
if (varp == NULL) { // hidden option
return gov_hidden_string;
}
if (stringval != NULL) {
- if ((char_u **)varp == &p_pt) { // 'pastetoggle'
+ if ((char **)varp == &p_pt) { // 'pastetoggle'
*stringval = str2special_save(*(char **)(varp), false, false);
} else {
*stringval = xstrdup(*(char **)(varp));
@@ -5176,7 +3056,7 @@ int get_option_value_strict(char *name, int64_t *numval, char **stringval, int o
// only getting a pointer, no need to use aucmd_prepbuf()
curbuf = (buf_T *)from;
curwin->w_buffer = curbuf;
- varp = get_varp_scope(p, OPT_LOCAL);
+ varp = (char_u *)get_varp_scope(p, OPT_LOCAL);
curbuf = save_curbuf;
curwin->w_buffer = curbuf;
}
@@ -5184,7 +3064,7 @@ int get_option_value_strict(char *name, int64_t *numval, char **stringval, int o
win_T *save_curwin = curwin;
curwin = (win_T *)from;
curbuf = curwin->w_buffer;
- varp = get_varp_scope(p, OPT_LOCAL);
+ varp = (char_u *)get_varp_scope(p, OPT_LOCAL);
curwin = save_curwin;
curbuf = curwin->w_buffer;
}
@@ -5207,6 +3087,49 @@ int get_option_value_strict(char *name, int64_t *numval, char **stringval, int o
return rv;
}
+/// Return the flags for the option at 'opt_idx'.
+uint32_t get_option_flags(int opt_idx)
+{
+ return options[opt_idx].flags;
+}
+
+/// Set a flag for the option at 'opt_idx'.
+void set_option_flag(int opt_idx, uint32_t flag)
+{
+ options[opt_idx].flags |= flag;
+}
+
+/// Clear a flag for the option at 'opt_idx'.
+void clear_option_flag(int opt_idx, uint32_t flag)
+{
+ options[opt_idx].flags &= ~flag;
+}
+
+/// Returns true if the option at 'opt_idx' is a global option
+bool is_global_option(int opt_idx)
+{
+ return options[opt_idx].indir == PV_NONE;
+}
+
+/// Returns true if the option at 'opt_idx' is a global option which also has a
+/// local value.
+int is_global_local_option(int opt_idx)
+{
+ return options[opt_idx].indir & PV_BOTH;
+}
+
+/// Returns true if the option at 'opt_idx' is a window-local option
+bool is_window_local_option(int opt_idx)
+{
+ return options[opt_idx].var == VAR_WIN;
+}
+
+/// Returns true if the option at 'opt_idx' is a hidden option
+bool is_hidden_option(int opt_idx)
+{
+ return options[opt_idx].var == NULL;
+}
+
/// Set the value of an option
///
/// @param[in] name Option name.
@@ -5217,7 +3140,7 @@ int get_option_value_strict(char *name, int64_t *numval, char **stringval, int o
/// is cleared (the exact semantics of this depend
/// on the option).
///
-/// @return NULL on success, error message on error.
+/// @return NULL on success, an untranslated error message on error.
char *set_option_value(const char *const name, const long number, const char *const string,
const int opt_flags)
FUNC_ATTR_NONNULL_ARG(1)
@@ -5247,7 +3170,7 @@ char *set_option_value(const char *const name, const long number, const char *co
return set_string_option(opt_idx, s, opt_flags);
}
- varp = get_varp_scope(&(options[opt_idx]), opt_flags);
+ varp = (char_u *)get_varp_scope(&(options[opt_idx]), opt_flags);
if (varp != NULL) { // hidden option is not changed
if (number == 0 && string != NULL) {
int idx;
@@ -5287,6 +3210,18 @@ char *set_option_value(const char *const name, const long number, const char *co
return NULL;
}
+/// Call set_option_value() and when an error is returned report it.
+///
+/// @param opt_flags OPT_LOCAL or 0 (both)
+void set_option_value_give_err(const char *name, long number, const char *string, int opt_flags)
+{
+ char *errmsg = set_option_value(name, number, string, opt_flags);
+
+ if (errmsg != NULL) {
+ emsg(_(errmsg));
+ }
+}
+
/// Return true if "name" is a string option.
/// Returns false if option "name" does not exist.
bool is_string_option(const char *name)
@@ -5364,14 +3299,14 @@ static void showoptions(int all, int opt_flags)
item_count = 0;
for (p = &options[0]; p->fullname != NULL; p++) {
// apply :filter /pat/
- if (message_filtered((char_u *)p->fullname)) {
+ if (message_filtered(p->fullname)) {
continue;
}
varp = NULL;
if ((opt_flags & (OPT_LOCAL | OPT_GLOBAL)) != 0) {
if (p->indir != PV_NONE) {
- varp = get_varp_scope(p, opt_flags);
+ varp = (char_u *)get_varp_scope(p, opt_flags);
}
} else {
varp = get_varp(p);
@@ -5475,13 +3410,12 @@ void ui_refresh_options(void)
/// @param opt_flags OPT_LOCAL or OPT_GLOBAL
static void showoneopt(vimoption_T *p, int opt_flags)
{
- char_u *varp;
int save_silent = silent_mode;
silent_mode = false;
info_message = true; // use mch_msg(), not mch_errmsg()
- varp = get_varp_scope(p, opt_flags);
+ char_u *varp = (char_u *)get_varp_scope(p, opt_flags);
// for 'modified' we also need to check if 'ff' or 'fenc' changed.
if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed
@@ -5527,7 +3461,7 @@ static void showoneopt(vimoption_T *p, int opt_flags)
int makeset(FILE *fd, int opt_flags, int local_only)
{
vimoption_T *p;
- char_u *varp; // currently used value
+ char *varp; // currently used value
char_u *varp_fresh; // local value
char_u *varp_local = NULL; // fresh value
char *cmd;
@@ -5564,7 +3498,7 @@ int makeset(FILE *fd, int opt_flags, int local_only)
continue;
}
// Global values are only written when not at the default value.
- if ((opt_flags & OPT_GLOBAL) && optval_default(p, varp)) {
+ if ((opt_flags & OPT_GLOBAL) && optval_default(p, (char_u *)varp)) {
continue;
}
@@ -5583,11 +3517,11 @@ int makeset(FILE *fd, int opt_flags, int local_only)
// When fresh value of window-local option is not at the
// default, need to write it too.
if (!(opt_flags & OPT_GLOBAL) && !local_only) {
- varp_fresh = get_varp_scope(p, OPT_GLOBAL);
+ varp_fresh = (char_u *)get_varp_scope(p, OPT_GLOBAL);
if (!optval_default(p, varp_fresh)) {
round = 1;
- varp_local = varp;
- varp = varp_fresh;
+ varp_local = (char_u *)varp;
+ varp = (char *)varp_fresh;
}
}
}
@@ -5595,7 +3529,7 @@ int makeset(FILE *fd, int opt_flags, int local_only)
// Round 1: fresh value for window-local options.
// Round 2: other values
- for (; round <= 2; varp = varp_local, round++) {
+ for (; round <= 2; varp = (char *)varp_local, round++) {
if (round == 1 || (opt_flags & OPT_GLOBAL)) {
cmd = "set";
} else {
@@ -5623,8 +3557,7 @@ int makeset(FILE *fd, int opt_flags, int local_only)
}
do_endif = true;
}
- if (put_setstring(fd, cmd, p->fullname, (char_u **)varp,
- p->flags) == FAIL) {
+ if (put_setstring(fd, cmd, p->fullname, (char **)varp, p->flags) == FAIL) {
return FAIL;
}
if (do_endif) {
@@ -5645,29 +3578,25 @@ int makeset(FILE *fd, int opt_flags, int local_only)
int makefoldset(FILE *fd)
{
if (put_setstring(fd, "setlocal", "fdm", &curwin->w_p_fdm, 0) == FAIL
- || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, 0)
- == FAIL
- || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, 0)
- == FAIL
- || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, 0)
- == FAIL
+ || put_setstring(fd, "setlocal", "fde", &curwin->w_p_fde, 0) == FAIL
+ || put_setstring(fd, "setlocal", "fmr", &curwin->w_p_fmr, 0) == FAIL
+ || put_setstring(fd, "setlocal", "fdi", &curwin->w_p_fdi, 0) == FAIL
|| put_setnum(fd, "setlocal", "fdl", &curwin->w_p_fdl) == FAIL
|| put_setnum(fd, "setlocal", "fml", &curwin->w_p_fml) == FAIL
|| put_setnum(fd, "setlocal", "fdn", &curwin->w_p_fdn) == FAIL
- || put_setbool(fd, "setlocal", "fen",
- curwin->w_p_fen) == FAIL) {
+ || put_setbool(fd, "setlocal", "fen", curwin->w_p_fen) == FAIL) {
return FAIL;
}
return OK;
}
-static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint64_t flags)
+static int put_setstring(FILE *fd, char *cmd, char *name, char **valuep, uint64_t flags)
{
char_u *s;
char_u *buf = NULL;
char_u *part = NULL;
- char_u *p;
+ char *p;
if (fprintf(fd, "%s %s=", cmd, name) < 0) {
return FAIL;
@@ -5677,7 +3606,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint6
// options some characters have to be escaped with
// CTRL-V or backslash
if (valuep == &p_pt) {
- s = *valuep;
+ s = (char_u *)(*valuep);
while (*s != NUL) {
if (put_escstr(fd, (char_u *)str2special((const char **)&s, false,
false), 2)
@@ -5690,27 +3619,27 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint6
// replace home directory in the whole option value into "buf"
buf = xmalloc(size);
- home_replace(NULL, (char *)(*valuep), (char *)buf, size, false);
+ home_replace(NULL, *valuep, (char *)buf, size, false);
// If the option value is longer than MAXPATHL, we need to append
// each comma separated part of the option separately, so that it
// can be expanded when read back.
if (size >= MAXPATHL && (flags & P_COMMA) != 0
- && vim_strchr((char *)(*valuep), ',') != NULL) {
+ && vim_strchr(*valuep, ',') != NULL) {
part = xmalloc(size);
// write line break to clear the option, e.g. ':set rtp='
if (put_eol(fd) == FAIL) {
goto fail;
}
- p = buf;
+ p = (char *)buf;
while (*p != NUL) {
// for each comma separated option part, append value to
// the option, :set rtp+=value
if (fprintf(fd, "%s %s+=", cmd, name) < 0) {
goto fail;
}
- (void)copy_option_part((char **)&p, (char *)part, size, ",");
+ (void)copy_option_part(&p, (char *)part, size, ",");
if (put_escstr(fd, part, 2) == FAIL || put_eol(fd) == FAIL) {
goto fail;
}
@@ -5724,7 +3653,7 @@ static int put_setstring(FILE *fd, char *cmd, char *name, char_u **valuep, uint6
return FAIL;
}
xfree(buf);
- } else if (put_escstr(fd, *valuep, 2) == FAIL) {
+ } else if (put_escstr(fd, (char_u *)(*valuep), 2) == FAIL) {
return FAIL;
}
}
@@ -5771,47 +3700,6 @@ static int put_setbool(FILE *fd, char *cmd, char *name, int value)
return OK;
}
-/// Compute columns for ruler and shown command. 'sc_col' is also used to
-/// decide what the maximum length of a message on the status line can be.
-/// If there is a status line for the last window, 'sc_col' is independent
-/// of 'ru_col'.
-
-#define COL_RULER 17 // columns needed by standard ruler
-
-void comp_col(void)
-{
- int last_has_status = (p_ls > 1 || (p_ls == 1 && !ONE_WINDOW));
-
- sc_col = 0;
- ru_col = 0;
- if (p_ru) {
- ru_col = (ru_wid ? ru_wid : COL_RULER) + 1;
- // no last status line, adjust sc_col
- if (!last_has_status) {
- sc_col = ru_col;
- }
- }
- if (p_sc) {
- sc_col += SHOWCMD_COLS;
- if (!p_ru || last_has_status) { // no need for separating space
- sc_col++;
- }
- }
- assert(sc_col >= 0
- && INT_MIN + sc_col <= Columns);
- sc_col = Columns - sc_col;
- assert(ru_col >= 0
- && INT_MIN + ru_col <= Columns);
- ru_col = Columns - ru_col;
- if (sc_col <= 0) { // screen too narrow, will become a mess
- sc_col = 1;
- }
- if (ru_col <= 0) {
- ru_col = 1;
- }
- set_vim_var_nr(VV_ECHOSPACE, sc_col - 1);
-}
-
// Unset local option value, similar to ":set opt<".
void unset_global_local_option(char *name, void *from)
{
@@ -5891,7 +3779,7 @@ void unset_global_local_option(char *name, void *from)
clear_string_option(&((win_T *)from)->w_p_stl);
break;
case PV_WBR:
- clear_string_option((char_u **)&((win_T *)from)->w_p_wbr);
+ clear_string_option(&((win_T *)from)->w_p_wbr);
break;
case PV_UL:
buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
@@ -5905,12 +3793,12 @@ void unset_global_local_option(char *name, void *from)
case PV_LCS:
clear_string_option(&((win_T *)from)->w_p_lcs);
set_chars_option((win_T *)from, &((win_T *)from)->w_p_lcs, true);
- redraw_later((win_T *)from, NOT_VALID);
+ redraw_later((win_T *)from, UPD_NOT_VALID);
break;
case PV_FCS:
clear_string_option(&((win_T *)from)->w_p_fcs);
set_chars_option((win_T *)from, &((win_T *)from)->w_p_fcs, true);
- redraw_later((win_T *)from, NOT_VALID);
+ redraw_later((win_T *)from, UPD_NOT_VALID);
break;
case PV_VE:
clear_string_option(&((win_T *)from)->w_p_ve);
@@ -5920,76 +3808,83 @@ void unset_global_local_option(char *name, void *from)
}
/// Get pointer to option variable, depending on local or global scope.
-static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
+static char *get_varp_scope(vimoption_T *p, int opt_flags)
{
if ((opt_flags & OPT_GLOBAL) && p->indir != PV_NONE) {
if (p->var == VAR_WIN) {
- return (char_u *)GLOBAL_WO(get_varp(p));
+ return GLOBAL_WO(get_varp(p));
}
- return p->var;
+ return (char *)p->var;
}
if ((opt_flags & OPT_LOCAL) && ((int)p->indir & PV_BOTH)) {
switch ((int)p->indir) {
case PV_FP:
- return (char_u *)&(curbuf->b_p_fp);
+ return (char *)&(curbuf->b_p_fp);
case PV_EFM:
- return (char_u *)&(curbuf->b_p_efm);
+ return (char *)&(curbuf->b_p_efm);
case PV_GP:
- return (char_u *)&(curbuf->b_p_gp);
+ return (char *)&(curbuf->b_p_gp);
case PV_MP:
- return (char_u *)&(curbuf->b_p_mp);
+ return (char *)&(curbuf->b_p_mp);
case PV_EP:
- return (char_u *)&(curbuf->b_p_ep);
+ return (char *)&(curbuf->b_p_ep);
case PV_KP:
- return (char_u *)&(curbuf->b_p_kp);
+ return (char *)&(curbuf->b_p_kp);
case PV_PATH:
- return (char_u *)&(curbuf->b_p_path);
+ return (char *)&(curbuf->b_p_path);
case PV_AR:
- return (char_u *)&(curbuf->b_p_ar);
+ return (char *)&(curbuf->b_p_ar);
case PV_TAGS:
- return (char_u *)&(curbuf->b_p_tags);
+ return (char *)&(curbuf->b_p_tags);
case PV_TC:
- return (char_u *)&(curbuf->b_p_tc);
+ return (char *)&(curbuf->b_p_tc);
case PV_SISO:
- return (char_u *)&(curwin->w_p_siso);
+ return (char *)&(curwin->w_p_siso);
case PV_SO:
- return (char_u *)&(curwin->w_p_so);
+ return (char *)&(curwin->w_p_so);
case PV_DEF:
- return (char_u *)&(curbuf->b_p_def);
+ return (char *)&(curbuf->b_p_def);
case PV_INC:
- return (char_u *)&(curbuf->b_p_inc);
+ return (char *)&(curbuf->b_p_inc);
case PV_DICT:
- return (char_u *)&(curbuf->b_p_dict);
+ return (char *)&(curbuf->b_p_dict);
case PV_TSR:
- return (char_u *)&(curbuf->b_p_tsr);
+ return (char *)&(curbuf->b_p_tsr);
case PV_TSRFU:
- return (char_u *)&(curbuf->b_p_tsrfu);
+ return (char *)&(curbuf->b_p_tsrfu);
case PV_TFU:
- return (char_u *)&(curbuf->b_p_tfu);
+ return (char *)&(curbuf->b_p_tfu);
case PV_SBR:
- return (char_u *)&(curwin->w_p_sbr);
+ return (char *)&(curwin->w_p_sbr);
case PV_STL:
- return (char_u *)&(curwin->w_p_stl);
+ return (char *)&(curwin->w_p_stl);
case PV_WBR:
- return (char_u *)&(curwin->w_p_wbr);
+ return (char *)&(curwin->w_p_wbr);
case PV_UL:
- return (char_u *)&(curbuf->b_p_ul);
+ return (char *)&(curbuf->b_p_ul);
case PV_LW:
- return (char_u *)&(curbuf->b_p_lw);
+ return (char *)&(curbuf->b_p_lw);
case PV_BKC:
- return (char_u *)&(curbuf->b_p_bkc);
+ return (char *)&(curbuf->b_p_bkc);
case PV_MENC:
- return (char_u *)&(curbuf->b_p_menc);
+ return (char *)&(curbuf->b_p_menc);
case PV_FCS:
- return (char_u *)&(curwin->w_p_fcs);
+ return (char *)&(curwin->w_p_fcs);
case PV_LCS:
- return (char_u *)&(curwin->w_p_lcs);
+ return (char *)&(curwin->w_p_lcs);
case PV_VE:
- return (char_u *)&(curwin->w_p_ve);
+ return (char *)&(curwin->w_p_ve);
}
return NULL; // "cannot happen"
}
- return get_varp(p);
+ return (char *)get_varp(p);
+}
+
+/// Get pointer to option variable at 'opt_idx', depending on local or global
+/// scope.
+char *get_option_varp_scope(int opt_idx, int opt_flags)
+{
+ return get_varp_scope(&(options[opt_idx]), opt_flags);
}
/// Get pointer to option variable.
@@ -6303,13 +4198,25 @@ static char_u *get_varp(vimoption_T *p)
return (char_u *)&(curbuf->b_p_wm);
}
+/// Return a pointer to the variable for option at 'opt_idx'
+char_u *get_option_var(int opt_idx)
+{
+ return options[opt_idx].var;
+}
+
+/// Return the full name of the option at 'opt_idx'
+char *get_option_fullname(int opt_idx)
+{
+ return options[opt_idx].fullname;
+}
+
/// Get the value of 'equalprg', either the buffer-local one or the global one.
char_u *get_equalprg(void)
{
if (*curbuf->b_p_ep == NUL) {
return p_ep;
}
- return curbuf->b_p_ep;
+ return (char_u *)curbuf->b_p_ep;
}
/// Copy options from one window to another.
@@ -6318,7 +4225,15 @@ void win_copy_options(win_T *wp_from, win_T *wp_to)
{
copy_winopt(&wp_from->w_onebuf_opt, &wp_to->w_onebuf_opt);
copy_winopt(&wp_from->w_allbuf_opt, &wp_to->w_allbuf_opt);
- didset_window_options(wp_to);
+ didset_window_options(wp_to, true);
+}
+
+static char *copy_option_val(const char *val)
+{
+ if (val == empty_option) {
+ return empty_option; // no need to allocate memory
+ }
+ return xstrdup(val);
}
/// Copy the options from one winopt_T to another.
@@ -6329,21 +4244,23 @@ void copy_winopt(winopt_T *from, winopt_T *to)
{
to->wo_arab = from->wo_arab;
to->wo_list = from->wo_list;
+ to->wo_lcs = copy_option_val(from->wo_lcs);
+ to->wo_fcs = copy_option_val(from->wo_fcs);
to->wo_nu = from->wo_nu;
to->wo_rnu = from->wo_rnu;
- to->wo_ve = vim_strsave(from->wo_ve);
+ to->wo_ve = copy_option_val(from->wo_ve);
to->wo_ve_flags = from->wo_ve_flags;
to->wo_nuw = from->wo_nuw;
to->wo_rl = from->wo_rl;
- to->wo_rlc = vim_strsave(from->wo_rlc);
- to->wo_sbr = vim_strsave(from->wo_sbr);
- to->wo_stl = vim_strsave(from->wo_stl);
- to->wo_wbr = xstrdup(from->wo_wbr);
+ to->wo_rlc = copy_option_val(from->wo_rlc);
+ to->wo_sbr = copy_option_val(from->wo_sbr);
+ to->wo_stl = copy_option_val(from->wo_stl);
+ to->wo_wbr = copy_option_val(from->wo_wbr);
to->wo_wrap = from->wo_wrap;
to->wo_wrap_save = from->wo_wrap_save;
to->wo_lbr = from->wo_lbr;
to->wo_bri = from->wo_bri;
- to->wo_briopt = vim_strsave(from->wo_briopt);
+ to->wo_briopt = copy_option_val(from->wo_briopt);
to->wo_scb = from->wo_scb;
to->wo_scb_save = from->wo_scb_save;
to->wo_crb = from->wo_crb;
@@ -6351,32 +4268,28 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_spell = from->wo_spell;
to->wo_cuc = from->wo_cuc;
to->wo_cul = from->wo_cul;
- to->wo_culopt = vim_strsave(from->wo_culopt);
- to->wo_cc = vim_strsave(from->wo_cc);
+ to->wo_culopt = copy_option_val(from->wo_culopt);
+ to->wo_cc = copy_option_val(from->wo_cc);
to->wo_diff = from->wo_diff;
to->wo_diff_saved = from->wo_diff_saved;
- to->wo_cocu = vim_strsave(from->wo_cocu);
+ to->wo_cocu = copy_option_val(from->wo_cocu);
to->wo_cole = from->wo_cole;
- to->wo_fdc = vim_strsave(from->wo_fdc);
- to->wo_fdc_save = from->wo_diff_saved
- ? vim_strsave(from->wo_fdc_save) : empty_option;
+ to->wo_fdc = copy_option_val(from->wo_fdc);
+ to->wo_fdc_save = from->wo_diff_saved ? xstrdup(from->wo_fdc_save) : empty_option;
to->wo_fen = from->wo_fen;
to->wo_fen_save = from->wo_fen_save;
- to->wo_fdi = vim_strsave(from->wo_fdi);
+ to->wo_fdi = copy_option_val(from->wo_fdi);
to->wo_fml = from->wo_fml;
to->wo_fdl = from->wo_fdl;
to->wo_fdl_save = from->wo_fdl_save;
- to->wo_fdm = vim_strsave(from->wo_fdm);
- to->wo_fdm_save = from->wo_diff_saved
- ? vim_strsave(from->wo_fdm_save) : empty_option;
+ to->wo_fdm = copy_option_val(from->wo_fdm);
+ to->wo_fdm_save = from->wo_diff_saved ? xstrdup(from->wo_fdm_save) : empty_option;
to->wo_fdn = from->wo_fdn;
- to->wo_fde = vim_strsave(from->wo_fde);
- to->wo_fdt = vim_strsave(from->wo_fdt);
- to->wo_fmr = vim_strsave(from->wo_fmr);
- to->wo_scl = vim_strsave(from->wo_scl);
- to->wo_winhl = vim_strsave(from->wo_winhl);
- to->wo_fcs = vim_strsave(from->wo_fcs);
- to->wo_lcs = vim_strsave(from->wo_lcs);
+ to->wo_fde = copy_option_val(from->wo_fde);
+ to->wo_fdt = copy_option_val(from->wo_fdt);
+ to->wo_fmr = copy_option_val(from->wo_fmr);
+ to->wo_scl = copy_option_val(from->wo_scl);
+ to->wo_winhl = copy_option_val(from->wo_winhl);
to->wo_winbl = from->wo_winbl;
// Copy the script context so that we know were the value was last set.
@@ -6411,10 +4324,10 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_cocu);
check_string_option(&wop->wo_briopt);
check_string_option(&wop->wo_winhl);
- check_string_option(&wop->wo_fcs);
check_string_option(&wop->wo_lcs);
+ check_string_option(&wop->wo_fcs);
check_string_option(&wop->wo_ve);
- check_string_option((char_u **)&wop->wo_wbr);
+ check_string_option(&wop->wo_wbr);
}
/// Free the allocated memory inside a winopt_T.
@@ -6437,13 +4350,13 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_cocu);
clear_string_option(&wop->wo_briopt);
clear_string_option(&wop->wo_winhl);
- clear_string_option(&wop->wo_fcs);
clear_string_option(&wop->wo_lcs);
+ clear_string_option(&wop->wo_fcs);
clear_string_option(&wop->wo_ve);
- clear_string_option((char_u **)&wop->wo_wbr);
+ clear_string_option(&wop->wo_wbr);
}
-void didset_window_options(win_T *wp)
+void didset_window_options(win_T *wp, bool valid_cursor)
{
check_colorcolumn(wp);
briopt_check(wp);
@@ -6452,7 +4365,7 @@ void didset_window_options(win_T *wp)
set_chars_option(wp, &wp->w_p_lcs, true);
parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl
check_blending(wp);
- set_winbar_win(wp, false);
+ set_winbar_win(wp, false, valid_cursor);
wp->w_grid_alloc.blending = wp->w_p_winbl > 0;
}
@@ -6515,14 +4428,14 @@ void buf_copy_options(buf_T *buf, int flags)
}
if (should_copy || (flags & BCO_ALWAYS)) {
- memset(buf->b_p_script_ctx, 0, sizeof(buf->b_p_script_ctx));
+ CLEAR_FIELD(buf->b_p_script_ctx);
init_buf_opt_idx();
// Don't copy the options specific to a help buffer when
// BCO_NOHELP is given or the options were initialized already
// (jumping back to a help file with CTRL-T or CTRL-O)
dont_do_help = ((flags & BCO_NOHELP) && buf->b_help) || buf->b_p_initialized;
if (dont_do_help) { // don't free b_p_isk
- save_p_isk = buf->b_p_isk;
+ save_p_isk = (char_u *)buf->b_p_isk;
buf->b_p_isk = NULL;
}
// Always free the allocated strings. If not already initialized,
@@ -6530,19 +4443,19 @@ void buf_copy_options(buf_T *buf, int flags)
if (!buf->b_p_initialized) {
free_buf_options(buf, true);
buf->b_p_ro = false; // don't copy readonly
- buf->b_p_fenc = vim_strsave(p_fenc);
+ buf->b_p_fenc = xstrdup(p_fenc);
switch (*p_ffs) {
case 'm':
- buf->b_p_ff = vim_strsave((char_u *)FF_MAC);
+ buf->b_p_ff = xstrdup(FF_MAC);
break;
case 'd':
- buf->b_p_ff = vim_strsave((char_u *)FF_DOS);
+ buf->b_p_ff = xstrdup(FF_DOS);
break;
case 'u':
- buf->b_p_ff = vim_strsave((char_u *)FF_UNIX);
+ buf->b_p_ff = xstrdup(FF_UNIX);
break;
default:
- buf->b_p_ff = vim_strsave(p_ff);
+ buf->b_p_ff = xstrdup(p_ff);
break;
}
buf->b_p_bh = empty_option;
@@ -6587,44 +4500,42 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_swf = p_swf;
COPY_OPT_SCTX(buf, BV_SWF);
}
- buf->b_p_cpt = vim_strsave(p_cpt);
+ buf->b_p_cpt = xstrdup(p_cpt);
COPY_OPT_SCTX(buf, BV_CPT);
#ifdef BACKSLASH_IN_FILENAME
buf->b_p_csl = vim_strsave(p_csl);
COPY_OPT_SCTX(buf, BV_CSL);
#endif
- buf->b_p_cfu = vim_strsave(p_cfu);
+ buf->b_p_cfu = xstrdup(p_cfu);
COPY_OPT_SCTX(buf, BV_CFU);
- buf->b_p_ofu = vim_strsave(p_ofu);
+ buf->b_p_ofu = xstrdup(p_ofu);
COPY_OPT_SCTX(buf, BV_OFU);
- buf->b_p_tfu = vim_strsave(p_tfu);
+ buf->b_p_tfu = xstrdup(p_tfu);
COPY_OPT_SCTX(buf, BV_TFU);
- buf->b_p_umf = vim_strsave(p_umf);
+ buf->b_p_umf = xstrdup(p_umf);
COPY_OPT_SCTX(buf, BV_UMF);
buf->b_p_sts = p_sts;
COPY_OPT_SCTX(buf, BV_STS);
buf->b_p_sts_nopaste = p_sts_nopaste;
- buf->b_p_vsts = vim_strsave(p_vsts);
+ buf->b_p_vsts = xstrdup(p_vsts);
COPY_OPT_SCTX(buf, BV_VSTS);
if (p_vsts && p_vsts != empty_option) {
(void)tabstop_set(p_vsts, &buf->b_p_vsts_array);
} else {
buf->b_p_vsts_array = NULL;
}
- buf->b_p_vsts_nopaste = p_vsts_nopaste
- ? vim_strsave(p_vsts_nopaste)
- : NULL;
- buf->b_p_com = vim_strsave(p_com);
+ buf->b_p_vsts_nopaste = p_vsts_nopaste ? xstrdup(p_vsts_nopaste) : NULL;
+ buf->b_p_com = xstrdup(p_com);
COPY_OPT_SCTX(buf, BV_COM);
- buf->b_p_cms = vim_strsave(p_cms);
+ buf->b_p_cms = xstrdup(p_cms);
COPY_OPT_SCTX(buf, BV_CMS);
- buf->b_p_fo = vim_strsave(p_fo);
+ buf->b_p_fo = xstrdup(p_fo);
COPY_OPT_SCTX(buf, BV_FO);
- buf->b_p_flp = vim_strsave(p_flp);
+ buf->b_p_flp = xstrdup(p_flp);
COPY_OPT_SCTX(buf, BV_FLP);
- buf->b_p_nf = vim_strsave(p_nf);
+ buf->b_p_nf = xstrdup(p_nf);
COPY_OPT_SCTX(buf, BV_NF);
- buf->b_p_mps = vim_strsave(p_mps);
+ buf->b_p_mps = xstrdup(p_mps);
COPY_OPT_SCTX(buf, BV_MPS);
buf->b_p_si = p_si;
COPY_OPT_SCTX(buf, BV_SI);
@@ -6634,18 +4545,18 @@ void buf_copy_options(buf_T *buf, int flags)
COPY_OPT_SCTX(buf, BV_CI);
buf->b_p_cin = p_cin;
COPY_OPT_SCTX(buf, BV_CIN);
- buf->b_p_cink = vim_strsave(p_cink);
+ buf->b_p_cink = xstrdup(p_cink);
COPY_OPT_SCTX(buf, BV_CINK);
- buf->b_p_cino = vim_strsave(p_cino);
+ buf->b_p_cino = xstrdup(p_cino);
COPY_OPT_SCTX(buf, BV_CINO);
- buf->b_p_cinsd = vim_strsave(p_cinsd);
+ buf->b_p_cinsd = xstrdup(p_cinsd);
COPY_OPT_SCTX(buf, BV_CINSD);
// Don't copy 'filetype', it must be detected
buf->b_p_ft = empty_option;
buf->b_p_pi = p_pi;
COPY_OPT_SCTX(buf, BV_PI);
- buf->b_p_cinw = vim_strsave(p_cinw);
+ buf->b_p_cinw = xstrdup(p_cinw);
COPY_OPT_SCTX(buf, BV_CINW);
buf->b_p_lisp = p_lisp;
COPY_OPT_SCTX(buf, BV_LISP);
@@ -6654,25 +4565,25 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_smc = p_smc;
COPY_OPT_SCTX(buf, BV_SMC);
buf->b_s.b_syn_isk = empty_option;
- buf->b_s.b_p_spc = vim_strsave(p_spc);
+ buf->b_s.b_p_spc = xstrdup(p_spc);
COPY_OPT_SCTX(buf, BV_SPC);
(void)compile_cap_prog(&buf->b_s);
- buf->b_s.b_p_spf = vim_strsave(p_spf);
+ buf->b_s.b_p_spf = xstrdup(p_spf);
COPY_OPT_SCTX(buf, BV_SPF);
- buf->b_s.b_p_spl = vim_strsave(p_spl);
+ buf->b_s.b_p_spl = xstrdup(p_spl);
COPY_OPT_SCTX(buf, BV_SPL);
- buf->b_s.b_p_spo = vim_strsave(p_spo);
+ buf->b_s.b_p_spo = xstrdup(p_spo);
COPY_OPT_SCTX(buf, BV_SPO);
- buf->b_p_inde = vim_strsave(p_inde);
+ buf->b_p_inde = xstrdup(p_inde);
COPY_OPT_SCTX(buf, BV_INDE);
- buf->b_p_indk = vim_strsave(p_indk);
+ buf->b_p_indk = xstrdup(p_indk);
COPY_OPT_SCTX(buf, BV_INDK);
buf->b_p_fp = empty_option;
- buf->b_p_fex = vim_strsave(p_fex);
+ buf->b_p_fex = xstrdup(p_fex);
COPY_OPT_SCTX(buf, BV_FEX);
- buf->b_p_sua = vim_strsave(p_sua);
+ buf->b_p_sua = xstrdup(p_sua);
COPY_OPT_SCTX(buf, BV_SUA);
- buf->b_p_keymap = vim_strsave(p_keymap);
+ buf->b_p_keymap = xstrdup(p_keymap);
COPY_OPT_SCTX(buf, BV_KMAP);
buf->b_kmap_state |= KEYMAP_INIT;
// This isn't really an option, but copying the langmap and IME
@@ -6699,12 +4610,12 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_tc_flags = 0;
buf->b_p_def = empty_option;
buf->b_p_inc = empty_option;
- buf->b_p_inex = vim_strsave(p_inex);
+ buf->b_p_inex = xstrdup(p_inex);
COPY_OPT_SCTX(buf, BV_INEX);
buf->b_p_dict = empty_option;
buf->b_p_tsr = empty_option;
buf->b_p_tsrfu = empty_option;
- buf->b_p_qe = vim_strsave(p_qe);
+ buf->b_p_qe = xstrdup(p_qe);
COPY_OPT_SCTX(buf, BV_QE);
buf->b_p_udf = p_udf;
COPY_OPT_SCTX(buf, BV_UDF);
@@ -6718,19 +4629,19 @@ void buf_copy_options(buf_T *buf, int flags)
* or to a help buffer.
*/
if (dont_do_help) {
- buf->b_p_isk = save_p_isk;
+ buf->b_p_isk = (char *)save_p_isk;
if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) {
(void)tabstop_set(p_vts, &buf->b_p_vts_array);
} else {
buf->b_p_vts_array = NULL;
}
} else {
- buf->b_p_isk = vim_strsave(p_isk);
+ buf->b_p_isk = xstrdup(p_isk);
COPY_OPT_SCTX(buf, BV_ISK);
did_isk = true;
buf->b_p_ts = p_ts;
COPY_OPT_SCTX(buf, BV_TS);
- buf->b_p_vts = vim_strsave(p_vts);
+ buf->b_p_vts = xstrdup(p_vts);
COPY_OPT_SCTX(buf, BV_VTS);
if (p_vts && p_vts != empty_option && !buf->b_p_vts_array) {
(void)tabstop_set(p_vts, &buf->b_p_vts_array);
@@ -7051,7 +4962,7 @@ void ExpandOldSetting(int *num_file, char ***file)
if (expand_option_idx >= 0) {
// Put string of option value in NameBuff.
option_value2string(&options[expand_option_idx], expand_option_flags);
- var = NameBuff;
+ var = (char_u *)NameBuff;
} else {
var = (char_u *)"";
}
@@ -7084,9 +4995,7 @@ void ExpandOldSetting(int *num_file, char ***file)
/// @param opt_flags OPT_GLOBAL and/or OPT_LOCAL
static void option_value2string(vimoption_T *opp, int opt_flags)
{
- char_u *varp;
-
- varp = get_varp_scope(opp, opt_flags);
+ char_u *varp = (char_u *)get_varp_scope(opp, opt_flags);
if (opp->flags & P_NUM) {
long wc = 0;
@@ -7108,7 +5017,7 @@ static void option_value2string(vimoption_T *opp, int opt_flags)
} else if (opp->flags & P_EXPAND) {
home_replace(NULL, (char *)varp, (char *)NameBuff, MAXPATHL, false);
// Translate 'pastetoggle' into special key names.
- } else if ((char_u **)opp->var == &p_pt) {
+ } else if ((char **)opp->var == &p_pt) {
str2specialbuf((const char *)p_pt, (char *)NameBuff, MAXPATHL);
} else {
STRLCPY(NameBuff, varp, MAXPATHL);
@@ -7130,25 +5039,14 @@ static int wc_use_keyname(char_u *varp, long *wcp)
return false;
}
-/// Return true if format option 'x' is in effect.
-/// Take care of no formatting when 'paste' is set.
-bool has_format_option(int x)
- FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
-{
- if (p_paste) {
- return false;
- }
- return vim_strchr((char *)curbuf->b_p_fo, x) != NULL;
-}
-
/// @returns true if "x" is present in 'shortmess' option, or
/// 'shortmess' contains 'a' and "x" is present in SHM_ALL_ABBREVIATIONS.
bool shortmess(int x)
{
return (p_shm != NULL
- && (vim_strchr((char *)p_shm, x) != NULL
- || (vim_strchr((char *)p_shm, 'a') != NULL
- && vim_strchr((char *)SHM_ALL_ABBREVIATIONS, x) != NULL)));
+ && (vim_strchr(p_shm, x) != NULL
+ || (vim_strchr(p_shm, 'a') != NULL
+ && vim_strchr(SHM_ALL_ABBREVIATIONS, x) != NULL)));
}
/// paste_option_changed() - Called after p_paste was set or reset.
@@ -7178,7 +5076,7 @@ static void paste_option_changed(void)
xfree(buf->b_p_vsts_nopaste);
}
buf->b_p_vsts_nopaste = buf->b_p_vsts && buf->b_p_vsts != empty_option
- ? vim_strsave(buf->b_p_vsts)
+ ? xstrdup(buf->b_p_vsts)
: NULL;
}
@@ -7197,9 +5095,7 @@ static void paste_option_changed(void)
if (p_vsts_nopaste) {
xfree(p_vsts_nopaste);
}
- p_vsts_nopaste = p_vsts && p_vsts != empty_option
- ? vim_strsave(p_vsts)
- : NULL;
+ p_vsts_nopaste = p_vsts && p_vsts != empty_option ? xstrdup(p_vsts) : NULL;
}
// Always set the option values, also when 'paste' is set when it is
@@ -7249,9 +5145,7 @@ static void paste_option_changed(void)
if (buf->b_p_vsts) {
free_string_option(buf->b_p_vsts);
}
- buf->b_p_vsts = buf->b_p_vsts_nopaste
- ? vim_strsave(buf->b_p_vsts_nopaste)
- : empty_option;
+ buf->b_p_vsts = buf->b_p_vsts_nopaste ? xstrdup(buf->b_p_vsts_nopaste) : empty_option;
xfree(buf->b_p_vsts_array);
if (buf->b_p_vsts && buf->b_p_vsts != empty_option) {
(void)tabstop_set(buf->b_p_vsts, &buf->b_p_vsts_array);
@@ -7278,7 +5172,7 @@ static void paste_option_changed(void)
if (p_vsts) {
free_string_option(p_vsts);
}
- p_vsts = p_vsts_nopaste ? vim_strsave(p_vsts_nopaste) : empty_option;
+ p_vsts = p_vsts_nopaste ? xstrdup(p_vsts_nopaste) : empty_option;
}
old_p_paste = p_paste;
@@ -7336,7 +5230,7 @@ void reset_option_was_set(const char *name)
}
/// fill_breakat_flags() -- called when 'breakat' changes value.
-static void fill_breakat_flags(void)
+void fill_breakat_flags(void)
{
char_u *p;
int i;
@@ -7346,16 +5240,16 @@ static void fill_breakat_flags(void)
}
if (p_breakat != NULL) {
- for (p = p_breakat; *p; p++) {
+ for (p = (char_u *)p_breakat; *p; p++) {
breakat_flags[*p] = true;
}
}
}
/// fill_culopt_flags() -- called when 'culopt' changes value
-static int fill_culopt_flags(char_u *val, win_T *wp)
+int fill_culopt_flags(char *val, win_T *wp)
{
- char_u *p;
+ char *p;
char_u culopt_flags_new = 0;
if (val == NULL) {
@@ -7395,101 +5289,41 @@ static int fill_culopt_flags(char_u *val, win_T *wp)
return OK;
}
-/// Check an option that can be a range of string values.
-///
-/// @param list when true: accept a list of values
-///
-/// @return OK for correct value, FAIL otherwise. Empty is always OK.
-static int check_opt_strings(char_u *val, char **values, int list)
-{
- return opt_strings_flags(val, values, NULL, list);
-}
-
-/// Handle an option that can be a range of string values.
-/// Set a flag in "*flagp" for each string present.
-///
-/// @param val new value
-/// @param values array of valid string values
-/// @param list when true: accept a list of values
-///
-/// @return OK for correct value, FAIL otherwise. Empty is always OK.
-static int opt_strings_flags(char_u *val, char **values, unsigned *flagp, bool list)
-{
- unsigned int new_flags = 0;
-
- while (*val) {
- for (unsigned int i = 0;; i++) {
- if (values[i] == NULL) { // val not found in values[]
- return FAIL;
- }
-
- 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);
- new_flags |= (1U << i);
- break; // check next item in val list
- }
- }
- }
- if (flagp != NULL) {
- *flagp = new_flags;
- }
-
- return OK;
-}
-
-/// Read the 'wildmode' option, fill wim_flags[].
-static int check_opt_wim(void)
+/// Set the callback function value for an option that accepts a function name,
+/// lambda, et al. (e.g. 'operatorfunc', 'tagfunc', etc.)
+/// @return OK if the option is successfully set to a function, otherwise FAIL
+int option_set_callback_func(char_u *optval, Callback *optcb)
{
- char_u new_wim_flags[4];
- char_u *p;
- int i;
- int idx = 0;
-
- for (i = 0; i < 4; i++) {
- new_wim_flags[i] = 0;
+ if (optval == NULL || *optval == NUL) {
+ callback_free(optcb);
+ return OK;
}
- for (p = p_wim; *p; p++) {
- for (i = 0; ASCII_ISALPHA(p[i]); i++) {}
- if (p[i] != NUL && p[i] != ',' && p[i] != ':') {
- return FAIL;
- }
- if (i == 7 && STRNCMP(p, "longest", 7) == 0) {
- new_wim_flags[idx] |= WIM_LONGEST;
- } else if (i == 4 && STRNCMP(p, "full", 4) == 0) {
- new_wim_flags[idx] |= WIM_FULL;
- } else if (i == 4 && STRNCMP(p, "list", 4) == 0) {
- new_wim_flags[idx] |= WIM_LIST;
- } else if (i == 8 && STRNCMP(p, "lastused", 8) == 0) {
- new_wim_flags[idx] |= WIM_BUFLASTUSED;
- } else {
+ typval_T *tv;
+ if (*optval == '{'
+ || (STRNCMP(optval, "function(", 9) == 0)
+ || (STRNCMP(optval, "funcref(", 8) == 0)) {
+ // Lambda expression or a funcref
+ tv = eval_expr((char *)optval);
+ if (tv == NULL) {
return FAIL;
}
- p += i;
- if (*p == NUL) {
- break;
- }
- if (*p == ',') {
- if (idx == 3) {
- return FAIL;
- }
- idx++;
- }
+ } else {
+ // treat everything else as a function name string
+ tv = xcalloc(1, sizeof(*tv));
+ tv->v_type = VAR_STRING;
+ tv->vval.v_string = (char *)vim_strsave(optval);
}
- // fill remaining entries with last flag
- while (idx < 3) {
- new_wim_flags[idx + 1] = new_wim_flags[idx];
- idx++;
+ Callback cb;
+ if (!callback_from_typval(&cb, tv)) {
+ tv_free(tv);
+ return FAIL;
}
- // only when there are no errors, wim_flags[] is changed
- for (i = 0; i < 4; i++) {
- wim_flags[i] = new_wim_flags[i];
- }
+ callback_free(optcb);
+ *optcb = cb;
+ tv_free(tv);
return OK;
}
@@ -7510,412 +5344,7 @@ bool can_bs(int what)
case '0':
return false;
}
- return vim_strchr((char *)p_bs, what) != NULL;
-}
-
-/// Save the current values of 'fileformat' and 'fileencoding', so that we know
-/// the file must be considered changed when the value is different.
-void save_file_ff(buf_T *buf)
-{
- buf->b_start_ffc = *buf->b_p_ff;
- buf->b_start_eol = buf->b_p_eol;
- buf->b_start_bomb = buf->b_p_bomb;
-
- // Only use free/alloc when necessary, they take time.
- if (buf->b_start_fenc == NULL
- || STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0) {
- xfree(buf->b_start_fenc);
- buf->b_start_fenc = (char *)vim_strsave(buf->b_p_fenc);
- }
-}
-
-/// Return true if 'fileformat' and/or 'fileencoding' has a different value
-/// from when editing started (save_file_ff() called).
-/// Also when 'endofline' was changed and 'binary' is set, or when 'bomb' was
-/// changed and 'binary' is not set.
-/// Also when 'endofline' was changed and 'fixeol' is not set.
-/// When "ignore_empty" is true don't consider a new, empty buffer to be
-/// changed.
-bool file_ff_differs(buf_T *buf, bool ignore_empty)
- FUNC_ATTR_NONNULL_ALL FUNC_ATTR_WARN_UNUSED_RESULT
-{
- // In a buffer that was never loaded the options are not valid.
- if (buf->b_flags & BF_NEVERLOADED) {
- return false;
- }
- if (ignore_empty
- && (buf->b_flags & BF_NEW)
- && buf->b_ml.ml_line_count == 1
- && *ml_get_buf(buf, (linenr_T)1, false) == NUL) {
- return false;
- }
- if (buf->b_start_ffc != *buf->b_p_ff) {
- return true;
- }
- if ((buf->b_p_bin || !buf->b_p_fixeol) && buf->b_start_eol != buf->b_p_eol) {
- return true;
- }
- if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb) {
- return true;
- }
- if (buf->b_start_fenc == NULL) {
- return *buf->b_p_fenc != NUL;
- }
- return STRCMP(buf->b_start_fenc, buf->b_p_fenc) != 0;
-}
-
-/// return OK if "p" is a valid fileformat name, FAIL otherwise.
-int check_ff_value(char_u *p)
-{
- return check_opt_strings(p, p_ff_values, false);
-}
-
-// Set the integer values corresponding to the string setting of 'vartabstop'.
-// "array" will be set, caller must free it if needed.
-// Return false for an error.
-bool tabstop_set(char_u *var, long **array)
-{
- long valcount = 1;
- int t;
- char_u *cp;
-
- if (var[0] == NUL || (var[0] == '0' && var[1] == NUL)) {
- *array = NULL;
- return true;
- }
-
- for (cp = var; *cp != NUL; cp++) {
- if (cp == var || cp[-1] == ',') {
- char_u *end;
-
- if (strtol((char *)cp, (char **)&end, 10) <= 0) {
- if (cp != end) {
- emsg(_(e_positive));
- } else {
- semsg(_(e_invarg2), cp);
- }
- return false;
- }
- }
-
- if (ascii_isdigit(*cp)) {
- continue;
- }
- if (cp[0] == ',' && cp > var && cp[-1] != ',' && cp[1] != NUL) {
- valcount++;
- continue;
- }
- semsg(_(e_invarg2), var);
- return false;
- }
-
- *array = (long *)xmalloc((unsigned)(valcount + 1) * sizeof(long));
- (*array)[0] = valcount;
-
- t = 1;
- for (cp = var; *cp != NUL;) {
- int n = atoi((char *)cp);
-
- // Catch negative values, overflow and ridiculous big values.
- if (n <= 0 || n > TABSTOP_MAX) {
- semsg(_(e_invarg2), cp);
- XFREE_CLEAR(*array);
- return false;
- }
- (*array)[t++] = n;
- while (*cp != NUL && *cp != ',') {
- cp++;
- }
- if (*cp != NUL) {
- cp++;
- }
- }
-
- return true;
-}
-
-// Calculate the number of screen spaces a tab will occupy.
-// If "vts" is set then the tab widths are taken from that array,
-// otherwise the value of ts is used.
-int tabstop_padding(colnr_T col, long ts_arg, long *vts)
-{
- long ts = ts_arg == 0 ? 8 : ts_arg;
- colnr_T tabcol = 0;
- int t;
- long padding = 0;
-
- if (vts == NULL || vts[0] == 0) {
- return (int)(ts - (col % ts));
- }
-
- const long tabcount = vts[0];
-
- for (t = 1; t <= tabcount; t++) {
- tabcol += (colnr_T)vts[t];
- if (tabcol > col) {
- padding = tabcol - col;
- break;
- }
- }
- if (t > tabcount) {
- padding = vts[tabcount] - ((col - tabcol) % vts[tabcount]);
- }
-
- return (int)padding;
-}
-
-// Find the size of the tab that covers a particular column.
-int tabstop_at(colnr_T col, long ts, long *vts)
-{
- colnr_T tabcol = 0;
- int t;
- long tab_size = 0;
-
- if (vts == NULL || vts[0] == 0) {
- return (int)ts;
- }
-
- const long tabcount = vts[0];
- for (t = 1; t <= tabcount; t++) {
- tabcol += (colnr_T)vts[t];
- if (tabcol > col) {
- tab_size = vts[t];
- break;
- }
- }
- if (t > tabcount) {
- tab_size = vts[tabcount];
- }
-
- return (int)tab_size;
-}
-
-// Find the column on which a tab starts.
-colnr_T tabstop_start(colnr_T col, long ts, long *vts)
-{
- colnr_T tabcol = 0;
- int t;
-
- if (vts == NULL || vts[0] == 0) {
- return (int)((col / ts) * ts);
- }
-
- const long tabcount = vts[0];
- for (t = 1; t <= tabcount; t++) {
- tabcol += (colnr_T)vts[t];
- if (tabcol > col) {
- return (int)(tabcol - vts[t]);
- }
- }
-
- const int excess = (int)(tabcol % vts[tabcount]);
- return (int)(excess + ((col - excess) / vts[tabcount]) * vts[tabcount]);
-}
-
-// Find the number of tabs and spaces necessary to get from one column
-// to another.
-void tabstop_fromto(colnr_T start_col, colnr_T end_col, long ts_arg, long *vts, int *ntabs,
- int *nspcs)
-{
- int spaces = end_col - start_col;
- colnr_T tabcol = 0;
- long padding = 0;
- int t;
- long ts = ts_arg == 0 ? curbuf->b_p_ts : ts_arg;
-
- if (vts == NULL || vts[0] == 0) {
- int tabs = 0;
-
- const int initspc = (int)(ts - (start_col % ts));
- if (spaces >= initspc) {
- spaces -= initspc;
- tabs++;
- }
- tabs += (int)(spaces / ts);
- spaces -= (int)((spaces / ts) * ts);
-
- *ntabs = tabs;
- *nspcs = spaces;
- return;
- }
-
- // Find the padding needed to reach the next tabstop.
- const long tabcount = vts[0];
- for (t = 1; t <= tabcount; t++) {
- tabcol += (colnr_T)vts[t];
- if (tabcol > start_col) {
- padding = tabcol - start_col;
- break;
- }
- }
- if (t > tabcount) {
- padding = vts[tabcount] - ((start_col - tabcol) % vts[tabcount]);
- }
-
- // If the space needed is less than the padding no tabs can be used.
- if (spaces < padding) {
- *ntabs = 0;
- *nspcs = spaces;
- return;
- }
-
- *ntabs = 1;
- spaces -= (int)padding;
-
- // At least one tab has been used. See if any more will fit.
- while (spaces != 0 && ++t <= tabcount) {
- padding = vts[t];
- if (spaces < padding) {
- *nspcs = spaces;
- return;
- }
- *ntabs += 1;
- spaces -= (int)padding;
- }
-
- *ntabs += spaces / (int)vts[tabcount];
- *nspcs = spaces % (int)vts[tabcount];
-}
-
-// See if two tabstop arrays contain the same values.
-bool tabstop_eq(long *ts1, long *ts2)
-{
- int t;
-
- if ((ts1 == 0 && ts2) || (ts1 && ts2 == 0)) {
- return false;
- }
- if (ts1 == ts2) {
- return true;
- }
- if (ts1[0] != ts2[0]) {
- return false;
- }
-
- for (t = 1; t <= ts1[0]; t++) {
- if (ts1[t] != ts2[t]) {
- return false;
- }
- }
-
- return true;
-}
-
-// Copy a tabstop array, allocating space for the new array.
-int *tabstop_copy(long *oldts)
-{
- long *newts;
- int t;
-
- if (oldts == 0) {
- return 0;
- }
-
- newts = xmalloc((unsigned)(oldts[0] + 1) * sizeof(long));
- for (t = 0; t <= oldts[0]; t++) {
- newts[t] = oldts[t];
- }
-
- return (int *)newts;
-}
-
-// Return a count of the number of tabstops.
-int tabstop_count(long *ts)
-{
- return ts != NULL ? (int)ts[0] : 0;
-}
-
-// Return the first tabstop, or 8 if there are no tabstops defined.
-int tabstop_first(long *ts)
-{
- return ts != NULL ? (int)ts[1] : 8;
-}
-
-/// Return the effective shiftwidth value for current buffer, using the
-/// 'tabstop' value when 'shiftwidth' is zero.
-int get_sw_value(buf_T *buf)
-{
- long result = get_sw_value_col(buf, 0);
- assert(result >= 0 && result <= INT_MAX);
- return (int)result;
-}
-
-// Idem, using the first non-black in the current line.
-long get_sw_value_indent(buf_T *buf)
-{
- pos_T pos = curwin->w_cursor;
-
- pos.col = (colnr_T)getwhitecols_curline();
- return get_sw_value_pos(buf, &pos);
-}
-
-// Idem, using "pos".
-long get_sw_value_pos(buf_T *buf, pos_T *pos)
-{
- pos_T save_cursor = curwin->w_cursor;
- long sw_value;
-
- curwin->w_cursor = *pos;
- sw_value = get_sw_value_col(buf, get_nolist_virtcol());
- curwin->w_cursor = save_cursor;
- return sw_value;
-}
-
-// Idem, using virtual column "col".
-long get_sw_value_col(buf_T *buf, colnr_T col)
-{
- return buf->b_p_sw ? buf->b_p_sw
- : tabstop_at(col, buf->b_p_ts, buf->b_p_vts_array);
-}
-
-/// Return the effective softtabstop value for the current buffer,
-/// using the shiftwidth value when 'softtabstop' is negative.
-int get_sts_value(void)
-{
- long result = curbuf->b_p_sts < 0 ? get_sw_value(curbuf) : curbuf->b_p_sts;
- assert(result >= 0 && result <= INT_MAX);
- return (int)result;
-}
-
-/// This is called when 'breakindentopt' is changed and when a window is
-/// initialized
-static bool briopt_check(win_T *wp)
-{
- int bri_shift = 0;
- int bri_min = 20;
- bool bri_sbr = false;
- int bri_list = 0;
-
- char *p = (char *)wp->w_p_briopt;
- while (*p != NUL) {
- if (STRNCMP(p, "shift:", 6) == 0
- && ((p[6] == '-' && ascii_isdigit(p[7])) || ascii_isdigit(p[6]))) {
- p += 6;
- bri_shift = getdigits_int(&p, true, 0);
- } else if (STRNCMP(p, "min:", 4) == 0 && ascii_isdigit(p[4])) {
- p += 4;
- bri_min = getdigits_int(&p, true, 0);
- } else if (STRNCMP(p, "sbr", 3) == 0) {
- p += 3;
- bri_sbr = true;
- } else if (STRNCMP(p, "list:", 5) == 0) {
- p += 5;
- bri_list = (int)getdigits(&p, false, 0);
- }
- if (*p != ',' && *p != NUL) {
- return false;
- }
- if (*p == ',') {
- p++;
- }
- }
-
- wp->w_briopt_shift = bri_shift;
- wp->w_briopt_min = bri_min;
- wp->w_briopt_sbr = bri_sbr;
- wp->w_briopt_list = bri_list;
-
- return true;
+ return vim_strchr(p_bs, what) != NULL;
}
/// Get the local or global value of 'backupcopy'.
@@ -7940,19 +5369,19 @@ char_u *get_showbreak_value(win_T *const win)
FUNC_ATTR_WARN_UNUSED_RESULT
{
if (win->w_p_sbr == NULL || *win->w_p_sbr == NUL) {
- return p_sbr;
+ return (char_u *)p_sbr;
}
if (STRCMP(win->w_p_sbr, "NONE") == 0) {
- return empty_option;
+ return (char_u *)empty_option;
}
- return win->w_p_sbr;
+ return (char_u *)win->w_p_sbr;
}
/// Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
int get_fileformat(const buf_T *buf)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_NONNULL_ALL
{
- int c = *buf->b_p_ff;
+ int c = (unsigned char)(*buf->b_p_ff);
if (buf->b_p_bin || c == 'u') {
return EOL_UNIX;
@@ -7979,7 +5408,7 @@ int get_fileformat_force(const buf_T *buf, const exarg_T *eap)
? (eap->force_bin == FORCE_BIN) : buf->b_p_bin) {
return EOL_UNIX;
}
- c = *buf->b_p_ff;
+ c = (unsigned char)(*buf->b_p_ff);
}
if (c == 'u') {
return EOL_UNIX;
@@ -8036,7 +5465,7 @@ void set_fileformat(int eol_style, int opt_flags)
}
/// Skip to next part of an option argument: skip space and comma
-char_u *skip_to_option_part(const char_u *p)
+char *skip_to_option_part(const char *p)
{
if (*p == ',') {
p++;
@@ -8044,7 +5473,7 @@ char_u *skip_to_option_part(const char_u *p)
while (*p == ' ') {
p++;
}
- return (char_u *)p;
+ return (char *)p;
}
/// Isolate one part of a string option separated by `sep_chars`.
@@ -8079,7 +5508,7 @@ size_t copy_option_part(char **option, char *buf, size_t maxlen, char *sep_chars
if (*p != NUL && *p != ',') { // skip non-standard separator
p++;
}
- p = (char *)skip_to_option_part((char_u *)p); // p points to next file name
+ p = skip_to_option_part(p); // p points to next file name
*option = p;
return len;