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' string (default "")
global or local to window |global-local|
Characters to fill the statuslines and vertical separators.
It is a comma-separated list of items:
Characters to fill the statuslines, vertical separators and special
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 ~
stl:c ' ' or '^' statusline of the current window
stlnc:c ' ' or '=' statusline of the non-current windows
wbr:c ' ' window bar
horiz:c '─' or '-' horizontal separators |:split|
horizup:c '┴' or '-' upwards facing horizontal separator
horizdown:c '┬' or '-' downwards facing horizontal separator
vert:c '│' or '|' vertical separators |:vsplit|
vertleft:c '┤' or '|' left facing vertical separator
vertright:c '├' or '|' right facing vertical separator
verthoriz:c '┼' or '+' overlapping vertical and horizontal
stl ' ' or '^' statusline of the current window
stlnc ' ' or '=' statusline of the non-current windows
wbr ' ' window bar
horiz '─' or '-' horizontal separators |:split|
horizup '┴' or '-' upwards facing horizontal separator
horizdown '┬' or '-' downwards facing horizontal separator
vert '│' or '|' vertical separators |:vsplit|
vertleft '┤' or '|' left facing vertical separator
vertright '├' or '|' right facing vertical separator
verthoriz '┼' or '+' overlapping vertical and horizontal
separator
fold:c '·' or '-' filling 'foldtext'
foldopen:c '-' mark the beginning of a fold
foldclose:c '+' show a closed fold
foldsep:c '│' or '|' open fold middle marker
diff:c '-' deleted lines of the 'diff' option
msgsep:c ' ' message separator 'display'
eob:c '~' empty lines at the end of a buffer
fold '·' or '-' filling 'foldtext'
foldopen '-' mark the beginning of a fold
foldclose '+' show a closed fold
foldsep '│' or '|' open fold middle marker
diff '-' deleted lines of the 'diff' option
msgsep ' ' message separator 'display'
eob '~' empty lines at the end of a buffer
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 '='
@@ -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:
item highlight group ~
stl:c StatusLine |hl-StatusLine|
stlnc:c StatusLineNC |hl-StatusLineNC|
wbr:c WinBar |hl-WinBar| or |hl-WinBarNC|
horiz:c WinSeparator |hl-WinSeparator|
horizup:c WinSeparator |hl-WinSeparator|
horizdown:c WinSeparator |hl-WinSeparator|
vert:c WinSeparator |hl-WinSeparator|
vertleft:c WinSeparator |hl-WinSeparator|
vertright:c WinSeparator |hl-WinSeparator|
verthoriz:c WinSeparator |hl-WinSeparator|
fold:c Folded |hl-Folded|
diff:c DiffDelete |hl-DiffDelete|
eob:c EndOfBuffer |hl-EndOfBuffer|
stl StatusLine |hl-StatusLine|
stlnc StatusLineNC |hl-StatusLineNC|
wbr WinBar |hl-WinBar| or |hl-WinBarNC|
horiz WinSeparator |hl-WinSeparator|
horizup WinSeparator |hl-WinSeparator|
horizdown WinSeparator |hl-WinSeparator|
vert WinSeparator |hl-WinSeparator|
vertleft WinSeparator |hl-WinSeparator|
vertright WinSeparator |hl-WinSeparator|
verthoriz WinSeparator |hl-WinSeparator|
fold Folded |hl-Folded|
diff DiffDelete |hl-DiffDelete|
eob EndOfBuffer |hl-EndOfBuffer|
*'fixendofline'* *'fixeol'* *'nofixendofline'* *'nofixeol'*
'fixendofline' 'fixeol' boolean (default on)

View File

@@ -257,10 +257,10 @@ typedef struct {
#define w_p_scl w_onebuf_opt.wo_scl // 'signcolumn'
char *wo_winhl;
#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;
#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;
#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;
} else if (filler_todo > 0) {
// draw "deleted" diff line(s)
// Draw "deleted" diff line(s)
if (char2cells(wp->w_p_fcs_chars.diff) > 1) {
c_extra = '-';
c_final = NUL;

View File

@@ -1920,8 +1920,9 @@ win_update_start:
wp->w_botline = lnum;
}
// make sure the rest of the screen is blank
// write the 'eob' character to rows that aren't part of the file.
// Make sure the rest of the screen is blank.
// 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,
HLF_EOB);
}

View File

