vim-patch:9.0.0036: 'fillchars' cannot have window-local values

Problem:    'fillchars' cannot have window-local values.
Solution:   Make 'fillchars' global-local. (closes vim/vim#5206)
96ba25ac01

Cherry-pick g:run_nr from patch 8.2.0454.

N/A patches for version.c:

vim-patch:9.0.0037: build error

Problem:    Build error.
Solution:   Add missing change.
510f03738d
This commit is contained in:
zeertzjq
2022-08-26 08:25:36 +08:00
parent 1ba3d5c712
commit fa1c761d62
10 changed files with 109 additions and 67 deletions

View File

@@ -2454,28 +2454,30 @@ A jump table for the options with a short description can be found at |Q_op|.
*'fillchars'* *'fcs'* *'fillchars'* *'fcs'*
'fillchars' 'fcs' string (default "") 'fillchars' 'fcs' string (default "")
global or local to window |global-local| global or local to window |global-local|
Characters to fill the statuslines and vertical separators. Characters to fill the statuslines, vertical separators and special
It is a comma-separated list of items: lines in the window.
It is a comma-separated list of items. Each item has a name, a colon
and the value of that item:
item default Used for ~ item default Used for ~
stl:c ' ' or '^' statusline of the current window stl ' ' or '^' statusline of the current window
stlnc:c ' ' or '=' statusline of the non-current windows stlnc ' ' or '=' statusline of the non-current windows
wbr:c ' ' window bar wbr ' ' window bar
horiz:c '─' or '-' horizontal separators |:split| horiz '─' or '-' horizontal separators |:split|
horizup:c '┴' or '-' upwards facing horizontal separator horizup '┴' or '-' upwards facing horizontal separator
horizdown:c '┬' or '-' downwards facing horizontal separator horizdown '┬' or '-' downwards facing horizontal separator
vert:c '│' or '|' vertical separators |:vsplit| vert '│' or '|' vertical separators |:vsplit|
vertleft:c '┤' or '|' left facing vertical separator vertleft '┤' or '|' left facing vertical separator
vertright:c '├' or '|' right facing vertical separator vertright '├' or '|' right facing vertical separator
verthoriz:c '┼' or '+' overlapping vertical and horizontal verthoriz '┼' or '+' overlapping vertical and horizontal
separator separator
fold:c '·' or '-' filling 'foldtext' fold '·' or '-' filling 'foldtext'
foldopen:c '-' mark the beginning of a fold foldopen '-' mark the beginning of a fold
foldclose:c '+' show a closed fold foldclose '+' show a closed fold
foldsep:c '│' or '|' open fold middle marker foldsep '│' or '|' open fold middle marker
diff:c '-' deleted lines of the 'diff' option diff '-' deleted lines of the 'diff' option
msgsep:c ' ' message separator 'display' msgsep ' ' message separator 'display'
eob:c '~' empty lines at the end of a buffer eob '~' empty lines at the end of a buffer
Any one that is omitted will fall back to the default. For "stl" and Any one that is omitted will fall back to the default. For "stl" and
"stlnc" the space will be used when there is highlighting, '^' or '=' "stlnc" the space will be used when there is highlighting, '^' or '='
@@ -2500,19 +2502,19 @@ A jump table for the options with a short description can be found at |Q_op|.
The highlighting used for these items: The highlighting used for these items:
item highlight group ~ item highlight group ~
stl:c StatusLine |hl-StatusLine| stl StatusLine |hl-StatusLine|
stlnc:c StatusLineNC |hl-StatusLineNC| stlnc StatusLineNC |hl-StatusLineNC|
wbr:c WinBar |hl-WinBar| or |hl-WinBarNC| wbr WinBar |hl-WinBar| or |hl-WinBarNC|
horiz:c WinSeparator |hl-WinSeparator| horiz WinSeparator |hl-WinSeparator|
horizup:c WinSeparator |hl-WinSeparator| horizup WinSeparator |hl-WinSeparator|
horizdown:c WinSeparator |hl-WinSeparator| horizdown WinSeparator |hl-WinSeparator|
vert:c WinSeparator |hl-WinSeparator| vert WinSeparator |hl-WinSeparator|
vertleft:c WinSeparator |hl-WinSeparator| vertleft WinSeparator |hl-WinSeparator|
vertright:c WinSeparator |hl-WinSeparator| vertright WinSeparator |hl-WinSeparator|
verthoriz:c WinSeparator |hl-WinSeparator| verthoriz WinSeparator |hl-WinSeparator|
fold:c Folded |hl-Folded| fold Folded |hl-Folded|
diff:c DiffDelete |hl-DiffDelete| diff DiffDelete |hl-DiffDelete|
eob:c EndOfBuffer |hl-EndOfBuffer| eob EndOfBuffer |hl-EndOfBuffer|
*'fixendofline'* *'fixeol'* *'nofixendofline'* *'nofixeol'* *'fixendofline'* *'fixeol'* *'nofixendofline'* *'nofixeol'*
'fixendofline' 'fixeol' boolean (default on) 'fixendofline' 'fixeol' boolean (default on)

View File

@@ -257,10 +257,10 @@ typedef struct {
#define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn' #define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
char *wo_winhl; char *wo_winhl;
#define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight' #define w_p_winhl w_onebuf_opt.wo_winhl // 'winhighlight'
char *wo_fcs;
#define w_p_fcs w_onebuf_opt.wo_fcs // 'fillchars'
char *wo_lcs; char *wo_lcs;
#define w_p_lcs w_onebuf_opt.wo_lcs // 'listchars' #define w_p_lcs w_onebuf_opt.wo_lcs // 'listchars'
char *wo_fcs;
#define w_p_fcs w_onebuf_opt.wo_fcs // 'fillchars'
long wo_winbl; long wo_winbl;
#define w_p_winbl w_onebuf_opt.wo_winbl // 'winblend' #define w_p_winbl w_onebuf_opt.wo_winbl // 'winblend'

View File

@@ -1247,7 +1247,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
} }
char_attr = 0; char_attr = 0;
} else if (filler_todo > 0) { } else if (filler_todo > 0) {
// draw "deleted" diff line(s) // Draw "deleted" diff line(s)
if (char2cells(wp->w_p_fcs_chars.diff) > 1) { if (char2cells(wp->w_p_fcs_chars.diff) > 1) {
c_extra = '-'; c_extra = '-';
c_final = NUL; c_final = NUL;

View File

@@ -1920,8 +1920,9 @@ win_update_start:
wp->w_botline = lnum; wp->w_botline = lnum;
} }
// make sure the rest of the screen is blank // Make sure the rest of the screen is blank.
// write the 'eob' character to rows that aren't part of the file. // write the "eob" character from 'fillchars' to rows that aren't part
// of the file.
win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, row, wp->w_grid.rows, win_draw_end(wp, wp->w_p_fcs_chars.eob, ' ', false, row, wp->w_grid.rows,
HLF_EOB); HLF_EOB);
} }

