]> granicus.if.org Git - vim/commitdiff
patch 8.2.2454: leading space can not be made visible v8.2.2454
authorBram Moolenaar <Bram@vim.org>
Wed, 3 Feb 2021 14:58:13 +0000 (15:58 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 3 Feb 2021 14:58:13 +0000 (15:58 +0100)
Problem:    Leading space can not be made visible.
Solution:   Add "lead:" to 'listchars'. (closes #7772)

runtime/doc/options.txt
src/drawline.c
src/globals.h
src/message.c
src/screen.c
src/testdir/test_listchars.vim
src/version.c

index 8b655dc600c92e69790e5d3c99e867ca991bd971..74bab429c5bbd554331c315c227abf6351ef40d5 100644 (file)
@@ -4877,6 +4877,10 @@ A jump table for the options with a short description can be found at |Q_op|.
                                                        *lcs-space*
          space:c       Character to show for a space.  When omitted, spaces
                        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*
          trail:c       Character to show for trailing spaces.  When omitted,
                        trailing spaces are blank.  Overrides the "space"
index d51b4c2d66e403790c2d5dff3cc8a3f875d990d8..4dde0d074039d479af3af4bc8768a39a216702a3 100644 (file)
@@ -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;
index e601fd6c4572c1f6d028761628c1b608b45a2cf4..4daa0921739886f3e5173b063ff8331ca053945c 100644 (file)
@@ -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
index e4f96d0de731bdd99238f58765ec3534428fcf7d..8adc224115ecaedb6a7c70847b0ad58dc94c0f07 100644 (file)
@@ -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;
index 60544b6e9663581a5ecd30607e35eabe76464727..cd727edb825dc6989c3e5fbb1c4086db44cdc4bc 100644 (file)
@@ -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
index d7658bf60506b5938d0fb2be4481d314531071a4..69c98b9269685530e51077216d3bd6b921db04f0 100644 (file)
@@ -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
index 679f3a57ebf8dd168544ff9f5eb2cdb27f9896da..9eb0f5d5b48cf289b310e54e2a51fb39b1663c99 100644 (file)
@@ -750,6 +750,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2454,
 /**/
     2453,
 /**/