@@ -1989,8 +1989,7 @@ theend:
}
/// @return true if string "s" is a valid utf-8 string.
/// When "end" is NULL stop at the first NUL.
/// When "end" is positive stop there.
/// When "end" is NULL stop at the first NUL. Otherwise stop at "end".
bool utf_valid_string(const char_u *s, const char_u *end)
{
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);
}
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.
/// 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.
@@ -4258,21 +4266,23 @@ void copy_winopt(winopt_T *from, winopt_T *to)
{
to->wo_arab = from->wo_arab;
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_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_nuw = from->wo_nuw;
to->wo_rl = from->wo_rl;
to->wo_rlc = xstrdup(from->wo_rlc);
to->wo_sbr = xstrdup(from->wo_sbr);
to->wo_stl = xstrdup(from->wo_stl);
to->wo_wbr = xstrdup(from->wo_wbr);
to->wo_rlc = copy_option_val(from->wo_rlc);
to->wo_sbr = copy_option_val(from->wo_sbr);
to->wo_stl = copy_option_val(from->wo_stl);
to->wo_wbr = copy_option_val(from->wo_wbr);
to->wo_wrap = from->wo_wrap;
to->wo_wrap_save = from->wo_wrap_save;
to->wo_lbr = from->wo_lbr;
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_save = from->wo_scb_save;
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_cuc = from->wo_cuc;
to->wo_cul = from->wo_cul;
to->wo_culopt = xstrdup(from->wo_culopt);
to->wo_cc = xstrdup(from->wo_cc);
to->wo_culopt = copy_option_val(from->wo_culopt);
to->wo_cc = copy_option_val(from->wo_cc);
to->wo_diff = from->wo_diff;
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_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_fen = from->wo_fen;
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_fdl = from->wo_fdl;
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_fdn = from->wo_fdn;
to->wo_fde = xstrdup(from->wo_fde);
to->wo_fdt = xstrdup(from->wo_fdt);
to->wo_fmr = xstrdup(from->wo_fmr);
to->wo_scl = xstrdup(from->wo_scl);
to->wo_winhl = xstrdup(from->wo_winhl);
to->wo_fcs = xstrdup(from->wo_fcs);
to->wo_lcs = xstrdup(from->wo_lcs);
to->wo_fde = copy_option_val(from->wo_fde);
to->wo_fdt = copy_option_val(from->wo_fdt);
to->wo_fmr = copy_option_val(from->wo_fmr);
to->wo_scl = copy_option_val(from->wo_scl);
to->wo_winhl = copy_option_val(from->wo_winhl);
to->wo_winbl = from->wo_winbl;
// 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_briopt);
check_string_option(&wop->wo_winhl);
check_string_option(&wop->wo_fcs);
check_string_option(&wop->wo_lcs);
check_string_option(&wop->wo_fcs);
check_string_option(&wop->wo_ve);
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_briopt);
clear_string_option(&wop->wo_winhl);
clear_string_option(&wop->wo_fcs);
clear_string_option(&wop->wo_lcs);
clear_string_option(&wop->wo_fcs);
clear_string_option(&wop->wo_ve);
clear_string_option(&wop->wo_wbr);
}

View File

@@ -972,8 +972,8 @@ enum {
WV_WRAP,
WV_SCL,
WV_WINHL,
WV_FCS,
WV_LCS,
WV_FCS,
WV_WINBL,
WV_WBR,
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) {
// If no error was returned above, we don't expect an error
// here, so ignore the return value.
if (*wp->w_p_lcs == NUL) {
(void)set_chars_option(wp, (char_u **)&wp->w_p_lcs, true);
}
}
redraw_all_later(UPD_NOT_VALID);
}
} 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) {
// If no error was returned above, we don't expect an error
// here, so ignore the return value.
if (*wp->w_p_fcs == NUL) {
(void)set_chars_option(wp, (char_u **)&wp->w_p_fcs, true);
}
}
redraw_all_later(UPD_NOT_VALID);
}
} 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
let prev_error = ''
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.
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 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)
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')
let v:errors = total_errors
break
@@ -462,7 +462,7 @@ for s:test in sort(s:tests)
let prev_error = v:errors[0]
let v:errors = []
let run_nr += 1
let g:run_nr += 1
call RunTheTest(s:test)

View File

@@ -363,6 +363,34 @@ func Test_fold_fillchars()
set fillchars& fdc& foldmethod& foldenable&
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()
new
vert resize 25