Patch 8.2.2454
Problem:    Leading space can not be made visible.
Solution:   Add "lead:" to 'listchars'. (closes #7772)
Files:      runtime/doc/options.txt, src/drawline.c, src/globals.h,
            src/message.c, src/screen.c, src/testdir/test_listchars.vim


*** ../vim-8.2.2453/runtime/doc/options.txt     2021-01-31 17:02:06.258490157 
+0100
--- runtime/doc/options.txt     2021-02-03 15:43:53.943532784 +0100
***************
*** 4877,4882 ****
--- 4877,4886 ----
                                                        *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"
*** ../vim-8.2.2453/src/drawline.c      2020-11-25 13:48:58.880233814 +0100
--- src/drawline.c      2021-02-03 15:55:35.353214762 +0100
***************
*** 339,344 ****
--- 339,345 ----
      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,741 ****
  
      if (wp->w_p_list)
      {
!       if (lcs_space || lcs_trail || lcs_nbsp)
            extra_check = TRUE;
        // find start of trailing whitespace
        if (lcs_trail)
        {
--- 735,743 ----
  
      if (wp->w_p_list)
      {
!       if (lcs_space || lcs_trail || lcs_lead || lcs_nbsp)
            extra_check = TRUE;
+ 
        // find start of trailing whitespace
        if (lcs_trail)
        {
***************
*** 744,749 ****
--- 746,764 ----
                --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,1997 ****
--- 2007,2013 ----
                            || (c == ' '
                                && mb_l == 1
                                && lcs_space
+                               && ptr - line >= leadcol
                                && ptr - line <= trailcol)))
                {
                    c = (c == ' ') ? lcs_space : lcs_nbsp;
***************
*** 2012,2020 ****
                        mb_utf8 = FALSE;
                }
  
!               if (trailcol != MAXCOL && ptr > line + trailcol && c == ' ')
                {
!                   c = lcs_trail;
                    if (!attr_pri)
                    {
                        n_attr = 1;
--- 2028,2037 ----
                        mb_utf8 = FALSE;
                }
  
!               if ((trailcol != MAXCOL && ptr > line + trailcol && c == ' ')
!                       || (leadcol != 0 && ptr < line + leadcol && c == ' '))
                {
!                   c = (ptr > line + trailcol) ? lcs_trail : lcs_lead;
                    if (!attr_pri)
                    {
                        n_attr = 1;
*** ../vim-8.2.2453/src/globals.h       2021-01-12 21:22:27.667588992 +0100
--- src/globals.h       2021-02-03 15:43:53.947532772 +0100
***************
*** 1352,1357 ****
--- 1352,1358 ----
  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
*** ../vim-8.2.2453/src/message.c       2020-12-05 21:22:03.626811733 +0100
--- src/message.c       2021-02-03 15:56:34.697012894 +0100
***************
*** 1831,1848 ****
      int               n;
      int               attr = 0;
      char_u    *trail = 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)
      {
!       trail = s + STRLEN(s);
!       while (trail > s && VIM_ISWHITE(trail[-1]))
!           --trail;
      }
  
      // output a space for an empty line, otherwise the line will be
--- 1831,1862 ----
      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;
  
!     if (list)
      {
!       // 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,1943 ****
--- 1952,1962 ----
                // 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;
*** ../vim-8.2.2453/src/screen.c        2021-01-02 16:53:08.294010035 +0100
--- src/screen.c        2021-02-03 15:43:53.947532772 +0100
***************
*** 4775,4780 ****
--- 4775,4781 ----
        {&lcs_space,    "space"},
        {&lcs_tab2,     "tab"},
        {&lcs_trail,    "trail"},
+       {&lcs_lead,     "lead"},
  #ifdef FEAT_CONCEAL
        {&lcs_conceal,  "conceal"},
  #else
*** ../vim-8.2.2453/src/testdir/test_listchars.vim      2020-08-12 
18:50:31.879655802 +0200
--- src/testdir/test_listchars.vim      2021-02-03 15:43:53.947532772 +0100
***************
*** 110,115 ****
--- 110,144 ----
              \ '.....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
*** ../vim-8.2.2453/src/version.c       2021-02-02 21:33:48.074488746 +0100
--- src/version.c       2021-02-03 15:45:23.291247797 +0100
***************
*** 752,753 ****
--- 752,755 ----
  {   /* Add new patch number below this line */
+ /**/
+     2454,
  /**/

-- 
The psychic said, "God bless you."  I said, "I didn't sneeze."  She
looked deep into my eyes and said, "You will, eventually."  And, damn
if she wasn't right.  Two days later, I sneezed.  --Ellen Degeneres

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/202102031458.113EwnkV1792571%40masaka.moolenaar.net.

Raspunde prin e-mail lui