aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/options.txt4
-rw-r--r--src/nvim/option.c68
-rw-r--r--src/nvim/option_defs.h2
-rw-r--r--src/nvim/options.lua6
-rw-r--r--src/nvim/testdir/test_display.vim1
-rw-r--r--test/functional/options/chars_spec.lua42
-rw-r--r--test/functional/ui/mouse_spec.lua8
7 files changed, 101 insertions, 30 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 386fcdf8c0..209b8a7aee 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -2362,7 +2362,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'fillchars'* *'fcs'*
'fillchars' 'fcs' string (default "")
- local to window
+ global or local to window |global-local|
Characters to fill the statuslines and vertical separators.
It is a comma separated list of items:
@@ -3671,7 +3671,7 @@ A jump table for the options with a short description can be found at |Q_op|.
*'listchars'* *'lcs'*
'listchars' 'lcs' string (default: "tab:> ,trail:-,nbsp:+"
Vi default: "eol:$")
- local to window
+ global or local to window |global-local|
Strings to use in 'list' mode and for the |:list| command. It is a
comma separated list of string settings.
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 20351d3908..25933d497e 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -2205,10 +2205,10 @@ static void didset_options2(void)
(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);
+ (void)set_chars_option(curwin, &curwin->w_p_fcs, true);
// Parse default for 'listchars'.
- (void)set_chars_option(curwin, &curwin->w_p_lcs);
+ (void)set_chars_option(curwin, &curwin->w_p_lcs, true);
// Parse default for 'wildmode'.
check_opt_wim();
@@ -2663,11 +2663,11 @@ did_set_string_option(
errmsg = e_invarg;
} else {
FOR_ALL_TAB_WINDOWS(tp, wp) {
- if (set_chars_option(wp, &wp->w_p_lcs) != NULL) {
+ if (set_chars_option(wp, &wp->w_p_lcs, true) != NULL) {
errmsg = (char_u *)_("E834: Conflicts with value of 'listchars'");
goto ambw_end;
}
- if (set_chars_option(wp, &wp->w_p_fcs) != NULL) {
+ if (set_chars_option(wp, &wp->w_p_fcs, true) != NULL) {
errmsg = (char_u *)_("E835: Conflicts with value of 'fillchars'");
goto ambw_end;
}
@@ -2868,10 +2868,26 @@ ambw_end:
}
s = skip_to_option_part(s);
}
- } else if (varp == &curwin->w_p_lcs) { // 'listchars'
- errmsg = set_chars_option(curwin, varp);
- } else if (varp == &curwin->w_p_fcs) { // 'fillchars'
- errmsg = set_chars_option(curwin, varp);
+ } else if (varp == &p_lcs) { // 'listchars'
+ errmsg = set_chars_option(curwin, varp, false);
+ if (!errmsg) {
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ 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) { // 'fillchars'
+ errmsg = set_chars_option(curwin, varp, false);
+ if (!errmsg) {
+ FOR_ALL_TAB_WINDOWS(tp, wp) {
+ 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'
@@ -3501,7 +3517,7 @@ skip:
///
/// @param varp either &curwin->w_p_lcs or &curwin->w_p_fcs
/// @return error message, NULL if it's OK.
-static char_u *set_chars_option(win_T *wp, char_u **varp)
+static char_u *set_chars_option(win_T *wp, char_u **varp, bool set)
{
int round, i, len, entries;
char_u *p, *s;
@@ -3536,12 +3552,18 @@ static char_u *set_chars_option(win_T *wp, char_u **varp)
{ &wp->w_p_lcs_chars.conceal, "conceal", NUL },
};
- if (varp == &wp->w_p_lcs) {
+ 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 "|" and "·" take 2 columns, which is
// forbidden (TUI limitation?). Set old defaults.
@@ -3554,7 +3576,7 @@ static char_u *set_chars_option(win_T *wp, char_u **varp)
}
// first round: check for valid value, second round: assign values
- for (round = 0; round <= 1; round++) {
+ 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++) {
@@ -3562,7 +3584,7 @@ static char_u *set_chars_option(win_T *wp, char_u **varp)
*(tab[i].cp) = tab[i].def;
}
}
- if (varp == &wp->w_p_lcs) {
+ if (varp == &p_lcs || varp == &wp->w_p_lcs) {
wp->w_p_lcs_chars.tab1 = NUL;
wp->w_p_lcs_chars.tab3 = NUL;
}
@@ -5562,6 +5584,16 @@ void unset_global_local_option(char *name, void *from)
case PV_MENC:
clear_string_option(&buf->b_p_menc);
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);
+ redraw_win_later((win_T *)from, 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_win_later((win_T *)from, NOT_VALID);
+ break;
}
}
@@ -5598,6 +5630,8 @@ static char_u *get_varp_scope(vimoption_T *p, int opt_flags)
case PV_LW: return (char_u *)&(curbuf->b_p_lw);
case PV_BKC: return (char_u *)&(curbuf->b_p_bkc);
case PV_MENC: return (char_u *)&(curbuf->b_p_menc);
+ case PV_FCS: return (char_u *)&(curwin->w_p_fcs);
+ case PV_LCS: return (char_u *)&(curwin->w_p_lcs);
}
return NULL; // "cannot happen"
}
@@ -5656,6 +5690,10 @@ static char_u *get_varp(vimoption_T *p)
? (char_u *)&(curbuf->b_p_lw) : p->var;
case PV_MENC: return *curbuf->b_p_menc != NUL
? (char_u *)&(curbuf->b_p_menc) : p->var;
+ case PV_FCS: return *curwin->w_p_fcs != NUL
+ ? (char_u *)&(curwin->w_p_fcs) : p->var;
+ case PV_LCS: return *curwin->w_p_lcs != NUL
+ ? (char_u *)&(curwin->w_p_lcs) : p->var;
case PV_ARAB: return (char_u *)&(curwin->w_p_arab);
case PV_LIST: return (char_u *)&(curwin->w_p_list);
@@ -5753,8 +5791,6 @@ static char_u *get_varp(vimoption_T *p)
case PV_KMAP: return (char_u *)&(curbuf->b_p_keymap);
case PV_SCL: return (char_u *)&(curwin->w_p_scl);
case PV_WINHL: return (char_u *)&(curwin->w_p_winhl);
- case PV_FCS: return (char_u *)&(curwin->w_p_fcs);
- case PV_LCS: return (char_u *)&(curwin->w_p_lcs);
case PV_WINBL: return (char_u *)&(curwin->w_p_winbl);
default: IEMSG(_("E356: get_varp ERROR"));
}
@@ -5896,8 +5932,8 @@ void didset_window_options(win_T *wp)
{
check_colorcolumn(wp);
briopt_check(wp);
- set_chars_option(wp, &wp->w_p_fcs);
- set_chars_option(wp, &wp->w_p_lcs);
+ set_chars_option(wp, &wp->w_p_fcs, true);
+ set_chars_option(wp, &wp->w_p_lcs, true);
parse_winhl_opt(wp); // sets w_hl_needs_update also for w_p_winbl
wp->w_grid.blending = wp->w_p_winbl > 0;
}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index e5a3c0bd95..ce0ea19a2f 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -484,6 +484,7 @@ EXTERN long p_linespace; // 'linespace'
EXTERN char_u *p_lispwords; // 'lispwords'
EXTERN long p_ls; // 'laststatus'
EXTERN long p_stal; // 'showtabline'
+EXTERN char_u *p_lcs; // 'listchars'
EXTERN int p_lz; // 'lazyredraw'
EXTERN int p_lpl; // 'loadplugins'
@@ -652,6 +653,7 @@ EXTERN long p_ul; ///< 'undolevels'
EXTERN long p_ur; ///< 'undoreload'
EXTERN long p_uc; ///< 'updatecount'
EXTERN long p_ut; ///< 'updatetime'
+EXTERN char_u *p_fcs; ///< 'fillchar'
EXTERN char_u *p_shada; ///< 'shada'
EXTERN char *p_shadafile; ///< 'shadafile'
EXTERN char_u *p_vdir; ///< 'viewdir'
diff --git a/src/nvim/options.lua b/src/nvim/options.lua
index d20174466d..0aa367e059 100644
--- a/src/nvim/options.lua
+++ b/src/nvim/options.lua
@@ -804,11 +804,12 @@ return {
},
{
full_name='fillchars', abbreviation='fcs',
- type='string', list='onecomma', scope={'window'},
+ type='string', list='onecomma', scope={'global', 'window'},
deny_duplicates=true,
vi_def=true,
alloced=true,
redraw={'current_window'},
+ varname='p_fcs',
defaults={if_true={vi=''}}
},
{
@@ -1420,11 +1421,12 @@ return {
},
{
full_name='listchars', abbreviation='lcs',
- type='string', list='onecomma', scope={'window'},
+ type='string', list='onecomma', scope={'global', 'window'},
deny_duplicates=true,
vim=true,
alloced=true,
redraw={'current_window'},
+ varname='p_lcs',
defaults={if_true={vi="eol:$", vim="tab:> ,trail:-,nbsp:+"}}
},
{
diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim
index 66c13ded82..1c2f5a05ff 100644
--- a/src/nvim/testdir/test_display.vim
+++ b/src/nvim/testdir/test_display.vim
@@ -71,6 +71,7 @@ func! Test_display_foldtext_mbyte()
endfunc
func Test_display_listchars_precedes()
+ set fillchars+=vert:\|
call NewWindow(10, 10)
" Need a physical line that wraps over the complete
" window size
diff --git a/test/functional/options/chars_spec.lua b/test/functional/options/chars_spec.lua
index 3453e79429..5439ca3dba 100644
--- a/test/functional/options/chars_spec.lua
+++ b/test/functional/options/chars_spec.lua
@@ -67,16 +67,29 @@ describe("'fillchars'", function()
shouldfail('eob:xy') -- two ascii chars
shouldfail('eob:\255', 'eob:<ff>') -- invalid UTF-8
end)
- it('is local to window', function()
- clear()
- screen = Screen.new(50, 5)
- screen:attach()
+ it('has global value', function()
+ screen:try_resize(50, 5)
insert("foo\nbar")
command('set laststatus=0')
command('1,2fold')
command('vsplit')
command('set fillchars=fold:x')
screen:expect([[
+ ^+-- 2 lines: fooxxxxxxxx│+-- 2 lines: fooxxxxxxx|
+ ~ │~ |
+ ~ │~ |
+ ~ │~ |
+ |
+ ]])
+ end)
+ it('has local window value', function()
+ screen:try_resize(50, 5)
+ insert("foo\nbar")
+ command('set laststatus=0')
+ command('1,2fold')
+ command('vsplit')
+ command('setl fillchars=fold:x')
+ screen:expect([[
^+-- 2 lines: fooxxxxxxxx│+-- 2 lines: foo·······|
~ │~ |
~ │~ |
@@ -96,12 +109,25 @@ describe("'listchars'", function()
screen:attach()
end)
- it('is local to window', function()
+ it('has global value', function()
+ feed('i<tab><tab><tab><esc>')
+ command('set list laststatus=0')
+ command('vsplit')
+ command('set listchars=tab:<->')
+ screen:expect([[
+ <------><------>^<------> │<------><------><------>|
+ ~ │~ |
+ ~ │~ |
+ ~ │~ |
+ |
+ ]])
+ end)
+ it('has value local to window', function()
feed('i<tab><tab><tab><esc>')
- command('set laststatus=0')
- command('set list listchars=tab:<->')
+ command('set list laststatus=0')
+ command('setl listchars=tab:<->')
command('vsplit')
- command('set listchars&')
+ command('setl listchars<')
screen:expect([[
> > ^> │<------><------><------>|
~ │~ |
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index 7840ba9167..d857b57a31 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -12,7 +12,10 @@ describe('ui/mouse/input', function()
clear()
meths.set_option('mouse', 'a')
meths.set_option('list', true)
- meths.set_option('listchars', 'eol:$')
+ -- NB: this is weird, but mostly irrelevant to the test
+ -- So I didn't bother to change it
+ command('set listchars=eol:$')
+ command('setl listchars=nbsp:x')
screen = Screen.new(25, 5)
screen:attach()
screen:set_default_attr_ids({
@@ -812,7 +815,8 @@ describe('ui/mouse/input', function()
feed_command('set concealcursor=ni')
feed_command('set nowrap')
- feed_command('set shiftwidth=2 tabstop=4 list listchars=tab:>-')
+ feed_command('set shiftwidth=2 tabstop=4 list')
+ feed_command('setl listchars=tab:>-')
feed_command('syntax match NonText "\\*" conceal')
feed_command('syntax match NonText "cats" conceal cchar=X')
feed_command('syntax match NonText "x" conceal cchar=>')