summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2021-02-03 15:58:13 +0100
committerBram Moolenaar <Bram@vim.org>2021-02-03 15:58:13 +0100
commit91478ae49a1b2dc1de63821db731a343e855dcc0 (patch)
tree1712c04276688e7664769ca084a5f9a4f76d7ac4 /src
parent148be9bc1cca16ce47ad21563f5835682001f9a2 (diff)
patch 8.2.2454: leading space can not be made visiblev8.2.2454
Problem: Leading space can not be made visible. Solution: Add "lead:" to 'listchars'. (closes #7772)
Diffstat (limited to 'src')
-rw-r--r--src/drawline.c23
-rw-r--r--src/globals.h1
-rw-r--r--src/message.c29
-rw-r--r--src/screen.c1
-rw-r--r--src/testdir/test_listchars.vim29
-rw-r--r--src/version.c2
6 files changed, 77 insertions, 8 deletions
diff --git a/src/drawline.c b/src/drawline.c
index d51b4c2d66..4dde0d0740 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -339,6 +339,7 @@ win_line(
int change_end = -1; // last col of changed area
#endif
colnr_T trailcol = MAXCOL; // start of trailing spaces
+ colnr_T leadcol = 0; // start of leading spaces
#ifdef FEAT_LINEBREAK
int need_showbreak = FALSE; // overlong line, skipping first x
// chars
@@ -734,8 +735,9 @@ win_line(
if (wp->w_p_list)
{
- if (lcs_space || lcs_trail || lcs_nbsp)
+ if (lcs_space || lcs_trail || lcs_lead || lcs_nbsp)
extra_check = TRUE;
+
// find start of trailing whitespace
if (lcs_trail)
{
@@ -744,6 +746,19 @@ win_line(
--trailcol;
trailcol += (colnr_T) (ptr - line);
}
+ // find end of leading whitespace
+ if (lcs_lead)
+ {
+ leadcol = 0;
+ while (VIM_ISWHITE(ptr[leadcol]))
+ ++leadcol;
+ if (ptr[leadcol] == NUL)
+ // in a line full of spaces all of them are treated as trailing
+ leadcol = (colnr_T)0;
+ else
+ // keep track of the first column not filled with spaces
+ leadcol += (colnr_T) (ptr - line) + 1;
+ }
}
wcr_attr = get_wcr_attr(wp);
@@ -1992,6 +2007,7 @@ win_line(
|| (c == ' '
&& mb_l == 1
&& lcs_space
+ && ptr - line >= leadcol
&& ptr - line <= trailcol)))
{
c = (c == ' ') ? lcs_space : lcs_nbsp;
@@ -2012,9 +2028,10 @@ win_line(
mb_utf8 = FALSE;
}
- if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ')
+ if ((trailcol != MAXCOL && ptr > line + trailcol && c == ' ')
+ || (leadcol != 0 && ptr < line + leadcol && c == ' '))
{
- c = lcs_trail;
+ c = (ptr > line + trailcol) ? lcs_trail : lcs_lead;
if (!attr_pri)
{
n_attr = 1;
diff --git a/src/globals.h b/src/globals.h
index e601fd6c45..4daa092173 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -1352,6 +1352,7 @@ EXTERN int lcs_tab1 INIT(= NUL);
EXTERN int lcs_tab2 INIT(= NUL);
EXTERN int lcs_tab3 INIT(= NUL);
EXTERN int lcs_trail INIT(= NUL);
+EXTERN int lcs_lead INIT(= NUL);
#ifdef FEAT_CONCEAL
EXTERN int lcs_conceal INIT(= ' ');
#endif
diff --git a/src/message.c b/src/message.c
index e4f96d0de7..8adc224115 100644
--- a/src/message.c
+++ b/src/message.c
@@ -1831,18 +1831,32 @@ msg_prt_line(char_u *s, int list)
int n;
int attr = 0;
char_u *trail = NULL;
+ char_u *lead = NULL;
int l;
char_u buf[MB_MAXBYTES + 1];
if (curwin->w_p_list)
list = TRUE;
- // find start of trailing whitespace
- if (list && lcs_trail)
+ if (list)
{
- trail = s + STRLEN(s);
- while (trail > s && VIM_ISWHITE(trail[-1]))
- --trail;
+ // find start of trailing whitespace
+ if (lcs_trail)
+ {
+ trail = s + STRLEN(s);
+ while (trail > s && VIM_ISWHITE(trail[-1]))
+ --trail;
+ }
+ // find end of leading whitespace
+ if (lcs_lead)
+ {
+ lead = s;
+ while (VIM_ISWHITE(lead[0]))
+ lead++;
+ // in a line full of spaces all of them are treated as trailing
+ if (*lead == NUL)
+ lead = NULL;
+ }
}
// output a space for an empty line, otherwise the line will be
@@ -1938,6 +1952,11 @@ msg_prt_line(char_u *s, int list)
// the same in plain text.
attr = HL_ATTR(HLF_8);
}
+ else if (c == ' ' && lead != NULL && s <= lead)
+ {
+ c = lcs_lead;
+ attr = HL_ATTR(HLF_8);
+ }
else if (c == ' ' && trail != NULL && s > trail)
{
c = lcs_trail;
diff --git a/src/screen.c b/src/screen.c
index 60544b6e96..cd727edb82 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -4775,6 +4775,7 @@ set_chars_option(char_u **varp)
{&lcs_space, "space"},
{&lcs_tab2, "tab"},
{&lcs_trail, "trail"},
+ {&lcs_lead, "lead"},
#ifdef FEAT_CONCEAL
{&lcs_conceal, "conceal"},
#else
diff --git a/src/testdir/test_listchars.vim b/src/testdir/test_listchars.vim
index d7658bf605..69c98b9269 100644
--- a/src/testdir/test_listchars.vim
+++ b/src/testdir/test_listchars.vim
@@ -110,6 +110,35 @@ func Test_listchars()
\ '.....h>-$',
\ 'iii<<<<><<$', '$'], l)
+ " Test lead and trail
+ normal ggdG
+ set listchars&
+ set listchars+=lead:>,trail:<,space:x
+ set list
+
+ call append(0, [
+ \ ' ffff ',
+ \ ' gg',
+ \ 'h ',
+ \ ' ',
+ \ ' 0 0 ',
+ \ ])
+
+ let expected = [
+ \ '>>>>ffff<<<<$',
+ \ '>>>>>>>>>>gg$',
+ \ 'h<<<<<<<<<<<$',
+ \ '<<<<<<<<<<<<$',
+ \ '>>>>0xx0<<<<$',
+ \ '$'
+ \ ]
+ redraw!
+ for i in range(1, 5)
+ call cursor(i, 1)
+ call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+ endfor
+
+ call assert_equal(expected, split(execute("%list"), "\n"))
" test nbsp
normal ggdG
diff --git a/src/version.c b/src/version.c
index 679f3a57eb..9eb0f5d5b4 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 */
/**/
+ 2454,
+/**/
2453,
/**/
2452,