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.c612
1 files changed, 435 insertions, 177 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 45ebb4fa4c..a4e7da770e 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -213,12 +213,12 @@ typedef struct vimoption {
#define P_VI_DEF 0x400U /* Use Vi default for Vim */
#define P_VIM 0x800U /* Vim option */
-/* when option changed, what to display: */
-#define P_RSTAT 0x1000U /* redraw status lines */
-#define P_RWIN 0x2000U /* redraw current window */
-#define P_RBUF 0x4000U /* redraw current buffer */
-#define P_RALL 0x6000U /* redraw all windows */
-#define P_RCLR 0x7000U /* clear and redraw all */
+// 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
@@ -236,6 +236,9 @@ typedef struct vimoption {
#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 HIGHLIGHT_INIT \
"8:SpecialKey,~:EndOfBuffer,z:TermCursor,Z:TermCursorNC,@:NonText," \
@@ -245,7 +248,7 @@ typedef struct vimoption {
"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"
+ "!:CursorColumn,.:CursorLine,o:ColorColumn,q:QuickFixLine"
/*
* options[] is initialized here.
@@ -287,6 +290,8 @@ static char *(p_fdm_values[]) = { "manual", "expr", "marker", "indent",
static char *(p_fcl_values[]) = { "all", NULL };
static char *(p_cot_values[]) = { "menu", "menuone", "longest", "preview",
"noinsert", "noselect", NULL };
+static char *(p_icm_values[]) = { "nosplit", "split", NULL };
+static char *(p_scl_values[]) = { "yes", "no", "auto", NULL };
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "option.c.generated.h"
@@ -520,6 +525,8 @@ static void set_runtimepath_default(void)
#undef SITE_SIZE
#undef AFTER_SIZE
set_string_default("runtimepath", rtp, true);
+ // Make a copy of 'rtp' for 'packpath'
+ set_string_default("packpath", rtp, false);
xfree(data_dirs);
xfree(config_dirs);
xfree(data_home);
@@ -676,15 +683,18 @@ void set_init_1(void)
#endif
false);
- char *backupdir = stdpaths_user_data_subpath("backup", 0);
+ char *backupdir = stdpaths_user_data_subpath("backup", 0, true);
const size_t backupdir_len = strlen(backupdir);
backupdir = xrealloc(backupdir, backupdir_len + 3);
memmove(backupdir + 2, backupdir, backupdir_len + 1);
memmove(backupdir, ".,", 2);
- set_string_default("viewdir", stdpaths_user_data_subpath("view", 0), true);
+ set_string_default("viewdir", stdpaths_user_data_subpath("view", 0, true),
+ true);
set_string_default("backupdir", backupdir, true);
- set_string_default("directory", stdpaths_user_data_subpath("swap", 2), true);
- set_string_default("undodir", stdpaths_user_data_subpath("undo", 0), true);
+ set_string_default("directory", stdpaths_user_data_subpath("swap", 2, true),
+ true);
+ set_string_default("undodir", stdpaths_user_data_subpath("undo", 0, true),
+ true);
// Set default for &runtimepath. All necessary expansions are performed in
// this function.
set_runtimepath_default();
@@ -726,6 +736,9 @@ void set_init_1(void)
* default.
*/
for (opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
+ if (options[opt_idx].flags & P_NO_DEF_EXP) {
+ continue;
+ }
char *p;
if ((options[opt_idx].flags & P_GETTEXT)
&& options[opt_idx].var != NULL) {
@@ -771,14 +784,11 @@ void set_init_1(void)
}
fenc_default = p;
- // Initialize multibyte (utf-8) handling
- mb_init();
-
- // Don't change &encoding when resetting to defaults with ":set all&".
- opt_idx = findoption((char_u *)"encoding");
- if (opt_idx >= 0) {
- options[opt_idx].flags |= P_NODEFAULT;
- }
+#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);
+#endif
/* Set the default for 'helplang'. */
set_helplang_default(get_mess_lang());
@@ -1023,6 +1033,15 @@ void set_init_3(void)
xfree(p);
}
+ if (bufempty()) {
+ int idx_ffs = findoption((char_u *)"ffs");
+
+ // Apply the first entry of 'fileformats' to the initial buffer.
+ if (idx_ffs >= 0 && (options[idx_ffs].flags & P_WAS_SET)) {
+ set_fileformat(default_fileformat(), OPT_LOCAL);
+ }
+ }
+
set_title_defaults();
}
@@ -1473,16 +1492,19 @@ do_set (
* default value was already expanded, only
* required when an environment variable was set
* later */
- if (newval == NULL)
+ new_value_alloced = true;
+ if (newval == NULL) {
newval = empty_option;
- else {
+ } else if (!(options[opt_idx].flags | P_NO_DEF_EXP)) {
s = option_expand(opt_idx, newval);
- if (s == NULL)
+ if (s == NULL) {
s = newval;
+ }
newval = vim_strsave(s);
+ } else {
+ newval = (char_u *)xstrdup((char *)newval);
}
- new_value_alloced = TRUE;
- } else if (nextchar == '<') { /* set to global val */
+ } else if (nextchar == '<') { // set to global val
newval = vim_strsave(*(char_u **)get_varp_scope(
&(options[opt_idx]), OPT_GLOBAL));
new_value_alloced = TRUE;
@@ -1708,13 +1730,25 @@ do_set (
}
if (flags & P_FLAGLIST) {
- /* Remove flags that appear twice. */
- for (s = newval; *s; ++s)
- if ((!(flags & P_COMMA) || *s != ',')
- && vim_strchr(s + 1, *s) != NULL) {
- STRMOVE(s, s + 1);
- --s;
+ // Remove flags that appear twice.
+ for (s = newval; *s; s++) {
+ // if options have P_FLAGLIST and P_ONECOMMA such as
+ // 'whichwrap'
+ if (flags & P_ONECOMMA) {
+ if (*s != ',' && *(s + 1) == ','
+ && vim_strchr(s + 2, *s) != NULL) {
+ // Remove the duplicated value and the next comma.
+ STRMOVE(s, s + 2);
+ s -= 2;
+ }
+ } else {
+ if ((!(flags & P_COMMA) || *s != ',')
+ && vim_strchr(s + 1, *s) != NULL) {
+ STRMOVE(s, s + 1);
+ s--;
+ }
}
+ }
}
if (save_arg != NULL) /* number for 'whichwrap' */
@@ -2020,13 +2054,15 @@ static char_u *option_expand(int opt_idx, char_u *val)
if (!(options[opt_idx].flags & P_EXPAND) || options[opt_idx].var == NULL)
return NULL;
- /* If val is longer than MAXPATHL no meaningful expansion can be done,
- * expand_env() would truncate the string. */
- if (val != NULL && STRLEN(val) > MAXPATHL)
- return NULL;
-
- if (val == NULL)
+ if (val == NULL) {
val = *(char_u **)options[opt_idx].var;
+ }
+
+ // If val is longer than MAXPATHL no meaningful expansion can be done,
+ // expand_env() would truncate the string.
+ if (val == NULL || STRLEN(val) > MAXPATHL) {
+ return NULL;
+ }
/*
* Expanding this with NameBuff, expand_env() must not be passed IObuff.
@@ -2129,6 +2165,7 @@ void check_buf_options(buf_T *buf)
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);
@@ -2313,50 +2350,46 @@ set_string_option_global (
}
}
-/*
- * Set a string option to a new value, and handle the effects.
- *
- * Returns NULL on success or error message on error.
- */
-static char_u *
-set_string_option (
- int opt_idx,
- char_u *value,
- int opt_flags /* OPT_LOCAL and/or OPT_GLOBAL */
-)
+/// 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
{
- char_u *s;
- char_u **varp;
- char_u *oldval;
- char *saved_oldval = NULL;
- char_u *r = NULL;
-
- if (options[opt_idx].var == NULL) /* don't set hidden option */
+ if (options[opt_idx].var == NULL) { // don't set hidden option
return NULL;
+ }
- s = vim_strsave(value);
- varp = (char_u **)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);
- oldval = *varp;
+ 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;
*varp = s;
- if (!starting) {
- saved_oldval = xstrdup((char *) oldval);
- }
+ char *const saved_oldval = (starting ? NULL : xstrdup(oldval));
- if ((r = did_set_string_option(opt_idx, varp, (int)true, oldval, NULL,
- opt_flags)) == NULL)
- did_set_option(opt_idx, opt_flags, TRUE);
+ char *const r = (char *)did_set_string_option(
+ opt_idx, (char_u **)varp, (int)true, (char_u *)oldval, NULL, opt_flags);
+ if (r == NULL) {
+ did_set_option(opt_idx, opt_flags, true);
+ }
// call autocommand after handling side effects
if (saved_oldval != NULL) {
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_NEW, (char *) (*varp), -1);
+ set_vim_var_string(VV_OPTION_NEW, (char *)(*varp), -1);
set_vim_var_string(VV_OPTION_OLD, saved_oldval, -1);
set_vim_var_string(VV_OPTION_TYPE, buf_type, -1);
apply_autocmds(EVENT_OPTIONSET,
@@ -2369,6 +2402,18 @@ set_string_option (
return r;
}
+/// Return true if "val" is a valid 'filetype' name.
+/// Also used for 'syntax' and 'keymap'.
+static bool valid_filetype(char_u *val)
+{
+ for (char_u *s = val; *s != NUL; s++) {
+ if (!ASCII_ISALNUM(*s) && vim_strchr((char_u *)".-_", *s) == NULL) {
+ return false;
+ }
+ }
+ return true;
+}
+
/*
* Handle string options that need some action to perform when changed.
* Returns NULL for success, or an error message for an error.
@@ -2442,16 +2487,13 @@ did_set_string_option (
else if (varp == &curwin->w_p_briopt) {
if (briopt_check(curwin) == FAIL)
errmsg = e_invarg;
- }
- /*
- * 'isident', 'iskeyword', 'isprint or 'isfname' option: refill chartab[]
- * If the new option is invalid, use old value. 'lisp' option: refill
- * chartab[] for '-' char
- */
- else if ( varp == &p_isi
+ } 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 */
@@ -2510,15 +2552,15 @@ did_set_string_option (
else if (varp == &p_sbo) {
if (check_opt_strings(p_sbo, p_scbopt_values, TRUE) != OK)
errmsg = e_invarg;
- }
- /* 'ambiwidth' */
- else if (varp == &p_ambw) {
- if (check_opt_strings(p_ambw, p_ambw_values, FALSE) != OK)
+ } 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 if (set_chars_option(&p_lcs) != NULL)
+ } else if (set_chars_option(&p_lcs) != NULL) {
errmsg = (char_u *)_("E834: Conflicts with value of 'listchars'");
- else if (set_chars_option(&p_fcs) != NULL)
+ } else if (set_chars_option(&p_fcs) != NULL) {
errmsg = (char_u *)_("E835: Conflicts with value of 'fillchars'");
+ }
}
/* 'background' */
else if (varp == &p_bg) {
@@ -2563,19 +2605,17 @@ did_set_string_option (
errmsg = e_invarg;
/* 'encoding' and 'fileencoding' */
} else if (varp == &p_enc || gvarp == &p_fenc) {
- if (varp == &p_enc && did_source_startup_scripts) {
- errmsg = e_afterinit;
- } else if (gvarp == &p_fenc) {
- if (!MODIFIABLE(curbuf) && opt_flags != OPT_GLOBAL)
+ if (gvarp == &p_fenc) {
+ if (!MODIFIABLE(curbuf) && opt_flags != OPT_GLOBAL) {
errmsg = e_modifiable;
- else if (vim_strchr(*varp, ',') != NULL)
- /* No comma allowed in 'fileencoding'; catches confusing it
- * with 'fileencodings'. */
+ } else if (vim_strchr(*varp, ',') != NULL) {
+ // No comma allowed in 'fileencoding'; catches confusing it
+ // with 'fileencodings'.
errmsg = e_invarg;
- else {
- /* May show a "+" in the title now. */
+ } else {
+ // May show a "+" in the title now.
redraw_titles();
- /* Add 'fileencoding' to the swap file. */
+ // Add 'fileencoding' to the swap file.
ml_setflags(curbuf);
}
}
@@ -2586,25 +2626,24 @@ did_set_string_option (
xfree(*varp);
*varp = p;
if (varp == &p_enc) {
- errmsg = mb_init();
- redraw_titles();
+ // only encoding=utf-8 allowed
+ if (STRCMP(p_enc, "utf-8") != 0) {
+ errmsg = e_invarg;
+ }
}
}
-
- if (errmsg == NULL) {
- /* When 'keymap' is used and 'encoding' changes, reload the keymap
- * (with another encoding). */
- if (varp == &p_enc && *curbuf->b_p_keymap != NUL)
- (void)keymap_init();
- }
} 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) {
- /* load or unload key mapping tables */
- errmsg = keymap_init();
+ if (!valid_filetype(*varp)) {
+ errmsg = e_invarg;
+ } else {
+ // load or unload key mapping tables
+ errmsg = keymap_init();
+ }
if (errmsg == NULL) {
if (*curbuf->b_p_keymap != NUL) {
@@ -2734,6 +2773,10 @@ did_set_string_option (
? ((shada_idx = findoption((char_u *) "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 fuction.
+ free_oldval = (options[opt_idx].flags & P_ALLOCED);
for (s = p_shada; *s; ) {
/* Check it's a valid character */
if (vim_strchr((char_u *)"!\"%'/:<@cfhnrs", *s) == NULL) {
@@ -2967,6 +3010,11 @@ did_set_string_option (
} else {
completeopt_was_set();
}
+ } else if (varp == &curwin->w_p_scl) {
+ // 'signcolumn'
+ if (check_opt_strings(*varp, p_scl_values, false) != OK) {
+ errmsg = e_invarg;
+ }
}
/* 'pastetoggle': translate key codes like in a mapping */
else if (varp == &p_pt) {
@@ -3093,9 +3141,21 @@ did_set_string_option (
else if (gvarp == &p_cino) {
/* TODO: recognize errors */
parse_cino(curbuf);
- }
- /* Options that are a list of flags. */
- else {
+ // 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 if (gvarp == &p_syn) {
+ if (!valid_filetype(*varp)) {
+ errmsg = e_invarg;
+ }
+ } else {
+ // Options that are a list of flags.
p = NULL;
if (varp == &p_ww)
p = (char_u *)WW_ALL;
@@ -3190,8 +3250,9 @@ did_set_string_option (
for (p = q; *p != NUL; ++p)
if (vim_strchr((char_u *)"_.,", *p) != NULL)
break;
- vim_snprintf((char *)fname, 200, "spell/%.*s.vim", (int)(p - q), q);
- source_runtime(fname, TRUE);
+ vim_snprintf((char *)fname, sizeof(fname), "spell/%.*s.vim",
+ (int)(p - q), q);
+ source_runtime(fname, DIP_ALL);
}
}
@@ -3402,9 +3463,10 @@ char_u *check_stl_option(char_u *s)
if (!*s)
break;
s++;
- if (*s != '%' && *s != ')')
- ++itemcnt;
- if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_MIDDLEMARK) {
+ if (*s != '%' && *s != ')') {
+ itemcnt++;
+ }
+ if (*s == '%' || *s == STL_TRUNCMARK || *s == STL_SEPARATE) {
s++;
continue;
}
@@ -3648,14 +3710,16 @@ set_bool_option (
/* when 'insertmode' is set from an autocommand need to do work here */
else if ((int *)varp == &p_im) {
if (p_im) {
- if ((State & INSERT) == 0)
- need_start_insertmode = TRUE;
- stop_insert_mode = FALSE;
- } else {
- need_start_insertmode = FALSE;
- stop_insert_mode = TRUE;
- if (restart_edit != 0 && mode_displayed)
- clear_cmdline = TRUE; /* remove "(insert)" */
+ if ((State & INSERT) == 0) {
+ need_start_insertmode = true;
+ }
+ stop_insert_mode = false;
+ } else if (old_value) { // only reset if it was set previously
+ need_start_insertmode = false;
+ stop_insert_mode = true;
+ if (restart_edit != 0 && mode_displayed) {
+ clear_cmdline = true; // remove "(insert)"
+ }
restart_edit = 0;
}
}
@@ -3685,23 +3749,19 @@ set_bool_option (
}
}
}
- }
-
- /*
- * When 'lisp' option changes include/exclude '-' in
- * keyword characters.
- */
- else if (varp == (char_u *)&(curbuf->b_p_lisp)) {
- (void)buf_init_chartab(curbuf, FALSE); /* ignore errors */
- }
- /* when 'title' changed, may need to change the title; same for 'icon' */
- else if ((int *)varp == &p_title) {
- did_set_title(FALSE);
+ } else if (varp == (char_u *)&(curbuf->b_p_lisp)) {
+ // When 'lisp' option changes include/exclude '-' in
+ // keyword characters.
+ (void)buf_init_chartab(curbuf, false); // ignore errors
+ } else if ((int *)varp == &p_title) {
+ // when 'title' changed, may need to change the title; same for 'icon'
+ did_set_title(false);
} else if ((int *)varp == &p_icon) {
- did_set_title(TRUE);
- } else if ((bool *)varp == &curbuf->b_changed) {
- if (!value)
- save_file_ff(curbuf); /* Buffer is unchanged */
+ did_set_title(true);
+ } else if ((int *)varp == &curbuf->b_changed) {
+ if (!value) {
+ save_file_ff(curbuf); // Buffer is unchanged
+ }
redraw_titles();
modified_was_set = value;
}
@@ -3729,11 +3789,12 @@ set_bool_option (
else if ((int *)varp == &curwin->w_p_wrap) {
if (curwin->w_p_wrap)
curwin->w_leftcol = 0;
- } else if ((bool *)varp == &p_ea) {
- if (p_ea && !old_value)
+ } else if ((int *)varp == &p_ea) {
+ if (p_ea && !old_value) {
win_equal(curwin, false, 0);
- } else if ((bool *)varp == &p_acd) {
- /* Change directories when the 'acd' option is set now. */
+ }
+ } else if ((int *)varp == &p_acd) {
+ // Change directories when the 'acd' option is set now.
do_autochdir();
}
/* 'diff' */
@@ -4029,15 +4090,16 @@ set_num_option (
errmsg = e_invarg;
curwin->w_p_fdc = 12;
}
- }
- /* 'shiftwidth' or 'tabstop' */
- else if (pp == &curbuf->b_p_sw || pp == &curbuf->b_p_ts) {
- if (foldmethodIsIndent(curwin))
+ // 'shiftwidth' or 'tabstop'
+ } else if (pp == &curbuf->b_p_sw || pp == (long *)&curbuf->b_p_ts) {
+ if (foldmethodIsIndent(curwin)) {
foldUpdateAll(curwin);
- /* When 'shiftwidth' changes, or it's zero and 'tabstop' changes:
- * parse 'cinoptions'. */
- if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0)
+ }
+ // When 'shiftwidth' changes, or it's zero and 'tabstop' changes:
+ // parse 'cinoptions'.
+ if (pp == &curbuf->b_p_sw || curbuf->b_p_sw == 0) {
parse_cino(curbuf);
+ }
}
/* 'maxcombine' */
else if (pp == &p_mco) {
@@ -4297,17 +4359,24 @@ static void check_redraw(uint32_t flags)
bool doclear = (flags & P_RCLR) == P_RCLR;
bool all = ((flags & P_RALL) == P_RALL || doclear);
- if ((flags & P_RSTAT) || all) /* mark all status lines dirty */
+ if ((flags & P_RSTAT) || all) { // mark all status lines dirty
status_redraw_all();
+ }
- if ((flags & P_RBUF) || (flags & P_RWIN) || all)
+ if ((flags & P_RBUF) || (flags & P_RWIN) || all) {
changed_window_setting();
- if (flags & P_RBUF)
+ }
+ if (flags & P_RBUF) {
redraw_curbuf_later(NOT_VALID);
- if (doclear)
+ }
+ if (flags & P_RWINONLY) {
+ redraw_later(NOT_VALID);
+ }
+ if (doclear) {
redraw_all_later(CLEAR);
- else if (all)
+ } else if (all) {
redraw_all_later(NOT_VALID);
+ }
}
/// Find index for named option
@@ -4405,6 +4474,7 @@ bool get_tty_option(char *name, char **value)
if (is_tty_option(name)) {
if (value) {
+ // XXX: All other t_* options were removed in 3baba1e7.
*value = xstrdup("");
}
return true;
@@ -4490,10 +4560,11 @@ get_option_value (
else {
/* Special case: 'modified' is b_changed, but we also want to consider
* it set when 'ff' or 'fenc' changed. */
- if ((bool *)varp == &curbuf->b_changed)
+ if ((int *)varp == &curbuf->b_changed) {
*numval = curbufIsChanged();
- else
+ } else {
*numval = *(int *)varp;
+ }
}
return 1;
}
@@ -4652,26 +4723,28 @@ set_option_value (
EMSG(_(e_sandbox));
return NULL;
}
- if (flags & P_STRING)
- return set_string_option(opt_idx, string, opt_flags);
- else {
+ if (flags & P_STRING) {
+ const char *s = (const char *)string;
+ if (s == NULL) {
+ s = "";
+ }
+ return (char_u *)set_string_option(opt_idx, s, opt_flags);
+ } else {
varp = get_varp_scope(&(options[opt_idx]), opt_flags);
if (varp != NULL) { /* hidden option is not changed */
if (number == 0 && string != NULL) {
int idx;
- /* Either we are given a string or we are setting option
- * to zero. */
- for (idx = 0; string[idx] == '0'; ++idx)
- ;
+ // Either we are given a string or we are setting option
+ // to zero.
+ for (idx = 0; string[idx] == '0'; idx++) {}
if (string[idx] != NUL || idx == 0) {
- /* There's another character after zeros or the string
- * is empty. In both cases, we are trying to set a
- * num option using a string. */
+ // There's another character after zeros or the string
+ // is empty. In both cases, we are trying to set a
+ // num option using a string.
EMSG3(_("E521: Number required: &%s = '%s'"),
- name, string);
- return NULL; /* do nothing as we hit an error */
-
+ name, string);
+ return NULL; // do nothing as we hit an error
}
}
if (flags & P_NUM)
@@ -4724,7 +4797,6 @@ static int find_key_option(const char_u *arg)
return find_key_option_len(arg, STRLEN(arg));
}
-
/*
* if 'all' == 0: show changed options
* if 'all' == 1: show all normal options
@@ -4859,14 +4931,15 @@ showoneopt (
varp = get_varp_scope(p, opt_flags);
- /* for 'modified' we also need to check if 'ff' or 'fenc' changed. */
- if ((p->flags & P_BOOL) && ((bool *)varp == &curbuf->b_changed
- ? !curbufIsChanged() : !*(bool *)varp))
+ // for 'modified' we also need to check if 'ff' or 'fenc' changed.
+ if ((p->flags & P_BOOL) && ((int *)varp == &curbuf->b_changed
+ ? !curbufIsChanged() : !*(int *)varp)) {
MSG_PUTS("no");
- else if ((p->flags & P_BOOL) && *(int *)varp < 0)
+ } else if ((p->flags & P_BOOL) && *(int *)varp < 0) {
MSG_PUTS("--");
- else
+ } else {
MSG_PUTS(" ");
+ }
MSG_PUTS(p->fullname);
if (!(p->flags & P_BOOL)) {
msg_putchar('=');
@@ -5369,6 +5442,7 @@ static char_u *get_varp(vimoption_T *p)
case PV_UDF: return (char_u *)&(curbuf->b_p_udf);
case PV_WM: return (char_u *)&(curbuf->b_p_wm);
case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
+ case PV_SCL: return (char_u *)&(curwin->w_p_scl);
default: EMSG(_("E356: get_varp ERROR"));
}
/* always return a valid pointer to avoid a crash! */
@@ -5446,7 +5520,8 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_fde = vim_strsave(from->wo_fde);
to->wo_fdt = vim_strsave(from->wo_fdt);
to->wo_fmr = vim_strsave(from->wo_fmr);
- check_winopt(to); /* don't want NULL pointers */
+ to->wo_scl = vim_strsave(from->wo_scl);
+ check_winopt(to); // don't want NULL pointers
}
/*
@@ -5469,6 +5544,7 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_fde);
check_string_option(&wop->wo_fdt);
check_string_option(&wop->wo_fmr);
+ check_string_option(&wop->wo_scl);
check_string_option(&wop->wo_rlc);
check_string_option(&wop->wo_stl);
check_string_option(&wop->wo_cc);
@@ -5487,6 +5563,7 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_fde);
clear_string_option(&wop->wo_fdt);
clear_string_option(&wop->wo_fmr);
+ clear_string_option(&wop->wo_scl);
clear_string_option(&wop->wo_rlc);
clear_string_option(&wop->wo_stl);
clear_string_option(&wop->wo_cc);
@@ -5606,6 +5683,7 @@ void buf_copy_options(buf_T *buf, int flags)
/* Don't copy 'syntax', it must be set */
buf->b_p_syn = empty_option;
buf->b_p_smc = p_smc;
+ buf->b_s.b_syn_isk = empty_option;
buf->b_s.b_p_spc = vim_strsave(p_spc);
(void)compile_cap_prog(&buf->b_s);
buf->b_s.b_p_spf = vim_strsave(p_spf);
@@ -5655,7 +5733,7 @@ void buf_copy_options(buf_T *buf, int flags)
buf->b_p_isk = save_p_isk;
else {
buf->b_p_isk = vim_strsave(p_isk);
- did_isk = TRUE;
+ did_isk = true;
buf->b_p_ts = p_ts;
buf->b_help = false;
if (buf->b_p_bt[0] == 'h')
@@ -5836,6 +5914,7 @@ set_context_in_set_cmd (
if (p == (char_u *)&p_bdir
|| p == (char_u *)&p_dir
|| p == (char_u *)&p_path
+ || p == (char_u *)&p_pp
|| p == (char_u *)&p_rtp
|| p == (char_u *)&p_cdpath
|| p == (char_u *)&p_vdir
@@ -6569,10 +6648,8 @@ int get_sw_value(buf_T *buf)
return (int)result;
}
-/*
- * Return the effective softtabstop value for the current buffer, using the
- * 'tabstop' value when 'softtabstop' is negative.
- */
+// Return the effective softtabstop value for the current buffer,
+// using the effective 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;
@@ -6698,3 +6775,184 @@ unsigned int get_bkc_value(buf_T *buf)
{
return buf->b_bkc_flags ? buf->b_bkc_flags : bkc_flags;
}
+
+/// Return the current end-of-line type: EOL_DOS, EOL_UNIX or EOL_MAC.
+int get_fileformat(buf_T *buf)
+{
+ int c = *buf->b_p_ff;
+
+ if (buf->b_p_bin || c == 'u') {
+ return EOL_UNIX;
+ }
+ if (c == 'm') {
+ return EOL_MAC;
+ }
+ return EOL_DOS;
+}
+
+/// Like get_fileformat(), but override 'fileformat' with "p" for "++opt=val"
+/// argument.
+///
+/// @param eap can be NULL!
+int get_fileformat_force(buf_T *buf, exarg_T *eap)
+{
+ int c;
+
+ if (eap != NULL && eap->force_ff != 0) {
+ c = eap->cmd[eap->force_ff];
+ } else {
+ if ((eap != NULL && eap->force_bin != 0)
+ ? (eap->force_bin == FORCE_BIN) : buf->b_p_bin) {
+ return EOL_UNIX;
+ }
+ c = *buf->b_p_ff;
+ }
+ if (c == 'u') {
+ return EOL_UNIX;
+ }
+ if (c == 'm') {
+ return EOL_MAC;
+ }
+ return EOL_DOS;
+}
+
+/// Return the default fileformat from 'fileformats'.
+int default_fileformat(void)
+{
+ switch (*p_ffs) {
+ case 'm': return EOL_MAC;
+ case 'd': return EOL_DOS;
+ }
+ return EOL_UNIX;
+}
+
+/// Set the current end-of-line type to EOL_UNIX, EOL_MAC, or EOL_DOS.
+///
+/// Sets 'fileformat'.
+///
+/// @param eol_style End-of-line style.
+/// @param opt_flags OPT_LOCAL and/or OPT_GLOBAL
+void set_fileformat(int eol_style, int opt_flags)
+{
+ char *p = NULL;
+
+ switch (eol_style) {
+ case EOL_UNIX:
+ p = FF_UNIX;
+ break;
+ case EOL_MAC:
+ p = FF_MAC;
+ break;
+ case EOL_DOS:
+ p = FF_DOS;
+ break;
+ }
+
+ // p is NULL if "eol_style" is EOL_UNKNOWN.
+ if (p != NULL) {
+ set_string_option_direct((char_u *)"ff",
+ -1,
+ (char_u *)p,
+ OPT_FREE | opt_flags,
+ 0);
+ }
+
+ // This may cause the buffer to become (un)modified.
+ check_status(curbuf);
+ redraw_tabline = true;
+ need_maketitle = true; // Set window title later.
+}
+
+/// Skip to next part of an option argument: Skip space and comma.
+char_u *skip_to_option_part(char_u *p)
+{
+ if (*p == ',') {
+ p++;
+ }
+ while (*p == ' ') {
+ p++;
+ }
+ return p;
+}
+
+/// Isolate one part of a string option separated by `sep_chars`.
+///
+/// @param[in,out] option advanced to the next part
+/// @param[in,out] buf copy of the isolated part
+/// @param[in] maxlen length of `buf`
+/// @param[in] sep_chars chars that separate the option parts
+///
+/// @return length of `*option`
+size_t copy_option_part(char_u **option, char_u *buf, size_t maxlen,
+ char *sep_chars)
+{
+ size_t len = 0;
+ char_u *p = *option;
+
+ // skip '.' at start of option part, for 'suffixes'
+ if (*p == '.') {
+ buf[len++] = *p++;
+ }
+ while (*p != NUL && vim_strchr((char_u *)sep_chars, *p) == NULL) {
+ // Skip backslash before a separator character and space.
+ if (p[0] == '\\' && vim_strchr((char_u *)sep_chars, p[1]) != NULL) {
+ p++;
+ }
+ if (len < maxlen - 1) {
+ buf[len++] = *p;
+ }
+ p++;
+ }
+ buf[len] = NUL;
+
+ if (*p != NUL && *p != ',') { // skip non-standard separator
+ p++;
+ }
+ p = skip_to_option_part(p); // p points to next file name
+
+ *option = p;
+ return len;
+}
+
+/// Return TRUE when 'shell' has "csh" in the tail.
+int csh_like_shell(void)
+{
+ return strstr((char *)path_tail(p_sh), "csh") != NULL;
+}
+
+/// Return true when window "wp" has a column to draw signs in.
+bool signcolumn_on(win_T *wp)
+{
+ if (*wp->w_p_scl == 'n') {
+ return false;
+ }
+ if (*wp->w_p_scl == 'y') {
+ return true;
+ }
+ return wp->w_buffer->b_signlist != NULL;
+}
+
+/// Get window or buffer local options.
+dict_T * get_winbuf_options(int bufopt)
+{
+ dict_T *d = dict_alloc();
+
+ for (int opt_idx = 0; options[opt_idx].fullname; opt_idx++) {
+ struct vimoption *opt = &options[opt_idx];
+
+ if ((bufopt && (opt->indir & PV_BUF))
+ || (!bufopt && (opt->indir & PV_WIN))) {
+ char_u *varp = get_varp(opt);
+
+ if (varp != NULL) {
+ if (opt->flags & P_STRING) {
+ dict_add_nr_str(d, opt->fullname, 0L, *(char_u **)varp);
+ } else {
+ dict_add_nr_str(d, opt->fullname, *varp, NULL);
+ }
+ }
+ }
+ }
+
+ return d;
+}