Skip to content

Commit 008bff9

Browse files
committed
patch 8.2.2569: 'fillchars' "stl" and "stlnc" items must be single byte
Problem: 'fillchars' "stl" and "stlnc" items must be single byte. Solution: Accept multi-byte characters. (Christian Wellenbrock, Yegappan Lakshmanan, closes #7927)
1 parent 6057748 commit 008bff9

File tree

7 files changed

+101
-24
lines changed

7 files changed

+101
-24
lines changed

runtime/doc/options.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3262,7 +3262,8 @@ A jump table for the options with a short description can be found at |Q_op|.
32623262
< This is similar to the default, except that these characters will also
32633263
be used when there is highlighting.
32643264

3265-
for "stl" and "stlnc" only single-byte values are supported.
3265+
For "stl" and "stlnc" single-byte and multibyte characters are
3266+
supported. But double-width characters are not supported.
32663267

32673268
The highlighting used for these items:
32683269
item highlight group ~

src/buffer.c

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4157,9 +4157,6 @@ build_stl_str_hl(
41574157

41584158
if (fillchar == 0)
41594159
fillchar = ' ';
4160-
// Can't handle a multi-byte fill character yet.
4161-
else if (mb_char2len(fillchar) > 1)
4162-
fillchar = '-';
41634160

41644161
// The cursor in windows other than the current one isn't always
41654162
// up-to-date, esp. because of autocommands and timers.
@@ -4335,7 +4332,7 @@ build_stl_str_hl(
43354332

43364333
// Fill up space left over by half a double-wide char.
43374334
while (++l < stl_items[stl_groupitem[groupdepth]].stl_minwid)
4338-
*p++ = fillchar;
4335+
MB_CHAR2BYTES(fillchar, p);
43394336

43404337
// correct the start of the items for the truncation
43414338
for (l = stl_groupitem[groupdepth] + 1; l < curitem; l++)
@@ -4354,20 +4351,20 @@ build_stl_str_hl(
43544351
// fill by appending characters
43554352
n = 0 - n;
43564353
while (l++ < n && p + 1 < out + outlen)
4357-
*p++ = fillchar;
4354+
MB_CHAR2BYTES(fillchar, p);
43584355
}
43594356
else
43604357
{
43614358
// fill by inserting characters
4362-
mch_memmove(t + n - l, t, (size_t)(p - t));
4363-
l = n - l;
4359+
l = (n - l) * MB_CHAR2LEN(fillchar);
4360+
mch_memmove(t + l, t, (size_t)(p - t));
43644361
if (p + l >= out + outlen)
43654362
l = (long)((out + outlen) - p - 1);
43664363
p += l;
43674364
for (n = stl_groupitem[groupdepth] + 1; n < curitem; n++)
43684365
stl_items[n].stl_start += l;
43694366
for ( ; l > 0; l--)
4370-
*t++ = fillchar;
4367+
MB_CHAR2BYTES(fillchar, t);
43714368
}
43724369
}
43734370
continue;
@@ -4746,23 +4743,24 @@ build_stl_str_hl(
47464743
if (l + 1 == minwid && fillchar == '-' && VIM_ISDIGIT(*t))
47474744
*p++ = ' ';
47484745
else
4749-
*p++ = fillchar;
4746+
MB_CHAR2BYTES(fillchar, p);
47504747
}
47514748
minwid = 0;
47524749
}
47534750
else
47544751
minwid *= -1;
4755-
while (*t && p + 1 < out + outlen)
4752+
for (; *t && p + 1 < out + outlen; t++)
47564753
{
4757-
*p++ = *t++;
47584754
// Change a space by fillchar, unless fillchar is '-' and a
47594755
// digit follows.
4760-
if (fillable && p[-1] == ' '
4761-
&& (!VIM_ISDIGIT(*t) || fillchar != '-'))
4762-
p[-1] = fillchar;
4756+
if (fillable && *t == ' '
4757+
&& (!VIM_ISDIGIT(*(t + 1)) || fillchar != '-'))
4758+
MB_CHAR2BYTES(fillchar, p);
4759+
else
4760+
*p++ = *t;
47634761
}
47644762
for (; l < minwid && p + 1 < out + outlen; l++)
4765-
*p++ = fillchar;
4763+
MB_CHAR2BYTES(fillchar, p);
47664764
}
47674765
else if (num >= 0)
47684766
{
@@ -4865,7 +4863,7 @@ build_stl_str_hl(
48654863
}
48664864
// Fill up for half a double-wide character.
48674865
while (++width < maxwidth)
4868-
*s++ = fillchar;
4866+
MB_CHAR2BYTES(fillchar, s);
48694867
}
48704868
else
48714869
s = out + maxwidth - 1;
@@ -4897,7 +4895,7 @@ build_stl_str_hl(
48974895
while (++width < maxwidth)
48984896
{
48994897
s = s + STRLEN(s);
4900-
*s++ = fillchar;
4898+
MB_CHAR2BYTES(fillchar, s);
49014899
*s = NUL;
49024900
}
49034901

@@ -4920,12 +4918,13 @@ build_stl_str_hl(
49204918
break;
49214919
if (l < itemcnt)
49224920
{
4923-
p = stl_items[l].stl_start + maxwidth - width;
4921+
int middlelength = (maxwidth - width) * MB_CHAR2LEN(fillchar);
4922+
p = stl_items[l].stl_start + middlelength;
49244923
STRMOVE(p, stl_items[l].stl_start);
4925-
for (s = stl_items[l].stl_start; s < p; s++)
4926-
*s = fillchar;
4924+
for (s = stl_items[l].stl_start; s < p;)
4925+
MB_CHAR2BYTES(fillchar, s);
49274926
for (l++; l < itemcnt; l++)
4928-
stl_items[l].stl_start += maxwidth - width;
4927+
stl_items[l].stl_start += middlelength;
49294928
width = maxwidth;
49304929
}
49314930
}

src/macros.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,7 @@
252252
#define MB_CHARLEN(p) (has_mbyte ? mb_charlen(p) : (int)STRLEN(p))
253253
#define MB_CHAR2LEN(c) (has_mbyte ? mb_char2len(c) : 1)
254254
#define PTR2CHAR(p) (has_mbyte ? mb_ptr2char(p) : (int)*(p))
255+
#define MB_CHAR2BYTES(c, b) do { if (has_mbyte) (b) += (*mb_char2bytes)((c), (b)); else *(b)++ = (c); } while(0)
255256

256257
#ifdef FEAT_AUTOCHDIR
257258
# define DO_AUTOCHDIR do { if (p_acd) do_autochdir(); } while (0)

src/screen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ fill_foldcolumn(
266266
empty = (fdc == 1) ? 0 : 1;
267267

268268
// If the column is too narrow, we start at the lowest level that
269-
// fits and use numbers to indicated the depth.
269+
// fits and use numbers to indicate the depth.
270270
first_level = level - fdc - closed + 1 + empty;
271271
if (first_level < 1)
272272
first_level = 1;

src/testdir/test_fold.vim

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -987,7 +987,66 @@ func s:mbyte_fillchar_tests(fo, fc, fs)
987987
\ a:fs .. 'six ',
988988
\ ], ScreenLines([1, 6], 7))
989989

