patch 9.2.0102: 'listchars' "leadtab" not used in :list

Commit: 
https://github.com/vim/vim/commit/5845741d69655a731288ab105c8fd9fe46e12df9
Author: zeertzjq <[email protected]>
Date:   Tue Mar 3 20:08:12 2026 +0000

    patch 9.2.0102: 'listchars' "leadtab" not used in :list
    
    Problem:  'listchars' "leadtab" not used in :list (after 9.2.0088).
    Solution: Also check for "leadtab" when using :list. Fix memory leak on
              E1572 if "multispace" or "leadmultispace" is set (zeertzjq).
    
    closes: #19557
    
    Signed-off-by: zeertzjq <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/message.c b/src/message.c
index 78e5f3073..85beaa7c7 100644
--- a/src/message.c
+++ b/src/message.c
@@ -2066,7 +2066,8 @@ msg_prt_line(char_u *s, int list)
        }
        // find end of leading whitespace
        if (curwin->w_lcs_chars.lead
-                                || curwin->w_lcs_chars.leadmultispace != NULL)
+                                || curwin->w_lcs_chars.leadmultispace != NULL
+                                || curwin->w_lcs_chars.leadtab1 != NUL)
        {
            lead = s;
            while (VIM_ISWHITE(lead[0]))
@@ -2146,11 +2147,22 @@ msg_prt_line(char_u *s, int list)
                }
                else
                {
-                   c = (n_extra == 0 && curwin->w_lcs_chars.tab3)
-                                               ? curwin->w_lcs_chars.tab3
-                                               : curwin->w_lcs_chars.tab1;
-                   c_extra = curwin->w_lcs_chars.tab2;
-                   c_final = curwin->w_lcs_chars.tab3;
+                   int lcs_tab1 = curwin->w_lcs_chars.tab1;
+                   int lcs_tab2 = curwin->w_lcs_chars.tab2;
+                   int lcs_tab3 = curwin->w_lcs_chars.tab3;
+
+                   // check if leadtab is set in 'listchars'
+                   if (lead != NULL && s <= lead
+                                       && curwin->w_lcs_chars.leadtab1 != NUL)
+                   {
+                       lcs_tab1 = curwin->w_lcs_chars.leadtab1;
+                       lcs_tab2 = curwin->w_lcs_chars.leadtab2;
+                       lcs_tab3 = curwin->w_lcs_chars.leadtab3;
+                   }
+
+                   c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
+                   c_extra = lcs_tab2;
+                   c_final = lcs_tab3;
                    attr = HL_ATTR(HLF_8);
                }
            }
diff --git a/src/screen.c b/src/screen.c
index 6a062ca26..1fb9a70aa 100644
--- a/src/screen.c
+++ b/src/screen.c
@@ -5080,6 +5080,8 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
     // first round: check for valid value, second round: assign values
     for (round = 0; round <= (apply ? 1 : 0); ++round)
     {
+       int has_tab = FALSE, has_leadtab = FALSE;
+
        if (round > 0)
        {
            // After checking that the value is valid: set defaults.
@@ -5247,6 +5249,10 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
                                         e_wrong_character_width_for_field_str,
                                         tab[i].name.string);
                    }
+                   if (tab[i].cp == &lcs_chars.tab2)
+                       has_tab = TRUE;
+                   else  // tab[i].cp == &lcs_chars.leadtab2
+                       has_leadtab = TRUE;
                }
 
                if (*s == ',' || *s == NUL)
@@ -5283,10 +5289,10 @@ set_chars_option(win_T *wp, char_u *value, int 
is_listchars, int apply,
            if (*p == ',')
                ++p;
        }
-    }
 
-    if (is_listchars && lcs_chars.leadtab2 != NUL && lcs_chars.tab2 == NUL)
-       return e_leadtab_requires_tab;
+       if (is_listchars && has_leadtab && !has_tab)
+           return e_leadtab_requires_tab;
+    }
 
     if (apply)
     {
diff --git a/src/testdir/test_listchars.vim b/src/testdir/test_listchars.vim
index 9064b6027..fd0e146b2 100644
--- a/src/testdir/test_listchars.vim
+++ b/src/testdir/test_listchars.vim
@@ -390,6 +390,8 @@ func Test_listchars()
         \ 'text>---tab         '
         \ ]
   call Check_listchars(expected, 3, 20)
