1
0
forked from aniani/vim

patch 8.2.2454: leading space can not be made visible

Problem:    Leading space can not be made visible.
Solution:   Add "lead:" to 'listchars'. (closes #7772)
This commit is contained in:
Bram Moolenaar
2021-02-03 15:58:13 +01:00
parent 148be9bc1c
commit 91478ae49a
7 changed files with 81 additions and 8 deletions

View File

@@ -4877,6 +4877,10 @@ A jump table for the options with a short description can be found at |Q_op|.
*lcs-space* *lcs-space*
space:c Character to show for a space. When omitted, spaces space:c Character to show for a space. When omitted, spaces
are left blank. are left blank.
*lcs-lead*
lead:c Character to show for leading spaces. When omitted,
leading spaces are blank. Overrides the "space"
setting for leading spaces.
*lcs-trail* *lcs-trail*
trail:c Character to show for trailing spaces. When omitted, trail:c Character to show for trailing spaces. When omitted,
trailing spaces are blank. Overrides the "space" trailing spaces are blank. Overrides the "space"

View File

@@ -339,6 +339,7 @@ win_line(
int change_end = -1; // last col of changed area int change_end = -1; // last col of changed area
#endif #endif
colnr_T trailcol = MAXCOL; // start of trailing spaces colnr_T trailcol = MAXCOL; // start of trailing spaces
colnr_T leadcol = 0; // start of leading spaces
#ifdef FEAT_LINEBREAK #ifdef FEAT_LINEBREAK
int need_showbreak = FALSE; // overlong line, skipping first x int need_showbreak = FALSE; // overlong line, skipping first x
// chars // chars
@@ -734,8 +735,9 @@ win_line(
if (wp->w_p_list) if (wp->w_p_list)
{ {
if (lcs_space || lcs_trail || lcs_nbsp) if (lcs_space || lcs_trail || lcs_lead || lcs_nbsp)
extra_check = TRUE; extra_check = TRUE;
// find start of trailing whitespace // find start of trailing whitespace
if (lcs_trail) if (lcs_trail)
{ {
@@ -744,6 +746,19 @@ win_line(
--trailcol; --trailcol;
trailcol += (colnr_T) (ptr - line); 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); wcr_attr = get_wcr_attr(wp);
@@ -1992,6 +2007,7 @@ win_line(
|| (c == ' ' || (c == ' '
&& mb_l == 1 && mb_l == 1
&& lcs_space && lcs_space
&& ptr - line >= leadcol
&& ptr - line <= trailcol))) && ptr - line <= trailcol)))
{ {
c = (c == ' ') ? lcs_space : lcs_nbsp; c = (c == ' ') ? lcs_space : lcs_nbsp;
@@ -2012,9 +2028,10 @@ win_line(
mb_utf8 = FALSE; 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) if (!attr_pri)
{ {
n_attr = 1; n_attr = 1;

View File

@@ -1352,6 +1352,7 @@ EXTERN int lcs_tab1 INIT(= NUL);
EXTERN int lcs_tab2 INIT(= NUL); EXTERN int lcs_tab2 INIT(= NUL);
EXTERN int lcs_tab3 INIT(= NUL); EXTERN int lcs_tab3 INIT(= NUL);
EXTERN int lcs_trail INIT(= NUL); EXTERN int lcs_trail INIT(= NUL);
EXTERN int lcs_lead INIT(= NUL);
#ifdef FEAT_CONCEAL #ifdef FEAT_CONCEAL
EXTERN int lcs_conceal INIT(= ' '); EXTERN int lcs_conceal INIT(= ' ');
#endif #endif

View File

@@ -1831,18 +1831,32 @@ msg_prt_line(char_u *s, int list)
int n; int n;
int attr = 0; int attr = 0;
char_u *trail = NULL; char_u *trail = NULL;
char_u *lead = NULL;
int l; int l;
char_u buf[MB_MAXBYTES + 1]; char_u buf[MB_MAXBYTES + 1];
if (curwin->w_p_list) if (curwin->w_p_list)
list = TRUE; list = TRUE;
// find start of trailing whitespace if (list)
if (list && lcs_trail)
{ {
trail = s + STRLEN(s); // find start of trailing whitespace
while (trail > s && VIM_ISWHITE(trail[-1])) if (lcs_trail)
--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 // 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. // the same in plain text.
attr = HL_ATTR(HLF_8); 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) else if (c == ' ' && trail != NULL && s > trail)
{ {
c = lcs_trail; c = lcs_trail;

View File

@@ -4775,6 +4775,7 @@ set_chars_option(char_u **varp)
{&lcs_space, "space"}, {&lcs_space, "space"},
{&lcs_tab2, "tab"}, {&lcs_tab2, "tab"},
{&lcs_trail, "trail"}, {&lcs_trail, "trail"},
{&lcs_lead, "lead"},
#ifdef FEAT_CONCEAL #ifdef FEAT_CONCEAL
{&lcs_conceal, "conceal"}, {&lcs_conceal, "conceal"},
#else #else

View File

@@ -110,6 +110,35 @@ func Test_listchars()
\ '.....h>-$', \ '.....h>-$',
\ 'iii<<<<><<$', '$'], l) \ '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 " test nbsp
normal ggdG normal ggdG

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2454,
/**/ /**/
2453, 2453,
/**/ /**/