aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-08-26 08:25:36 +0800
committerzeertzjq <zeertzjq@outlook.com>2022-08-26 10:14:59 +0800
commitfa1c761d62667c28e4d3a81f379abeddb878f3cd (patch)
tree49b4a1025bed19a5948b7afefe300a4aabd0842e
parent1ba3d5c712dcc2e2ee35c6bc27d9965f671f967a (diff)
downloadrneovim-fa1c761d62667c28e4d3a81f379abeddb878f3cd.tar.gz
rneovim-fa1c761d62667c28e4d3a81f379abeddb878f3cd.tar.bz2
rneovim-fa1c761d62667c28e4d3a81f379abeddb878f3cd.zip
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) https://github.com/vim/vim/commit/96ba25ac01279f73c0ecb5d4aa4ff37aa359e5eb 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. https://github.com/vim/vim/commit/510f03738dfcadfe2099c5b6a58cb75f64dbaa82
-rw-r--r--runtime/doc/options.txt66
-rw-r--r--src/nvim/buffer_defs.h4
-rw-r--r--src/nvim/drawline.c2
-rw-r--r--src/nvim/drawscreen.c5
-rw-r--r--src/nvim/mbyte.c3
-rw-r--r--src/nvim/option.c50
-rw-r--r--src/nvim/option_defs.h2
-rw-r--r--src/nvim/optionstr.c8
-rw-r--r--src/nvim/testdir/runtest.vim8
-rw-r--r--src/nvim/testdir/test_display.vim28
10 files changed, 109 insertions, 67 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 2e0c1f8cc4..164e09ccce 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -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)
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index d7d680b0fd..c0d7f8d066 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -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'
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
index f1a808e2bc..22b0f26a1c 100644
--- a/src/nvim/drawline.c
+++ b/src/nvim/drawline.c
@@ -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;
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index 012c4ecb19..cf8178a30f 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -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);
}
diff --git a/src/nvim/mbyte.c b/src/nvim/mbyte.c
index 83044f209a..ad8718742f 100644
--- a/src/nvim/mbyte.c
+++ b/src/nvim/mbyte.c
@@ -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;
diff --git a/src/nvim/option.c b/src/nvim/option.c
index b2525b73a0..6912f93daa 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -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);
}
diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h
index ad8092add2..f9848cb792 100644
--- a/src/nvim/option_defs.h
+++ b/src/nvim/option_defs.h
@@ -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
diff --git a/src/nvim/optionstr.c b/src/nvim/optionstr.c
index e1538e0491..e6847c3ea5 100644
--- a/src/nvim/optionstr.c
+++ b/src/nvim/optionstr.c
@@ -960,7 +960,9 @@ 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.
- (void)set_chars_option(wp, (char_u **)&wp->w_p_lcs, true);
+ if (*wp->w_p_lcs == NUL) {
+ (void)set_chars_option(wp, (char_u **)&wp->w_p_lcs, true);
+ }
}
redraw_all_later(UPD_NOT_VALID);
}
@@ -977,7 +979,9 @@ 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.
- (void)set_chars_option(wp, (char_u **)&wp->w_p_fcs, true);
+ if (*wp->w_p_fcs == NUL) {
+ (void)set_chars_option(wp, (char_u **)&wp->w_p_fcs, true);
+ }
}
redraw_all_later(UPD_NOT_VALID);
}
diff --git a/src/nvim/testdir/runtest.vim b/src/nvim/testdir/runtest.vim
index 206f335751..ce23141c7a 100644
--- a/src/nvim/testdir/runtest.vim
+++ b/src/nvim/testdir/runtest.vim
@@ -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)
diff --git a/src/nvim/testdir/test_display.vim b/src/nvim/testdir/test_display.vim
index a30d57016a..217bb5d781 100644
--- a/src/nvim/testdir/test_display.vim
+++ b/src/nvim/testdir/test_display.vim
@@ -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