View File

@@ -1989,8 +1989,7 @@ theend:
} }
/// @return true if string "s" is a valid utf-8 string. /// @return true if string "s" is a valid utf-8 string.
/// When "end" is NULL stop at the first NUL. /// When "end" is NULL stop at the first NUL. Otherwise stop at "end".
/// When "end" is positive stop there.
bool utf_valid_string(const char_u *s, const char_u *end) bool utf_valid_string(const char_u *s, const char_u *end)
{ {
const char_u *p = s; const char_u *p = s;

View File

@@ -4250,6 +4250,14 @@ void win_copy_options(win_T *wp_from, win_T *wp_to)
didset_window_options(wp_to, true); didset_window_options(wp_to, true);
} }
static char *copy_option_val(const char *val)
{
if (val == empty_option) {
return empty_option; // no need to allocate memory
}
return xstrdup(val);
}
/// Copy the options from one winopt_T to another. /// Copy the options from one winopt_T to another.
/// Doesn't free the old option values in "to", use clear_winopt() for that. /// Doesn't free the old option values in "to", use clear_winopt() for that.
/// The 'scroll' option is not copied, because it depends on the window height. /// The 'scroll' option is not copied, because it depends on the window height.
@@ -4258,21 +4266,23 @@ void copy_winopt(winopt_T *from, winopt_T *to)
{ {
to->wo_arab = from->wo_arab; to->wo_arab = from->wo_arab;
to->wo_list = from->wo_list; to->wo_list = from->wo_list;
to->wo_lcs = copy_option_val(from->wo_lcs);
to->wo_fcs = copy_option_val(from->wo_fcs);
to->wo_nu = from->wo_nu; to->wo_nu = from->wo_nu;
to->wo_rnu = from->wo_rnu; to->wo_rnu = from->wo_rnu;
to->wo_ve = xstrdup(from->wo_ve); to->wo_ve = copy_option_val(from->wo_ve);
to->wo_ve_flags = from->wo_ve_flags; to->wo_ve_flags = from->wo_ve_flags;
to->wo_nuw = from->wo_nuw; to->wo_nuw = from->wo_nuw;
to->wo_rl = from->wo_rl; to->wo_rl = from->wo_rl;
to->wo_rlc = xstrdup(from->wo_rlc); to->wo_rlc = copy_option_val(from->wo_rlc);
to->wo_sbr = xstrdup(from->wo_sbr); to->wo_sbr = copy_option_val(from->wo_sbr);
to->wo_stl = xstrdup(from->wo_stl); to->wo_stl = copy_option_val(from->wo_stl);
to->wo_wbr = xstrdup(from->wo_wbr); to->wo_wbr = copy_option_val(from->wo_wbr);
to->wo_wrap = from->wo_wrap; to->wo_wrap = from->wo_wrap;
to->wo_wrap_save = from->wo_wrap_save; to->wo_wrap_save = from->wo_wrap_save;
to->wo_lbr = from->wo_lbr; to->wo_lbr = from->wo_lbr;
to->wo_bri = from->wo_bri; to->wo_bri = from->wo_bri;
to->wo_briopt = xstrdup(from->wo_briopt); to->wo_briopt = copy_option_val(from->wo_briopt);
to->wo_scb = from->wo_scb; to->wo_scb = from->wo_scb;
to->wo_scb_save = from->wo_scb_save; to->wo_scb_save = from->wo_scb_save;
to->wo_crb = from->wo_crb; to->wo_crb = from->wo_crb;
@@ -4280,30 +4290,28 @@ void copy_winopt(winopt_T *from, winopt_T *to)
to->wo_spell = from->wo_spell; to->wo_spell = from->wo_spell;
to->wo_cuc = from->wo_cuc; to->wo_cuc = from->wo_cuc;
to->wo_cul = from->wo_cul; to->wo_cul = from->wo_cul;
to->wo_culopt = xstrdup(from->wo_culopt); to->wo_culopt = copy_option_val(from->wo_culopt);
to->wo_cc = xstrdup(from->wo_cc); to->wo_cc = copy_option_val(from->wo_cc);
to->wo_diff = from->wo_diff; to->wo_diff = from->wo_diff;
to->wo_diff_saved = from->wo_diff_saved; to->wo_diff_saved = from->wo_diff_saved;
to->wo_cocu = xstrdup(from->wo_cocu); to->wo_cocu = copy_option_val(from->wo_cocu);
to->wo_cole = from->wo_cole; to->wo_cole = from->wo_cole;
to->wo_fdc = xstrdup(from->wo_fdc); to->wo_fdc = copy_option_val(from->wo_fdc);
to->wo_fdc_save = from->wo_diff_saved ? xstrdup(from->wo_fdc_save) : empty_option; to->wo_fdc_save = from->wo_diff_saved ? xstrdup(from->wo_fdc_save) : empty_option;
to->wo_fen = from->wo_fen; to->wo_fen = from->wo_fen;
to->wo_fen_save = from->wo_fen_save; to->wo_fen_save = from->wo_fen_save;
to->wo_fdi = xstrdup(from->wo_fdi); to->wo_fdi = copy_option_val(from->wo_fdi);
to->wo_fml = from->wo_fml; to->wo_fml = from->wo_fml;
to->wo_fdl = from->wo_fdl; to->wo_fdl = from->wo_fdl;
to->wo_fdl_save = from->wo_fdl_save; to->wo_fdl_save = from->wo_fdl_save;
to->wo_fdm = xstrdup(from->wo_fdm); to->wo_fdm = copy_option_val(from->wo_fdm);
to->wo_fdm_save = from->wo_diff_saved ? xstrdup(from->wo_fdm_save) : empty_option; to->wo_fdm_save = from->wo_diff_saved ? xstrdup(from->wo_fdm_save) : empty_option;
to->wo_fdn = from->wo_fdn; to->wo_fdn = from->wo_fdn;
to->wo_fde = xstrdup(from->wo_fde); to->wo_fde = copy_option_val(from->wo_fde);
to->wo_fdt = xstrdup(from->wo_fdt); to->wo_fdt = copy_option_val(from->wo_fdt);
to->wo_fmr = xstrdup(from->wo_fmr); to->wo_fmr = copy_option_val(from->wo_fmr);
to->wo_scl = xstrdup(from->wo_scl); to->wo_scl = copy_option_val(from->wo_scl);
to->wo_winhl = xstrdup(from->wo_winhl); to->wo_winhl = copy_option_val(from->wo_winhl);
to->wo_fcs = xstrdup(from->wo_fcs);
to->wo_lcs = xstrdup(from->wo_lcs);
to->wo_winbl = from->wo_winbl; to->wo_winbl = from->wo_winbl;
// Copy the script context so that we know were the value was last set. // Copy the script context so that we know were the value was last set.
@@ -4338,8 +4346,8 @@ static void check_winopt(winopt_T *wop)
check_string_option(&wop->wo_cocu); check_string_option(&wop->wo_cocu);
check_string_option(&wop->wo_briopt); check_string_option(&wop->wo_briopt);
check_string_option(&wop->wo_winhl); check_string_option(&wop->wo_winhl);
check_string_option(&wop->wo_fcs);
check_string_option(&wop->wo_lcs); check_string_option(&wop->wo_lcs);
check_string_option(&wop->wo_fcs);
check_string_option(&wop->wo_ve); check_string_option(&wop->wo_ve);
check_string_option(&wop->wo_wbr); check_string_option(&wop->wo_wbr);
} }
@@ -4364,8 +4372,8 @@ void clear_winopt(winopt_T *wop)
clear_string_option(&wop->wo_cocu); clear_string_option(&wop->wo_cocu);
clear_string_option(&wop->wo_briopt); clear_string_option(&wop->wo_briopt);
clear_string_option(&wop->wo_winhl); clear_string_option(&wop->wo_winhl);
clear_string_option(&wop->wo_fcs);
clear_string_option(&wop->wo_lcs); clear_string_option(&wop->wo_lcs);
clear_string_option(&wop->wo_fcs);
clear_string_option(&wop->wo_ve); clear_string_option(&wop->wo_ve);
clear_string_option(&wop->wo_wbr); clear_string_option(&wop->wo_wbr);
} }