+  call assert_equal(expected->mapnew({_, s -> trim(s, ' ', 2)}) + [' '],
+                  \ split(execute("%list"), "
"))
 
   " Test leadtab with unicode characters
   normal ggdG
@@ -397,6 +399,7 @@ func Test_listchars()
   call append(0, ["    text"])
   let expected = ['├──────┤text']
   call Check_listchars(expected, 1, 12)
+  call assert_equal(expected + [' '], split(execute("%list"), "
"))
 
   " Test leadtab with mixed indentation (spaces + tabs)
   normal ggdG
@@ -404,6 +407,7 @@ func Test_listchars()
   call append(0, ["     text"])
   let expected = ['.+******.text']
   call Check_listchars(expected, 1, 13)
+  call assert_equal(expected + [' '], split(execute("%list"), "
"))
 
   " Test leadtab with pipe character
   normal ggdG
@@ -411,6 +415,7 @@ func Test_listchars()
   call append(0, ["    text"])
   let expected = ['|       text']
   call Check_listchars(expected, 1, 12)
+  call assert_equal(expected + [' '], split(execute("%list"), "
"))
 
   " Test leadtab with unicode bar
   normal ggdG
@@ -418,6 +423,7 @@ func Test_listchars()
   call append(0, ["    text"])
   let expected = ['│       text']
   call Check_listchars(expected, 1, 12)
+  call assert_equal(expected + [' '], split(execute("%list"), "
"))
 
   " Test leadtab vs tab distinction (leading vs non-leading)
   " In a line with only tabs, they aren't considered leading.
@@ -436,6 +442,8 @@ func Test_listchars()
         \ '>------->-------                '
         \ ]
   call Check_listchars(expected, 4, 32)
+  call assert_equal(expected->mapnew({_, s -> trim(s, ' ', 2)}) + [' '],
+                  \ split(execute("%list"), "
"))
 
   " Test leadtab with trail and space
   normal ggdG
@@ -451,6 +459,8 @@ func Test_listchars()
         \ '+*******..text<<'
         \ ]
   call Check_listchars(expected, 3, 16)
+  call assert_equal(expected->mapnew({_, s -> trim(s, ' ', 2)}) + [' '],
+                  \ split(execute("%list"), "
"))
 
   " Test leadtab with eol
   normal ggdG
@@ -461,7 +471,8 @@ func Test_listchars()
         \ 'text>---tab$ '
         \ ]
   call Check_listchars(expected, 2, 13)
-
+  call assert_equal(expected->mapnew({_, s -> trim(s, ' ', 2)}) + ['$'],
+                  \ split(execute("%list"), "
"))
 
   " test nbsp
   normal ggdG
diff --git a/src/testdir/util/gen_opt_test.vim 
b/src/testdir/util/gen_opt_test.vim
index 0a010a9f4..e1476001f 100644
--- a/src/testdir/util/gen_opt_test.vim
+++ b/src/testdir/util/gen_opt_test.vim
@@ -247,11 +247,13 @@ let test_values = {
       \                ['xxx', ':none', 'xxx:', 'x:non', 'y:mok3', 
'z:kittty']],
       \ 'langmap': [['', 'xX', 'aA,bB'], ['xxx']],
       \ 'lispoptions': [['', 'expr:0', 'expr:1'], ['xxx', 'expr:x', 'expr:']],
-      \ 'listchars': [['', 'eol:x', 'tab:xy', 'tab:xyz', 'space:x',
-      \                'multispace:xxxy', 'lead:x', 'tab:xy,leadtab:xyz', 
'leadmultispace:xxxy',
-      \                'trail:x', 'extends:x', 'precedes:x', 'conceal:x', 
'nbsp:x',
-      \                'eol:\x24', 'eol:\u21b5', 'eol:\U000021b5', 
'eol:x,space:y'],
-      \                ['xxx', 'eol:', 'leadtab:xyz']],
+      \ 'listchars': [['', 'eol:x', 'tab:xy', 'tab:xyz', 'space:x', 'lead:x',
+      \                'multispace:xxxy', 'tab:xy,leadtab:xyz', 
'leadtab:xyz,tab:xy',
+      \                'leadmultispace:xxxy', 'trail:x', 'extends:x', 
'precedes:x',
+      \                'conceal:x', 'eol:\x24', 'eol:\u21b5', 'eol:\U000021b5',
+      \                'eol:x,space:y', 'nbsp:x'],
+      \                ['xxx', 'eol:', 'leadtab:xyz', 
'multispace:xxxy,leadtab:xyz',
+      \                'leadmultispace:xxxy,leadtab:xyz,multispace:yyyx']],
       \ 'matchpairs': [['', '(:)', '(:),<:>'], ['xxx']],
       \ 'maxsearchcount': [[1, 10, 100, 1000], [0, -1, 10000]],
       \ 'messagesopt': [['hit-enter,history:1', 'hit-enter,history:10000',
diff --git a/src/version.c b/src/version.c
index ebf573e1a..45c76d267 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    102,
 /**/
     101,
 /**/

-- 
-- 
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 visit 
https://groups.google.com/d/msgid/vim_dev/E1vxW93-005FyY-Px%40256bit.org.

Raspunde prin e-mail lui