aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/nvim/option.c12
-rw-r--r--src/nvim/options.lua6
-rw-r--r--src/nvim/optionstr.c119
-rw-r--r--test/old/testdir/test_options.vim8
4 files changed, 95 insertions, 50 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index b941160e8a..729636d80a 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -1854,10 +1854,10 @@ static void didset_options2(void)
highlight_changed();
// Parse default for 'fillchars'.
- (void)set_chars_option(curwin, &curwin->w_p_fcs, true);
+ (void)set_fillchars_option(curwin, curwin->w_p_fcs, true);
// Parse default for 'listchars'.
- (void)set_chars_option(curwin, &curwin->w_p_lcs, true);
+ (void)set_listchars_option(curwin, curwin->w_p_lcs, true);
// Parse default for 'wildmode'.
check_opt_wim();
@@ -4164,12 +4164,12 @@ void unset_global_local_option(char *name, void *from)
break;
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);
+ set_listchars_option((win_T *)from, ((win_T *)from)->w_p_lcs, true);
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);
+ set_fillchars_option((win_T *)from, ((win_T *)from)->w_p_fcs, true);
redraw_later((win_T *)from, UPD_NOT_VALID);
break;
case PV_VE:
@@ -4749,8 +4749,8 @@ void didset_window_options(win_T *wp, bool valid_cursor)
check_colorcolumn(wp);
briopt_check(wp);
fill_culopt_flags(NULL, wp);
- set_chars_option(wp, &wp->w_p_fcs, true);
- set_chars_option(wp, &wp->w_p_lcs, true);
+ set_fillchars_option(wp, wp->w_p_fcs, true);
+ set_listchars_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, valid_cursor);
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index 7ab3e7e27e..aeef336686 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -832,7 +832,8 @@ return {
alloced=true,
redraw={'current_window'},
varname='p_fcs',
- defaults={if_true=''}
+ defaults={if_true=''},
+ cb='did_set_chars_option'
},
{
full_name='fixendofline', abbreviation='fixeol',
@@ -1485,7 +1486,8 @@ return {
alloced=true,
redraw={'current_window'},
varname='p_lcs',
- defaults={if_true="tab:> ,trail:-,nbsp:+"}
+ defaults={if_true="tab:> ,trail:-,nbsp:+"},
+ cb='did_set_chars_option'
},
{
full_name='loadplugins', abbreviation='lpl',
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index 694738d8f1..2c38835625 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -1131,30 +1131,79 @@ const char *did_set_comments(optset_T *args)
return errmsg;
}
-static void did_set_global_listfillchars(win_T *win, char **varp, int opt_flags,
- const char **errmsg)
-{
- char **local_ptr = varp == &p_lcs ? &win->w_p_lcs : &win->w_p_fcs;
- // only apply the global value to "win" when it does not have a local value
- *errmsg = set_chars_option(win, varp, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL));
- if (*errmsg == NULL) {
- // If the current window is set to use the global
- // 'listchars'/'fillchars' value, clear the window-local value.
- if (!(opt_flags & OPT_GLOBAL)) {
- clear_string_option(local_ptr);
- }
- FOR_ALL_TAB_WINDOWS(tp, wp) {
- // If the current window has a local value need to apply it
- // again, it was changed when setting the global value.
- // If no error was returned above, we don't expect an error
- // here, so ignore the return value.
- local_ptr = varp == &p_lcs ? &wp->w_p_lcs : &wp->w_p_fcs;
- if (**local_ptr == NUL) {
- (void)set_chars_option(wp, local_ptr, true);
+/// The global 'listchars' or 'fillchars' option is changed.
+static const char *did_set_global_listfillchars(win_T *win, char *val, bool opt_lcs, int opt_flags)
+{
+ const char *errmsg = NULL;
+ char **local_ptr = opt_lcs ? &win->w_p_lcs : &win->w_p_fcs;
+
+ // only apply the global value to "win" when it does not have a
+ // local value
+ if (opt_lcs) {
+ errmsg = set_listchars_option(win, val, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL));
+ } else {
+ errmsg = set_fillchars_option(win, val, **local_ptr == NUL || !(opt_flags & OPT_GLOBAL));
+ }
+ if (errmsg != NULL) {
+ return errmsg;
+ }
+
+ // If the current window is set to use the global
+ // 'listchars'/'fillchars' value, clear the window-local value.
+ if (!(opt_flags & OPT_GLOBAL)) {
+ clear_string_option(local_ptr);
+ }
+
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ // If the current window has a local value need to apply it
+ // again, it was changed when setting the global value.
+ // If no error was returned above, we don't expect an error
+ // here, so ignore the return value.
+ if (opt_lcs) {
+ if (*wp->w_p_lcs == NUL) {
+ (void)set_listchars_option(wp, wp->w_p_lcs, true);
+ }
+ } else {
+ if (*wp->w_p_fcs == NUL) {
+ (void)set_fillchars_option(wp, wp->w_p_fcs, true);
}
}
- redraw_all_later(UPD_NOT_VALID);
}
+
+ redraw_all_later(UPD_NOT_VALID);
+
+ return NULL;
+}
+
+/// Handle the new value of 'fillchars'.
+const char *set_fillchars_option(win_T *wp, char *val, int apply)
+{
+ return set_chars_option(wp, val, false, apply);
+}
+
+/// Handle the new value of 'listchars'.
+const char *set_listchars_option(win_T *wp, char *val, int apply)
+{
+ return set_chars_option(wp, val, true, apply);
+}
+
+/// The 'fillchars' option or the 'listchars' option is changed.
+const char *did_set_chars_option(optset_T *args)
+{
+ win_T *win = (win_T *)args->os_win;
+ const char *errmsg = NULL;
+
+ if (args->os_varp == p_lcs // global 'listchars'
+ || args->os_varp == p_fcs) { // global 'fillchars'
+ errmsg = did_set_global_listfillchars(win, args->os_varp,
+ args->os_varp == p_lcs, args->os_flags);
+ } else if (args->os_varp == win->w_p_lcs) { // local 'listchars'
+ errmsg = set_listchars_option(win, args->os_varp, true);
+ } else if (args->os_varp == win->w_p_fcs) { // local 'fillchars'
+ errmsg = set_fillchars_option(win, args->os_varp, true);
+ }
+
+ return errmsg;
}
/// The 'verbosefile' option is changed.
@@ -2026,13 +2075,6 @@ static const char *did_set_string_option_for(buf_T *buf, win_T *win, int opt_idx
|| gvarp == &p_fenc // 'fileencoding'
|| gvarp == &p_menc) { // 'makeencoding'
did_set_encoding(buf, varp, gvarp, opt_flags, &errmsg);
- } else if (varp == &p_lcs // global 'listchars'
- || varp == &p_fcs) { // global 'fillchars'
- did_set_global_listfillchars(win, varp, opt_flags, &errmsg);
- } else if (varp == &win->w_p_lcs) { // local 'listchars'
- errmsg = set_chars_option(win, varp, true);
- } else if (varp == &win->w_p_fcs) { // local 'fillchars'
- errmsg = set_chars_option(win, varp, true);
}
// If an error is detected, restore the previous value.
@@ -2231,16 +2273,17 @@ static int get_encoded_char_adv(const char **p)
/// Handle setting 'listchars' or 'fillchars'.
/// Assume monocell characters
///
-/// @param varp either the global or the window-local value.
+/// @param val points to either the global or the window-local value.
+/// @param opt_lcs is tue for "listchars" and FALSE for "fillchars".
/// @param apply if false, do not store the flags, only check for errors.
/// @return error message, NULL if it's OK.
-const char *set_chars_option(win_T *wp, char **varp, bool apply)
+static const char *set_chars_option(win_T *wp, const char *val, bool opt_lcs, bool apply)
{
const char *last_multispace = NULL; // Last occurrence of "multispace:"
const char *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
- const bool is_listchars = (varp == &p_lcs || varp == &wp->w_p_lcs);
+ const bool is_listchars = opt_lcs;
struct chars_tab {
int *cp; ///< char value
@@ -2284,17 +2327,17 @@ const char *set_chars_option(win_T *wp, char **varp, bool apply)
struct chars_tab *tab;
int entries;
- const char *value = *varp;
+ const char *value = val;
if (is_listchars) {
tab = lcs_tab;
entries = ARRAY_SIZE(lcs_tab);
- if (varp == &wp->w_p_lcs && wp->w_p_lcs[0] == NUL) {
+ if (opt_lcs && wp->w_p_lcs[0] == NUL) {
value = p_lcs; // local value is empty, use the global value
}
} else {
tab = fcs_tab;
entries = ARRAY_SIZE(fcs_tab);
- if (varp == &wp->w_p_fcs && wp->w_p_fcs[0] == NUL) {
+ if (!opt_lcs && wp->w_p_fcs[0] == NUL) {
value = p_fcs; // local value is empty, use the global value
}
}
@@ -2460,17 +2503,17 @@ const char *set_chars_option(win_T *wp, char **varp, bool apply)
/// @return an untranslated error message if any of them is invalid, NULL otherwise.
const char *check_chars_options(void)
{
- if (set_chars_option(curwin, &p_lcs, false) != NULL) {
+ if (set_listchars_option(curwin, p_lcs, false) != NULL) {
return e_conflicts_with_value_of_listchars;
}
- if (set_chars_option(curwin, &p_fcs, false) != NULL) {
+ if (set_fillchars_option(curwin, p_fcs, false) != NULL) {
return e_conflicts_with_value_of_fillchars;
}
FOR_ALL_TAB_WINDOWS(tp, wp) {
- if (set_chars_option(wp, &wp->w_p_lcs, true) != NULL) {
+ if (set_listchars_option(wp, wp->w_p_lcs, true) != NULL) {
return e_conflicts_with_value_of_listchars;
}
- if (set_chars_option(wp, &wp->w_p_fcs, true) != NULL) {
+ if (set_fillchars_option(wp, wp->w_p_fcs, true) != NULL) {
return e_conflicts_with_value_of_fillchars;
}
}
diff --git a/test/old/testdir/test_options.vim b/test/old/testdir/test_options.vim
index e4cdf539e2..769aa1c35f 100644
--- a/test/old/testdir/test_options.vim
+++ b/test/old/testdir/test_options.vim
@@ -1480,18 +1480,18 @@ func Test_string_option_revert_on_failure()
if has('win32') && has('terminal')
call add(optlist, ['termwintype', 'winpty', 'a123'])
endif
- if has('+toolbar')
+ if exists('+toolbar')
call add(optlist, ['toolbar', 'text', 'a123'])
call add(optlist, ['toolbariconsize', 'medium', 'a123'])
endif
- if has('+mouse')
+ if exists('+ttymouse') && !has('gui')
call add(optlist, ['ttymouse', 'xterm', 'a123'])
endif
- if has('+vartabs')
+ if exists('+vartabs')
call add(optlist, ['varsofttabstop', '12', 'a123'])
call add(optlist, ['vartabstop', '4,20', '4,'])
endif
- if has('gui')
+ if exists('+winaltkeys')
call add(optlist, ['winaltkeys', 'no', 'a123'])
endif
for opt in optlist