diff options
-rw-r--r-- | runtime/doc/options.txt | 4 | ||||
-rw-r--r-- | src/nvim/option.c | 68 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/options.lua | 6 | ||||
-rw-r--r-- | src/nvim/testdir/test_display.vim | 1 | ||||
-rw-r--r-- | test/functional/options/chars_spec.lua | 42 | ||||
-rw-r--r-- | test/functional/ui/mouse_spec.lua | 8 |
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=>') |