summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-03-04 21:55:58 +0100
committerBram Moolenaar <Bram@vim.org>2021-03-04 21:55:58 +0100
commit008bff967f7fcaa6af066f71d65bfbba5ef5c7d3 (patch)
tree7ea14f1f725326415879039cf4ed6e96e7d81458
parent6057748a1af2260b4ab9630f21fe71f42f91250d (diff)
downloadvim-git-008bff967f7fcaa6af066f71d65bfbba5ef5c7d3.tar.gz
patch 8.2.2569: 'fillchars' "stl" and "stlnc" items must be single bytev8.2.2569
Problem: 'fillchars' "stl" and "stlnc" items must be single byte. Solution: Accept multi-byte characters. (Christian Wellenbrock, Yegappan Lakshmanan, closes #7927)
-rw-r--r--runtime/doc/options.txt3
-rw-r--r--src/buffer.c41
-rw-r--r--src/macros.h1
-rw-r--r--src/screen.c2
-rw-r--r--src/testdir/test_fold.vim61
-rw-r--r--src/testdir/test_statusline.vim15
-rw-r--r--src/version.c2
7 files changed, 101 insertions, 24 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 70746082c..7fcdfbe95 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -3262,7 +3262,8 @@ A jump table for the options with a short description can be found at |Q_op|.
< This is similar to the default, except that these characters will also
be used when there is highlighting.
- for "stl" and "stlnc" only single-byte values are supported.
+ For "stl" and "stlnc" single-byte and multibyte characters are
+ supported. But double-width characters are not supported.
The highlighting used for these items:
item highlight group ~
diff --git a/src/buffer.c b/src/buffer.c
index 4e4f87c92..f80d42494 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -4157,9 +4157,6 @@ build_stl_str_hl(
if (fillchar == 0)
fillchar = ' ';
- // Can't handle a multi-byte fill character yet.
- else if (mb_char2len(fillchar) > 1)
- fillchar = '-';
// The cursor in windows other than the current one isn't always
// up-to-date, esp. because of autocommands and timers.
@@ -4335,7 +4332,7 @@ build_stl_str_hl(
// Fill up space left over by half a double-wide char.
while (++l < stl_items[stl_groupitem[groupdepth]].stl_minwid)
- *p++ = fillchar;
+ MB_CHAR2BYTES(fillchar, p);
// correct the start of the items for the truncation
for (l = stl_groupitem[groupdepth] + 1; l < curitem; l++)
@@ -4354,20 +4351,20 @@ build_stl_str_hl(
// fill by appending characters
n = 0 - n;
while (l++ < n && p + 1 < out + outlen)
- *p++ = fillchar;
+ MB_CHAR2BYTES(fillchar, p);
}
else
{
// fill by inserting characters
- mch_memmove(t + n - l, t, (size_t)(p - t));
- l = n - l;
+ l = (n - l) * MB_CHAR2LEN(fillchar);
+ mch_memmove(t + l, t, (size_t)(p - t));
if (p + l >= out + outlen)
l = (long)((out + outlen) - p - 1);
p += l;
for (n = stl_groupitem[groupdepth] + 1; n < curitem; n++)
stl_items[n].stl_start += l;
for ( ; l > 0; l--)
- *t++ = fillchar;
+ MB_CHAR2BYTES(fillchar, t);
}
}
continue;
@@ -4746,23 +4743,24 @@ build_stl_str_hl(
if (l + 1 == minwid && fillchar == '-' && VIM_ISDIGIT(*t))
*p++ = ' ';
else
- *p++ = fillchar;
+ MB_CHAR2BYTES(fillchar, p);
}
minwid = 0;
}
else
minwid *= -1;
- while (*t && p + 1 < out + outlen)
+ for (; *t && p + 1 < out + outlen; t++)
{
- *p++ = *t++;
// Change a space by fillchar, unless fillchar is '-' and a
// digit follows.
- if (fillable && p[-1] == ' '
- && (!VIM_ISDIGIT(*t) || fillchar != '-'))
- p[-1] = fillchar;
+ if (fillable && *t == ' '
+ && (!VIM_ISDIGIT(*(t + 1)) || fillchar != '-'))
+ MB_CHAR2BYTES(fillchar, p);
+ else
+ *p++ = *t;
}
for (; l < minwid && p + 1 < out + outlen; l++)
- *p++ = fillchar;
+ MB_CHAR2BYTES(fillchar, p);
}
else if (num >= 0)
{
@@ -4865,7 +4863,7 @@ build_stl_str_hl(
}
// Fill up for half a double-wide character.
while (++width < maxwidth)
- *s++ = fillchar;
+ MB_CHAR2BYTES(fillchar, s);
}
else
s = out + maxwidth - 1;
@@ -4897,7 +4895,7 @@ build_stl_str_hl(
while (++width < maxwidth)
{
s = s + STRLEN(s);
- *s++ = fillchar;
+ MB_CHAR2BYTES(fillchar, s);
*s = NUL;
}
@@ -4920,12 +4918,13 @@ build_stl_str_hl(
break;
if (l < itemcnt)
{
- p = stl_items[l].stl_start + maxwidth - width;
+ int middlelength = (maxwidth - width) * MB_CHAR2LEN(fillchar);
+ p = stl_items[l].stl_start + middlelength;
STRMOVE(p, stl_items[l].stl_start);
- for (s = stl_items[l].stl_start; s < p; s++)
- *s = fillchar;
+ for (s = stl_items[l].stl_start; s < p;)
+ MB_CHAR2BYTES(fillchar, s);
for (l++; l < itemcnt; l++)
- stl_items[l].stl_start += maxwidth - width;
+ stl_items[l].stl_start += middlelength;
width = maxwidth;
}
}
diff --git a/src/macros.h b/src/macros.h
index 5a57a8928..c11ee660c 100644
--- a/src/macros.h
+++ b/src/macros.h
@@ -252,6 +252,7 @@
#define MB_CHARLEN(p) (has_mbyte ? mb_charlen(p) : (int)STRLEN(p))
#define MB_CHAR2LEN(c) (has_mbyte ? mb_char2len(c) : 1)
#define PTR2CHAR(p) (has_mbyte ? mb_ptr2char(p) : (int)*(p))
+#define MB_CHAR2BYTES(c, b) do { if (has_mbyte) (b) += (*mb_char2bytes)((c), (b)); else *(b)++ = (c); } while(0)
#ifdef FEAT_AUTOCHDIR
# define DO_AUTOCHDIR do { if (p_acd) do_autochdir(); } while (0)
diff --git a/src/screen.c b/src/screen.c
index ce4ab1146..84951c5cc 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -266,7 +266,7 @@ fill_foldcolumn(
empty = (fdc == 1) ? 0 : 1;
// If the column is too narrow, we start at the lowest level that
- // fits and use numbers to indicated the depth.
+ // fits and use numbers to indicate the depth.
first_level = level - fdc - closed + 1 + empty;
if (first_level < 1)
first_level = 1;
diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim
index 920dcc406..d451b1eb4 100644
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
@@ -987,7 +987,66 @@ func s:mbyte_fillchar_tests(fo, fc, fs)
\ a:fs .. 'six ',
\ ], ScreenLines([1, 6], 7))
- setlocal foldcolumn&
+ " Enable number and sign columns and place some signs
+ setlocal fdc=3
+ setlocal number
+ setlocal signcolumn=auto
+ sign define S1 text=->
+ sign place 10 line=3 name=S1
+ call assert_equal([
+ \ a:fo .. ' 1 one ',
+ \ a:fs .. a:fo .. ' 2 two ',
+ \ '2' .. a:fo .. ' -> 3 three',
+ \ '23 4 four ',
+ \ a:fs .. a:fs .. ' 5 five ',
+ \ a:fs .. ' 6 six '
+ \ ], ScreenLines([1, 6], 14))
+
+ " Test with 'rightleft'
+ if has('rightleft')
+ setlocal rightleft
+ let lines = ScreenLines([1, 6], winwidth(0))
+ call assert_equal('o 1 ' .. a:fo,
+ \ strcharpart(lines[0], strchars(lines[0]) - 10, 10))
+ call assert_equal('t 2 ' .. a:fo .. a:fs,
+ \ strcharpart(lines[1], strchars(lines[1]) - 10, 10))
+ call assert_equal('t 3 >- ' .. a:fo .. '2',
+ \ strcharpart(lines[2], strchars(lines[2]) - 10, 10))
+ call assert_equal('f 4 32',
+ \ strcharpart(lines[3], strchars(lines[3]) - 10, 10))
+ call assert_equal('f 5 ' .. a:fs .. a:fs,
+ \ strcharpart(lines[4], strchars(lines[4]) - 10, 10))
+ call assert_equal('s 6 ' .. a:fs,
+ \ strcharpart(lines[5], strchars(lines[5]) - 10, 10))
+ setlocal norightleft
+ endif
+
+ sign unplace *
+ sign undefine S1
+ setlocal number& signcolumn&
+
+ " Add a test with more than 9 folds (and then delete some folds)
+ normal zE
+ for i in range(1, 10)
+ normal zfGzo
+ endfor
+ normal zR
+ call assert_equal([
+ \ a:fo .. a:fo .. ' one ',
+ \ '9> two '
+ \ ], ScreenLines([1, 2], 7))
+ normal 1Gzd
+ call assert_equal([
+ \ a:fo .. a:fo .. ' one ',
+ \ '89 two '
+ \ ], ScreenLines([1, 2], 7))
+ normal 1Gzdzdzdzdzdzdzd
+ call assert_equal([
+ \ a:fo .. a:fo .. ' one ',
+ \ a:fs .. a:fs .. ' two '
+ \ ], ScreenLines([1, 2], 7))
+
+ setlocal foldcolumn& number& signcolumn&
endfunc
func Test_foldcolumn_multibyte_char()
diff --git a/src/testdir/test_statusline.vim b/src/testdir/test_statusline.vim
index b28dbb953..f6c05f661 100644
--- a/src/testdir/test_statusline.vim
+++ b/src/testdir/test_statusline.vim
@@ -464,5 +464,20 @@ func Test_statusline_after_split_vsplit()
set ls& stl&
endfunc
+" Test using a multibyte character for 'stl' and 'stlnc' items in 'fillchars'
+" with a custom 'statusline'
+func Test_statusline_mbyte_fillchar()
+ only
+ set laststatus=2
+ set fillchars=vert:\|,fold:-,stl:━,stlnc:═
+ set statusline=a%=b
+ call assert_match('^a\+━\+b$', s:get_statusline())
+ vnew
+ call assert_match('^a\+━\+b━a\+═\+b$', s:get_statusline())
+ wincmd w
+ call assert_match('^a\+═\+b═a\+━\+b$', s:get_statusline())
+ set statusline& fillchars& laststatus&
+ %bw!
+endfunc
" vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index da9328c69..ffedb4fdf 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,6 +751,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2569,
+/**/
2568,
/**/
2567,