]> granicus.if.org Git - vim/commitdiff
patch 8.1.0759: showing two characters for tab is limited v8.1.0759
authorBram Moolenaar <Bram@vim.org>
Wed, 16 Jan 2019 21:41:54 +0000 (22:41 +0100)
committerBram Moolenaar <Bram@vim.org>
Wed, 16 Jan 2019 21:41:54 +0000 (22:41 +0100)
Problem:    Showing two characters for tab is limited.
Solution:   Allow for a third character for "tab:" in 'listchars'. (Nathaniel
            Braun, Ken Takata, closes #3810)

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

index 008926f63e12dc1f3b262de28c525fda838ebe87..be53e9f5617f87e8620723709fbeb5b49788644c 100644 (file)
@@ -5063,11 +5063,26 @@ A jump table for the options with a short description can be found at |Q_op|.
                        omitted, there is no extra character at the end of the
                        line.
                                                        *lcs-tab*
-         tab:xy        Two characters to be used to show a tab.  The first
-                       char is used once.  The second char is repeated to
-                       fill the space that the tab normally occupies.
-                       "tab:>-" will show a tab that takes four spaces as
-                       ">---".  When omitted, a tab is show as ^I.
+         tab:xy[z]     Two or three characters to be used to show a tab.
+                       The third character is optional.
+
+         tab:xy        The 'x' is always used, then 'y' as many times as will
+                       fit.  Thus "tab:>-" displays:
+                               >
+                               >-
+                               >--
+                               etc.
+
+         tab:xyz       The 'z' is always used, then 'x' is prepended, and
+                       then 'y' is used as many times as will fit.  Thus
+                       "tab:<->" displays:
+                               >
+                               <>
+                               <->
+                               <-->
+                               etc.
+
+                       When "tab:" is omitted, a tab is shown as ^I.
                                                        *lcs-space*
          space:c       Character to show for a space.  When omitted, spaces
                        are left blank.
index 27b1562e8912a64f1e7753936174e8a7cf0d7987..4a0c52ce4c2a123617d64822f44e0667cf161098 100644 (file)
@@ -1163,6 +1163,7 @@ EXTERN int        lcs_nbsp INIT(= NUL);
 EXTERN int     lcs_space INIT(= NUL);
 EXTERN int     lcs_tab1 INIT(= NUL);
 EXTERN int     lcs_tab2 INIT(= NUL);
+EXTERN int     lcs_tab3 INIT(= NUL);
 EXTERN int     lcs_trail INIT(= NUL);
 #ifdef FEAT_CONCEAL
 EXTERN int     lcs_conceal INIT(= ' ');
index 635dd8be94869e5d3a321e46bbfc0572d5dcd9b4..9969632dd18ee85997e3d4f56da648bc47d6d567 100644 (file)
@@ -1771,6 +1771,7 @@ msg_prt_line(char_u *s, int list)
     int                col = 0;
     int                n_extra = 0;
     int                c_extra = 0;
+    int                c_final = 0;
     char_u     *p_extra = NULL;            /* init to make SASC shut up */
     int                n;
     int                attr = 0;
@@ -1801,7 +1802,9 @@ msg_prt_line(char_u *s, int list)
        if (n_extra > 0)
        {
            --n_extra;
-           if (c_extra)
+           if (n_extra == 0 && c_final)
+               c = c_final;
+           else if (c_extra)
                c = c_extra;
            else
                c = *p_extra++;
@@ -1844,11 +1847,13 @@ msg_prt_line(char_u *s, int list)
                {
                    c = ' ';
                    c_extra = ' ';
+                   c_final = NUL;
                }
                else
                {
-                   c = lcs_tab1;
+                   c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
                    c_extra = lcs_tab2;
+                   c_final = lcs_tab3;
                    attr = HL_ATTR(HLF_8);
                }
            }
@@ -1861,6 +1866,7 @@ msg_prt_line(char_u *s, int list)
            {
                p_extra = (char_u *)"";
                c_extra = NUL;
+               c_final = NUL;
                n_extra = 1;
                c = lcs_eol;
                attr = HL_ATTR(HLF_AT);
@@ -1871,6 +1877,7 @@ msg_prt_line(char_u *s, int list)
                n_extra = n - 1;
                p_extra = transchar_byte(c);
                c_extra = NUL;
+               c_final = NUL;
                c = *p_extra++;
                /* Use special coloring to be able to distinguish <hex> from
                 * the same in plain text. */
index ca3e3d8308d3b8dd267dfb6c1826e13da06bace1..ec058e97d8319484007903b1e5ff437077afc2df 100644 (file)
@@ -7949,7 +7949,7 @@ set_chars_option(char_u **varp)
 {
     int                round, i, len, entries;
     char_u     *p, *s;
-    int                c1, c2 = 0;
+    int                c1 = 0, c2 = 0, c3 = 0;
     struct charstab
     {
        int     *cp;
@@ -8001,8 +8001,12 @@ set_chars_option(char_u **varp)
            for (i = 0; i < entries; ++i)
                if (tab[i].cp != NULL)
                    *(tab[i].cp) = (varp == &p_lcs ? NUL : ' ');
+
            if (varp == &p_lcs)
+           {
                lcs_tab1 = NUL;
+               lcs_tab3 = NUL;
+           }
            else
                fill_diff = '-';
        }
@@ -8016,6 +8020,7 @@ set_chars_option(char_u **varp)
                        && p[len] == ':'
                        && p[len + 1] != NUL)
                {
+                   c1 = c2 = c3 = 0;
                    s = p + len + 1;
 #ifdef FEAT_MBYTE
                    c1 = mb_ptr2char_adv(&s);
@@ -8035,7 +8040,18 @@ set_chars_option(char_u **varp)
 #else
                        c2 = *s++;
 #endif
+                       if (!(*s == ',' || *s == NUL))
+                       {
+#ifdef FEAT_MBYTE
+                           c3 = mb_ptr2char_adv(&s);
+                           if (mb_char2cells(c3) > 1)
+                               continue;
+#else
+                           c3 = *s++;
+#endif
+                       }
                    }
+
                    if (*s == ',' || *s == NUL)
                    {
                        if (round)
@@ -8044,6 +8060,7 @@ set_chars_option(char_u **varp)
                            {
                                lcs_tab1 = c1;
                                lcs_tab2 = c2;
+                               lcs_tab3 = c3;
                            }
                            else if (tab[i].cp != NULL)
                                *(tab[i].cp) = c1;
index 9b976ffaf1d8e2c8d9549904312d1b66bfb2d6b6..cd146fd6c1299b717dacaa0dff19ad8f3985baa4 100644 (file)
@@ -3049,6 +3049,7 @@ win_line(
     char_u     *p_extra = NULL;        /* string of extra chars, plus NUL */
     char_u     *p_extra_free = NULL;   /* p_extra needs to be freed */
     int                c_extra = NUL;          /* extra chars, all the same */
+    int                c_final = NUL;          /* final char, mandatory if set */
     int                extra_attr = 0;         /* attributes when n_extra != 0 */
     static char_u *at_end_str = (char_u *)""; /* used for p_extra when
                                           displaying lcs_eol at end-of-line */
@@ -3059,6 +3060,7 @@ win_line(
     int                saved_n_extra = 0;
     char_u     *saved_p_extra = NULL;
     int                saved_c_extra = 0;
+    int                saved_c_final = 0;
     int                saved_char_attr = 0;
 
     int                n_attr = 0;             /* chars with special attr */
@@ -3814,6 +3816,7 @@ win_line(
                    /* Draw the cmdline character. */
                    n_extra = 1;
                    c_extra = cmdwin_type;
+                   c_final = NUL;
                    char_attr = HL_ATTR(HLF_AT);
                }
            }
@@ -3839,6 +3842,7 @@ win_line(
                        p_extra_free[n_extra] = NUL;
                        p_extra = p_extra_free;
                        c_extra = NUL;
+                       c_final = NUL;
                        char_attr = HL_ATTR(HLF_FC);
                    }
                }
@@ -3860,6 +3864,7 @@ win_line(
 
                    /* Draw two cells with the sign value or blank. */
                    c_extra = ' ';
+                   c_final = NUL;
                    char_attr = HL_ATTR(HLF_SC);
                    n_extra = 2;
 
@@ -3878,9 +3883,13 @@ win_line(
                        {
                            /* Use the image in this position. */
                            c_extra = SIGN_BYTE;
+                           c_final = NUL;
 #  ifdef FEAT_NETBEANS_INTG
                            if (buf_signcount(wp->w_buffer, lnum) > 1)
+                           {
                                c_extra = MULTISIGN_BYTE;
+                               c_final = NUL;
+                           }
 #  endif
                            char_attr = icon_sign;
                        }
@@ -3892,6 +3901,7 @@ win_line(
                            if (p_extra != NULL)
                            {
                                c_extra = NUL;
+                               c_final = NUL;
                                n_extra = (int)STRLEN(p_extra);
                            }
                            char_attr = sign_get_attr(text_sign, FALSE);
@@ -3949,9 +3959,13 @@ win_line(
 #endif
                        p_extra = extra;
                        c_extra = NUL;
+                       c_final = NUL;
                    }
                    else
+                   {
                        c_extra = ' ';
+                       c_final = NUL;
+                   }
                    n_extra = number_width(wp) + 1;
                    char_attr = HL_ATTR(HLF_N);
 #ifdef FEAT_SYN_HL
@@ -4020,9 +4034,15 @@ win_line(
                {
                    /* Draw "deleted" diff line(s). */
                    if (char2cells(fill_diff) > 1)
+                   {
                        c_extra = '-';
+                       c_final = NUL;
+                   }
                    else
+                   {
                        c_extra = fill_diff;
+                       c_final = NUL;
+                   }
 #  ifdef FEAT_RIGHTLEFT
                    if (wp->w_p_rl)
                        n_extra = col + 1;
@@ -4038,6 +4058,7 @@ win_line(
                    /* Draw 'showbreak' at the start of each broken line. */
                    p_extra = p_sbr;
                    c_extra = NUL;
+                   c_final = NUL;
                    n_extra = (int)STRLEN(p_sbr);
                    char_attr = HL_ATTR(HLF_AT);
                    need_showbreak = FALSE;
@@ -4065,6 +4086,7 @@ win_line(
                    /* Continue item from end of wrapped line. */
                    n_extra = saved_n_extra;
                    c_extra = saved_c_extra;
+                   c_final = saved_c_final;
                    p_extra = saved_p_extra;
                    char_attr = saved_char_attr;
                }
@@ -4364,15 +4386,16 @@ win_line(
         * The "p_extra" points to the extra stuff that is inserted to
         * represent special characters (non-printable stuff) and other
         * things.  When all characters are the same, c_extra is used.
+        * If c_final is set, it will compulsorily be used at the end.
         * "p_extra" must end in a NUL to avoid mb_ptr2len() reads past
         * "p_extra[n_extra]".
         * For the '$' of the 'list' option, n_extra == 1, p_extra == "".
         */
        if (n_extra > 0)
        {
-           if (c_extra != NUL)
+           if (c_extra != NUL || (n_extra == 1 && c_final != NUL))
            {
-               c = c_extra;
+               c = (n_extra == 1 && c_final != NUL) ? c_final : c_extra;
 #ifdef FEAT_MBYTE
                mb_c = c;       /* doesn't handle non-utf-8 multi-byte! */
                if (enc_utf8 && utf_char2len(c) > 1)
@@ -4537,6 +4560,7 @@ win_line(
                        mb_utf8 = (c >= 0x80);
                        n_extra = (int)STRLEN(p_extra);
                        c_extra = NUL;
+                       c_final = NUL;
                        if (area_attr == 0 && search_attr == 0)
                        {
                            n_attr = n_extra + 1;
@@ -4605,6 +4629,7 @@ win_line(
                            p_extra = extra;
                            n_extra = (int)STRLEN(extra) - 1;
                            c_extra = NUL;
+                           c_final = NUL;
                            c = *p_extra++;
                            if (area_attr == 0 && search_attr == 0)
                            {
@@ -4645,6 +4670,7 @@ win_line(
                {
                    n_extra = 1;
                    c_extra = MB_FILLER_CHAR;
+                   c_final = NUL;
                    c = ' ';
                    if (area_attr == 0 && search_attr == 0)
                    {
@@ -4856,6 +4882,7 @@ win_line(
 # else
                    c_extra = ' ';
 # endif
+                   c_final = NUL;
                    if (VIM_ISWHITE(c))
                    {
 #ifdef FEAT_CONCEAL
@@ -5040,13 +5067,14 @@ win_line(
 #endif
                    if (wp->w_p_list)
                    {
-                       c = lcs_tab1;
+                       c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
 #ifdef FEAT_LINEBREAK
                        if (wp->w_p_lbr)
                            c_extra = NUL; /* using p_extra from above */
                        else
 #endif
                            c_extra = lcs_tab2;
+                       c_final = lcs_tab3;
                        n_attr = tab_len + 1;
                        extra_attr = HL_ATTR(HLF_8);
                        saved_attr2 = char_attr; /* save current attr */
@@ -5062,6 +5090,7 @@ win_line(
                    }
                    else
                    {
+                       c_final = NUL;
                        c_extra = ' ';
                        c = ' ';
                    }
@@ -5111,6 +5140,7 @@ win_line(
                            p_extra = at_end_str;
                            n_extra = 1;
                            c_extra = NUL;
+                           c_final = NUL;
                        }
                    }
                    if (wp->w_p_list && lcs_eol > 0)
@@ -5146,6 +5176,7 @@ win_line(
                        rl_mirror(p_extra);     /* reverse "<12>" */
 #endif
                    c_extra = NUL;
+                   c_final = NUL;
 #ifdef FEAT_LINEBREAK
                    if (wp->w_p_lbr)
                    {
@@ -5407,6 +5438,7 @@ win_line(
                /* Double-width character being overwritten by the "precedes"
                 * character, need to fill up half the character. */
                c_extra = MB_FILLER_CHAR;
+               c_final = NUL;
                n_extra = 1;
                n_attr = 2;
                extra_attr = HL_ATTR(HLF_AT);
@@ -6064,6 +6096,7 @@ win_line(
            saved_n_extra = n_extra;
            saved_p_extra = p_extra;
            saved_c_extra = c_extra;
+           saved_c_final = c_final;
            saved_char_attr = char_attr;
            n_extra = 0;
            lcs_prec_todo = lcs_prec;
index 57ea7ca5a970084c1180cb6ce8379c3ab21b5deb..4899f59910670bc0061db1348984332e4297a694 100644 (file)
@@ -42,6 +42,38 @@ func Test_listchars()
     call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
   endfor
 
+  " tab with 3rd character.
+  set listchars-=tab:>-
+  set listchars+=tab:<=>,trail:-
+  let expected = [
+             \ '<======>aa<====>$',
+             \ '..bb<==>--$',
+             \ '...cccc>-$',
+             \ 'dd........ee--<>$',
+             \ '-$'
+             \ ]
+  redraw!
+  for i in range(1, 5)
+    call cursor(i, 1)
+    call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+  endfor
+
+  set listchars-=trail:-
+  let expected = [
+             \ '<======>aa<====>$',
+             \ '..bb<==>..$',
+             \ '...cccc>.$',
+             \ 'dd........ee..<>$',
+             \ '.$'
+             \ ]
+  redraw!
+  for i in range(1, 5)
+    call cursor(i, 1)
+    call assert_equal([expected[i - 1]], ScreenLines(i, virtcol('$')))
+  endfor
+
+  set listchars-=tab:<=>
+  set listchars+=tab:>-
   set listchars+=trail:<
   set nolist
   normal ggdG
index 710c0245e9900cb49e7470506de446f072a85224..c4c596956843d98b61ea2e09d2d185c8ed1c5455 100644 (file)
@@ -795,6 +795,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    759,
 /**/
     758,
 /**/