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.c218
1 files changed, 114 insertions, 104 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 50c172b580..11f3df7cfa 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1068,6 +1068,10 @@ void set_helplang_default(const char *lang)
if (STRNICMP(p_hlg, "zh_", 3) == 0 && STRLEN(p_hlg) >= 5) {
p_hlg[0] = (char_u)TOLOWER_ASC(p_hlg[3]);
p_hlg[1] = (char_u)TOLOWER_ASC(p_hlg[4]);
+ } else if (STRLEN(p_hlg) >= 1 && *p_hlg == 'C') {
+ // any C like setting, such as C.UTF-8, becomes "en"
+ p_hlg[0] = 'e';
+ p_hlg[1] = 'n';
}
p_hlg[2] = NUL;
options[idx].flags |= P_ALLOCED;
@@ -1434,7 +1438,7 @@ do_set (
|| (long *)varp == &p_wcm)
&& (*arg == '<'
|| *arg == '^'
- || ((!arg[1] || ascii_iswhite(arg[1]))
+ || (*arg != NUL && (!arg[1] || ascii_iswhite(arg[1]))
&& !ascii_isdigit(*arg)))) {
value = string_to_key(arg);
if (value == 0 && (long *)varp != &p_wcm) {
@@ -1769,14 +1773,13 @@ do_set (
// Set the new value.
*(char_u **)(varp) = newval;
- if (!starting && origval != NULL && newval != NULL) {
- // origval may be freed by
- // did_set_string_option(), make a copy.
- saved_origval = xstrdup((char *)origval);
- // newval (and varp) may become invalid if the
- // buffer is closed by autocommands.
- saved_newval = xstrdup((char *)newval);
- }
+ // origval may be freed by
+ // did_set_string_option(), make a copy.
+ saved_origval = (origval != NULL) ? xstrdup((char *)origval) : 0;
+
+ // newval (and varp) may become invalid if the
+ // buffer is closed by autocommands.
+ saved_newval = (newval != NULL) ? xstrdup((char *)newval) : 0;
// Handle side effects, and set the global value for
// ":set" on local options. Note: when setting 'syntax'
@@ -1786,8 +1789,14 @@ do_set (
new_value_alloced, oldval, errbuf, opt_flags);
if (errmsg == NULL) {
- trigger_optionsset_string(opt_idx, opt_flags, saved_origval,
- saved_newval);
+ if (!starting) {
+ trigger_optionsset_string(opt_idx, opt_flags, saved_origval,
+ 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_origval);
xfree(saved_newval);
@@ -2378,8 +2387,8 @@ static char *set_string_option(const int opt_idx, const char *const value,
char *const oldval = *varp;
*varp = s;
- char *const saved_oldval = (starting ? NULL : xstrdup(oldval));
- char *const saved_newval = (starting ? NULL : xstrdup(s));
+ char *const saved_oldval = xstrdup(oldval);
+ char *const saved_newval = xstrdup(s);
char *const r = (char *)did_set_string_option(
opt_idx, (char_u **)varp, (int)true, (char_u *)oldval, NULL, opt_flags);
@@ -2389,8 +2398,13 @@ static char *set_string_option(const int opt_idx, const char *const value,
// call autocommand after handling side effects
if (r == NULL) {
- trigger_optionsset_string(opt_idx, opt_flags,
- saved_oldval, saved_newval);
+ if (!starting) {
+ trigger_optionsset_string(opt_idx, opt_flags, saved_oldval, 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_newval);
@@ -2434,7 +2448,7 @@ did_set_string_option (
int did_chartab = FALSE;
char_u **gvarp;
bool free_oldval = (options[opt_idx].flags & P_ALLOCED);
- int ft_changed = false;
+ bool value_changed = false;
/* Get the global option to compare with, otherwise we would have to check
* two values for all local options. */
@@ -2703,7 +2717,7 @@ did_set_string_option (
if (*p != NUL)
x2 = *p++;
if (*p != NUL) {
- x3 = mb_ptr2char(p);
+ x3 = utf_ptr2char(p);
p += mb_ptr2len(p);
}
if (x2 != ':' || x3 == -1 || (*p != NUL && *p != ',')) {
@@ -3155,11 +3169,13 @@ did_set_string_option (
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
} else {
- ft_changed = STRCMP(oldval, *varp) != 0;
+ value_changed = STRCMP(oldval, *varp) != 0;
}
} else if (gvarp == &p_syn) {
if (!valid_filetype(*varp)) {
errmsg = e_invarg;
+ } else {
+ value_changed = STRCMP(oldval, *varp) != 0;
}
} else if (varp == &curwin->w_p_winhl) {
if (!parse_winhl_opt(curwin)) {
@@ -3235,14 +3251,28 @@ did_set_string_option (
*/
/* When 'syntax' is set, load the syntax of that name */
if (varp == &(curbuf->b_p_syn)) {
- apply_autocmds(EVENT_SYNTAX, curbuf->b_p_syn,
- curbuf->b_fname, TRUE, curbuf);
+ 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, curbuf->b_p_syn, curbuf->b_fname,
+ value_changed || syn_recursive == 1, curbuf);
+ syn_recursive--;
} else if (varp == &(curbuf->b_p_ft)) {
// 'filetype' is set, trigger the FileType autocommand
- if (!(opt_flags & OPT_MODELINE) || ft_changed) {
+ // 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;
+
+ ft_recursive++;
did_filetype = true;
- apply_autocmds(EVENT_FILETYPE, curbuf->b_p_ft,
- curbuf->b_fname, true, curbuf);
+ // Only pass true for "force" when the value changed or not
+ // used recursively, to avoid endless recurrence.
+ apply_autocmds(EVENT_FILETYPE, 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;
@@ -3705,6 +3735,9 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
} else if ((int *)varp == &p_lnr) {
// 'langnoremap' -> !'langremap'
p_lrm = !p_lnr;
+ } else if ((int *)varp == &curwin->w_p_cul && !value && old_value) {
+ // 'cursorline'
+ reset_cursorline();
// 'undofile'
} else if ((int *)varp == &curbuf->b_p_udf || (int *)varp == &p_udf) {
// Only take action when the option was set. When reset we do not
@@ -3961,8 +3994,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
/* Enable Arabic shaping (major part of what Arabic requires) */
if (!p_arshape) {
- p_arshape = TRUE;
- redraw_later_clear();
+ p_arshape = true;
+ redraw_all_later(NOT_VALID);
}
}
@@ -4019,7 +4052,8 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
options[opt_idx].flags |= P_WAS_SET;
- if (!starting) {
+ // Don't do this while starting up or recursively.
+ if (!starting && *get_vim_var_str(VV_OPTION_TYPE) == NUL) {
char buf_old[2];
char buf_new[2];
char buf_type[7];
@@ -4036,10 +4070,11 @@ static char *set_bool_option(const int opt_idx, char_u *const varp,
(char_u *) options[opt_idx].fullname,
NULL, false, NULL);
reset_v_option_vars();
- if (options[opt_idx].flags & P_UI_OPTION) {
- ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
- BOOLEAN_OBJ(value));
- }
+ }
+
+ if (options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ BOOLEAN_OBJ(value));
}
comp_col(); /* in case 'ruler' or 'showcmd' changed */
@@ -4393,7 +4428,8 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
options[opt_idx].flags |= P_WAS_SET;
- if (!starting && errmsg == NULL) {
+ // Don't do this while starting up, failure or recursively.
+ if (!starting && errmsg == NULL && *get_vim_var_str(VV_OPTION_TYPE) == NUL) {
char buf_old[NUMBUFLEN];
char buf_new[NUMBUFLEN];
char buf_type[7];
@@ -4408,10 +4444,11 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
(char_u *) options[opt_idx].fullname,
NULL, false, NULL);
reset_v_option_vars();
- if (options[opt_idx].flags & P_UI_OPTION) {
- ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
- INTEGER_OBJ(value));
- }
+ }
+
+ if (errmsg == NULL && options[opt_idx].flags & P_UI_OPTION) {
+ ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
+ INTEGER_OBJ(value));
}
comp_col(); /* in case 'columns' or 'ls' changed */
@@ -4426,7 +4463,10 @@ static char *set_num_option(int opt_idx, char_u *varp, long value,
static void trigger_optionsset_string(int opt_idx, int opt_flags,
char *oldval, char *newval)
{
- if (oldval != NULL && newval != NULL) {
+ // 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",
@@ -4437,10 +4477,6 @@ static void trigger_optionsset_string(int opt_idx, int opt_flags,
apply_autocmds(EVENT_OPTIONSET,
(char_u *)options[opt_idx].fullname, NULL, false, NULL);
reset_v_option_vars();
- if (options[opt_idx].flags & P_UI_OPTION) {
- ui_call_option_set(cstr_as_string(options[opt_idx].fullname),
- STRING_OBJ(cstr_as_string(newval)));
- }
}
}
@@ -6406,22 +6442,25 @@ static void langmap_set(void)
++p;
break;
}
- if (p[0] == '\\' && p[1] != NUL)
- ++p;
- from = (*mb_ptr2char)(p);
+ if (p[0] == '\\' && p[1] != NUL) {
+ p++;
+ }
+ from = utf_ptr2char(p);
to = NUL;
if (p2 == NULL) {
MB_PTR_ADV(p);
if (p[0] != ',') {
- if (p[0] == '\\')
- ++p;
- to = (*mb_ptr2char)(p);
+ if (p[0] == '\\') {
+ p++;
+ }
+ to = utf_ptr2char(p);
}
} else {
if (p2[0] != ',') {
- if (p2[0] == '\\')
- ++p2;
- to = (*mb_ptr2char)(p2);
+ if (p2[0] == '\\') {
+ p2++;
+ }
+ to = utf_ptr2char(p2);
}
}
if (to == NUL) {
@@ -6846,66 +6885,37 @@ int get_sts_value(void)
*/
void find_mps_values(int *initc, int *findc, int *backwards, int switchit)
{
- char_u *ptr;
+ char_u *ptr = curbuf->b_p_mps;
- ptr = curbuf->b_p_mps;
while (*ptr != NUL) {
- if (has_mbyte) {
- char_u *prev;
-
- if (mb_ptr2char(ptr) == *initc) {
- if (switchit) {
- *findc = *initc;
- *initc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
- *backwards = TRUE;
- } else {
- *findc = mb_ptr2char(ptr + mb_ptr2len(ptr) + 1);
- *backwards = FALSE;
- }
- return;
- }
- prev = ptr;
- ptr += mb_ptr2len(ptr) + 1;
- if (mb_ptr2char(ptr) == *initc) {
- if (switchit) {
- *findc = *initc;
- *initc = mb_ptr2char(prev);
- *backwards = FALSE;
- } else {
- *findc = mb_ptr2char(prev);
- *backwards = TRUE;
- }
- return;
- }
- ptr += mb_ptr2len(ptr);
- } else {
- if (*ptr == *initc) {
- if (switchit) {
- *backwards = TRUE;
- *findc = *initc;
- *initc = ptr[2];
- } else {
- *backwards = FALSE;
- *findc = ptr[2];
- }
- return;
+ if (utf_ptr2char(ptr) == *initc) {
+ if (switchit) {
+ *findc = *initc;
+ *initc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1);
+ *backwards = true;
+ } else {
+ *findc = utf_ptr2char(ptr + utfc_ptr2len(ptr) + 1);
+ *backwards = false;
}
- ptr += 2;
- if (*ptr == *initc) {
- if (switchit) {
- *backwards = FALSE;
- *findc = *initc;
- *initc = ptr[-2];
- } else {
- *backwards = TRUE;
- *findc = ptr[-2];
- }
- return;
+ return;
+ }
+ char_u *prev = ptr;
+ ptr += utfc_ptr2len(ptr) + 1;
+ if (utf_ptr2char(ptr) == *initc) {
+ if (switchit) {
+ *findc = *initc;
+ *initc = utf_ptr2char(prev);
+ *backwards = false;
+ } else {
+ *findc = utf_ptr2char(prev);
+ *backwards = true;
}
- ++ptr;
+ return;
+ }
+ ptr += utfc_ptr2len(ptr);
+ if (*ptr == ',') {
+ ptr++;
}
- if (*ptr == ',')
- ++ptr;
}
}