View File

@@ -972,8 +972,8 @@ enum {
WV_WRAP, WV_WRAP,
WV_SCL, WV_SCL,
WV_WINHL, WV_WINHL,
WV_FCS,
WV_LCS, WV_LCS,
WV_FCS,
WV_WINBL, WV_WINBL,
WV_WBR, WV_WBR,
WV_COUNT, // must be the last one WV_COUNT, // must be the last one

View File

@@ -960,8 +960,10 @@ char *did_set_string_option(int opt_idx, char_u **varp, char_u *oldval, char *er
FOR_ALL_TAB_WINDOWS(tp, wp) { FOR_ALL_TAB_WINDOWS(tp, wp) {
// If no error was returned above, we don't expect an error // If no error was returned above, we don't expect an error
// here, so ignore the return value. // here, so ignore the return value.
if (*wp->w_p_lcs == NUL) {
(void)set_chars_option(wp, (char_u **)&wp->w_p_lcs, true); (void)set_chars_option(wp, (char_u **)&wp->w_p_lcs, true);
} }
}
redraw_all_later(UPD_NOT_VALID); redraw_all_later(UPD_NOT_VALID);
} }
} else if (varp == (char_u **)&curwin->w_p_lcs) { // local 'listchars' } else if (varp == (char_u **)&curwin->w_p_lcs) { // local 'listchars'
@@ -977,8 +979,10 @@ char *did_set_string_option(int opt_idx, char_u **varp, char_u *oldval, char *er
FOR_ALL_TAB_WINDOWS(tp, wp) { FOR_ALL_TAB_WINDOWS(tp, wp) {
// If no error was returned above, we don't expect an error // If no error was returned above, we don't expect an error
// here, so ignore the return value. // here, so ignore the return value.
if (*wp->w_p_fcs == NUL) {
(void)set_chars_option(wp, (char_u **)&wp->w_p_fcs, true); (void)set_chars_option(wp, (char_u **)&wp->w_p_fcs, true);
} }
}
redraw_all_later(UPD_NOT_VALID); redraw_all_later(UPD_NOT_VALID);
} }
} else if (varp == (char_u **)&curwin->w_p_fcs) { // local 'fillchars' } else if (varp == (char_u **)&curwin->w_p_fcs) { // local 'fillchars'

View File

@@ -425,7 +425,7 @@ for s:test in sort(s:tests)
set belloff=all set belloff=all
let prev_error = '' let prev_error = ''
let total_errors = [] let total_errors = []
let run_nr = 1 let g:run_nr = 1
" A test can set g:test_is_flaky to retry running the test. " A test can set g:test_is_flaky to retry running the test.
let g:test_is_flaky = 0 let g:test_is_flaky = 0
@@ -444,10 +444,10 @@ for s:test in sort(s:tests)
call add(s:messages, 'Found errors in ' . s:test . ':') call add(s:messages, 'Found errors in ' . s:test . ':')
call extend(s:messages, v:errors) call extend(s:messages, v:errors)
call add(total_errors, 'Run ' . run_nr . ':') call add(total_errors, 'Run ' . g:run_nr . ':')
call extend(total_errors, v:errors) call extend(total_errors, v:errors)
if run_nr == 5 || prev_error == v:errors[0] if g:run_nr >= 5 || prev_error == v:errors[0]
call add(total_errors, 'Flaky test failed too often, giving up') call add(total_errors, 'Flaky test failed too often, giving up')
let v:errors = total_errors let v:errors = total_errors
break break
@@ -462,7 +462,7 @@ for s:test in sort(s:tests)
let prev_error = v:errors[0] let prev_error = v:errors[0]
let v:errors = [] let v:errors = []
let run_nr += 1 let g:run_nr += 1
call RunTheTest(s:test) call RunTheTest(s:test)

View File

@@ -363,6 +363,34 @@ func Test_fold_fillchars()
set fillchars& fdc& foldmethod& foldenable& set fillchars& fdc& foldmethod& foldenable&
endfunc endfunc
func Test_local_fillchars()
CheckScreendump
let lines =<< trim END
call setline(1, ['window 1']->repeat(3))
setlocal fillchars=stl:1,stlnc:a,vert:=,eob:x
vnew
call setline(1, ['window 2']->repeat(3))
setlocal fillchars=stl:2,stlnc:b,vert:+,eob:y
new
wincmd J
call setline(1, ['window 3']->repeat(3))
setlocal fillchars=stl:3,stlnc:c,vert:<,eob:z
vnew
call setline(1, ['window 4']->repeat(3))
setlocal fillchars=stl:4,stlnc:d,vert:>,eob:o
END
call writefile(lines, 'Xdisplayfillchars')
let buf = RunVimInTerminal('-S Xdisplayfillchars', #{rows: 12})
call VerifyScreenDump(buf, 'Test_display_fillchars_1', {})
call term_sendkeys(buf, ":wincmd k\r")
call VerifyScreenDump(buf, 'Test_display_fillchars_2', {})
call StopVimInTerminal(buf)
call delete('Xdisplayfillchars')
endfunc
func Test_display_linebreak_breakat() func Test_display_linebreak_breakat()
new new
vert resize 25 vert resize 25