990-
setlocal foldcolumn&
990+
" Enable number and sign columns and place some signs
991+
setlocal fdc=3
992+
setlocal number
993+
setlocal signcolumn=auto
994+
sign define S1 text=->
995+
sign place 10 line=3 name=S1
996+
call assert_equal([
997+
\ a:fo .. ' 1 one ',
998+
\ a:fs .. a:fo .. ' 2 two ',
999+
\ '2' .. a:fo .. ' -> 3 three',
1000+
\ '23 4 four ',
1001+
\ a:fs .. a:fs .. ' 5 five ',
1002+
\ a:fs .. ' 6 six '
1003+
\ ], ScreenLines([1, 6], 14))
1004+
1005+
" Test with 'rightleft'
1006+
if has('rightleft')
1007+
setlocal rightleft
1008+
let lines = ScreenLines([1, 6], winwidth(0))
1009+
call assert_equal('o 1 ' .. a:fo,
1010+
\ strcharpart(lines[0], strchars(lines[0]) - 10, 10))
1011+
call assert_equal('t 2 ' .. a:fo .. a:fs,
1012+
\ strcharpart(lines[1], strchars(lines[1]) - 10, 10))
1013+
call assert_equal('t 3 >- ' .. a:fo .. '2',
1014+
\ strcharpart(lines[2], strchars(lines[2]) - 10, 10))
1015+
call assert_equal('f 4 32',
1016+
\ strcharpart(lines[3], strchars(lines[3]) - 10, 10))
1017+
call assert_equal('f 5 ' .. a:fs .. a:fs,
1018+
\ strcharpart(lines[4], strchars(lines[4]) - 10, 10))
1019+
call assert_equal('s 6 ' .. a:fs,
1020+
\ strcharpart(lines[5], strchars(lines[5]) - 10, 10))
1021+
setlocal norightleft
1022+
endif
1023+
1024+
sign unplace *
1025+
sign undefine S1
1026+
setlocal number& signcolumn&
1027+
1028+
" Add a test with more than 9 folds (and then delete some folds)
1029+
normal zE
1030+
for i in range(1, 10)
1031+
normal zfGzo
1032+
endfor
1033+
normal zR
1034+
call assert_equal([
1035+
\ a:fo .. a:fo .. ' one ',
1036+
\ '9> two '
1037+
\ ], ScreenLines([1, 2], 7))
1038+
normal 1Gzd
1039+
call assert_equal([
1040+
\ a:fo .. a:fo .. ' one ',
1041+
\ '89 two '
1042+
\ ], ScreenLines([1, 2], 7))
1043+
normal 1Gzdzdzdzdzdzdzd
1044+
call assert_equal([
1045+
\ a:fo .. a:fo .. ' one ',
1046+
\ a:fs .. a:fs .. ' two '
1047+
\ ], ScreenLines([1, 2], 7))
1048+
1049+
setlocal foldcolumn& number& signcolumn&
9911050
endfunc
9921051

9931052
func Test_foldcolumn_multibyte_char()

src/testdir/test_statusline.vim

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,5 +464,20 @@ func Test_statusline_after_split_vsplit()
464464
set ls& stl&
465465
endfunc
466466

467+
" Test using a multibyte character for 'stl' and 'stlnc' items in 'fillchars'
468+
" with a custom 'statusline'
469+
func Test_statusline_mbyte_fillchar()
470+
only
471+
set laststatus=2
472+
set fillchars=vert:\|,fold:-,stl:━,stlnc:═
473+
set statusline=a%=b
474+
call assert_match('^a\+━\+b$', s:get_statusline())
475+
vnew
476+
call assert_match('^a\+━\+b━a\+═\+b$', s:get_statusline())
477+
wincmd w
478+
call assert_match('^a\+═\+b═a\+━\+b$', s:get_statusline())
479+
set statusline& fillchars& laststatus&
480+
%bw!
481+
endfunc
467482

468483
" vim: shiftwidth=2 sts=2 expandtab

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
2569,
753755
/**/
754756
2568,
755757
/**/

0 commit comments

Comments
 (0)