Skip to content

Commit 83a5217

Browse files
committed
patch 8.1.0759: showing two characters for tab is limited
Problem: Showing two characters for tab is limited. Solution: Allow for a third character for "tab:" in 'listchars'. (Nathaniel Braun, Ken Takata, closes #3810)
1 parent 500f361 commit 83a5217

File tree

7 files changed

+118
-11
lines changed

7 files changed

+118
-11
lines changed

runtime/doc/options.txt

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5063,11 +5063,26 @@ A jump table for the options with a short description can be found at |Q_op|.
50635063
omitted, there is no extra character at the end of the
50645064
line.
50655065
*lcs-tab*
5066-
tab:xy Two characters to be used to show a tab. The first
5067-
char is used once. The second char is repeated to
5068-
fill the space that the tab normally occupies.
5069-
"tab:>-" will show a tab that takes four spaces as
5070-
">---". When omitted, a tab is show as ^I.
5066+
tab:xy[z] Two or three characters to be used to show a tab.
5067+
The third character is optional.
5068+
5069+
tab:xy The 'x' is always used, then 'y' as many times as will
5070+
fit. Thus "tab:>-" displays:
5071+
>
5072+
>-
5073+
>--
5074+
etc.
5075+
5076+
tab:xyz The 'z' is always used, then 'x' is prepended, and
5077+
then 'y' is used as many times as will fit. Thus
5078+
"tab:<->" displays:
5079+
>
5080+
<>
5081+
<->
5082+
<-->
5083+
etc.
5084+
5085+
When "tab:" is omitted, a tab is shown as ^I.
50715086
*lcs-space*
50725087
space:c Character to show for a space. When omitted, spaces
50735088
are left blank.

src/globals.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,7 @@ EXTERN int lcs_nbsp INIT(= NUL);
11631163
EXTERN int lcs_space INIT(= NUL);
11641164
EXTERN int lcs_tab1 INIT(= NUL);
11651165
EXTERN int lcs_tab2 INIT(= NUL);
1166+
EXTERN int lcs_tab3 INIT(= NUL);
11661167
EXTERN int lcs_trail INIT(= NUL);
11671168
#ifdef FEAT_CONCEAL
11681169
EXTERN int lcs_conceal INIT(= ' ');

src/message.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1771,6 +1771,7 @@ msg_prt_line(char_u *s, int list)
17711771
int col = 0;
17721772
int n_extra = 0;
17731773
int c_extra = 0;
1774+
int c_final = 0;
17741775
char_u *p_extra = NULL; /* init to make SASC shut up */
17751776
int n;
17761777
int attr = 0;
@@ -1801,7 +1802,9 @@ msg_prt_line(char_u *s, int list)
18011802
if (n_extra > 0)
18021803
{
18031804
--n_extra;
1804-
if (c_extra)
1805+
if (n_extra == 0 && c_final)
1806+
c = c_final;
1807+
else if (c_extra)
18051808
c = c_extra;
18061809
else
18071810
c = *p_extra++;
@@ -1844,11 +1847,13 @@ msg_prt_line(char_u *s, int list)
18441847
{
18451848
c = ' ';
18461849
c_extra = ' ';
1850+
c_final = NUL;
18471851
}
18481852
else
18491853
{
1850-
c = lcs_tab1;
1854+
c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
18511855
c_extra = lcs_tab2;
1856+
c_final = lcs_tab3;
18521857
attr = HL_ATTR(HLF_8);
18531858
}
18541859
}
@@ -1861,6 +1866,7 @@ msg_prt_line(char_u *s, int list)
18611866
{
18621867
p_extra = (char_u *)"";
18631868
c_extra = NUL;
1869+
c_final = NUL;
18641870
n_extra = 1;
18651871
c = lcs_eol;
18661872
attr = HL_ATTR(HLF_AT);
@@ -1871,6 +1877,7 @@ msg_prt_line(char_u *s, int list)
18711877
n_extra = n - 1;
18721878
p_extra = transchar_byte(c);
18731879
c_extra = NUL;
1880+
c_final = NUL;
18741881
c = *p_extra++;
18751882
/* Use special coloring to be able to distinguish <hex> from
18761883
* the same in plain text. */

src/option.c

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7949,7 +7949,7 @@ set_chars_option(char_u **varp)
79497949
{
79507950
int round, i, len, entries;
79517951
char_u *p, *s;
7952-
int c1, c2 = 0;
7952+
int c1 = 0, c2 = 0, c3 = 0;
79537953
struct charstab
79547954
{
79557955
int *cp;
@@ -8001,8 +8001,12 @@ set_chars_option(char_u **varp)
80018001
for (i = 0; i < entries; ++i)
80028002
if (tab[i].cp != NULL)
80038003
*(tab[i].cp) = (varp == &p_lcs ? NUL : ' ');
8004+
80048005
if (varp == &p_lcs)
8006+
{
80058007
lcs_tab1 = NUL;
8008+
lcs_tab3 = NUL;
8009+
}
80068010
else
80078011
fill_diff = '-';
80088012
}
@@ -8016,6 +8020,7 @@ set_chars_option(char_u **varp)
80168020
&& p[len] == ':'
80178021
&& p[len + 1] != NUL)
80188022
{
8023+
c1 = c2 = c3 = 0;
80198024
s = p + len + 1;
80208025
#ifdef FEAT_MBYTE
80218026
c1 = mb_ptr2char_adv(&s);
@@ -8035,7 +8040,18 @@ set_chars_option(char_u **varp)
80358040
#else
80368041
c2 = *s++;
80378042
#endif
8043+
if (!(*s == ',' || *s == NUL))
8044+
{
8045+
#ifdef FEAT_MBYTE
8046+
c3 = mb_ptr2char_adv(&s);
8047+
if (mb_char2cells(c3) > 1)
8048+
continue;
8049+
#else
8050+
c3 = *s++;
8051+
#endif
8052+
}
80388053
}
8054+
80398055
if (*s == ',' || *s == NUL)
80408056
{
80418057
if (round)
@@ -8044,6 +8060,7 @@ set_chars_option(char_u **varp)
80448060
{
80458061
lcs_tab1 = c1;
80468062
lcs_tab2 = c2;
8063+
lcs_tab3 = c3;
80478064
}
80488065
else if (tab[i].cp != NULL)
80498066
*(tab[i].cp) = c1;

src/screen.c

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3049,6 +3049,7 @@ win_line(
30493049
char_u *p_extra = NULL; /* string of extra chars, plus NUL */
30503050
char_u *p_extra_free = NULL; /* p_extra needs to be freed */
30513051
int c_extra = NUL; /* extra chars, all the same */
3052+
int c_final = NUL; /* final char, mandatory if set */
30523053
int extra_attr = 0; /* attributes when n_extra != 0 */
30533054
static char_u *at_end_str = (char_u *)""; /* used for p_extra when
30543055
displaying lcs_eol at end-of-line */
@@ -3059,6 +3060,7 @@ win_line(
30593060
int saved_n_extra = 0;
30603061
char_u *saved_p_extra = NULL;
30613062
int saved_c_extra = 0;
3063+
int saved_c_final = 0;
30623064
int saved_char_attr = 0;
30633065

30643066
int n_attr = 0; /* chars with special attr */
@@ -3814,6 +3816,7 @@ win_line(
38143816
/* Draw the cmdline character. */
38153817
n_extra = 1;
38163818
c_extra = cmdwin_type;
3819+
c_final = NUL;
38173820
char_attr = HL_ATTR(HLF_AT);
38183821
}
38193822
}
@@ -3839,6 +3842,7 @@ win_line(
38393842
p_extra_free[n_extra] = NUL;
38403843
p_extra = p_extra_free;
38413844
c_extra = NUL;
3845+
c_final = NUL;
38423846
char_attr = HL_ATTR(HLF_FC);
38433847
}
38443848
}
@@ -3860,6 +3864,7 @@ win_line(
38603864

38613865
/* Draw two cells with the sign value or blank. */
38623866
c_extra = ' ';
3867+
c_final = NUL;
38633868
char_attr = HL_ATTR(HLF_SC);
38643869
n_extra = 2;
38653870

@@ -3878,9 +3883,13 @@ win_line(
38783883
{
38793884
/* Use the image in this position. */
38803885
c_extra = SIGN_BYTE;
3886+
c_final = NUL;
38813887
# ifdef FEAT_NETBEANS_INTG
38823888
if (buf_signcount(wp->w_buffer, lnum) > 1)
3889+
{
38833890
c_extra = MULTISIGN_BYTE;
3891+
c_final = NUL;
3892+
}
38843893
# endif
38853894
char_attr = icon_sign;
38863895
}
@@ -3892,6 +3901,7 @@ win_line(
38923901
if (p_extra != NULL)
38933902
{
38943903
c_extra = NUL;
3904+
c_final = NUL;
38953905
n_extra = (int)STRLEN(p_extra);
38963906
}
38973907
char_attr = sign_get_attr(text_sign, FALSE);
@@ -3949,9 +3959,13 @@ win_line(
39493959
#endif
39503960
p_extra = extra;
39513961
c_extra = NUL;
3962+
c_final = NUL;
39523963
}
39533964
else
3965+
{
39543966
c_extra = ' ';
3967+
c_final = NUL;
3968+
}
39553969
n_extra = number_width(wp) + 1;
39563970
char_attr = HL_ATTR(HLF_N);
39573971
#ifdef FEAT_SYN_HL
@@ -4020,9 +4034,15 @@ win_line(
40204034
{
40214035
/* Draw "deleted" diff line(s). */
40224036
if (char2cells(fill_diff) > 1)
4037+
{
40234038
c_extra = '-';
4039+
c_final = NUL;
4040+
}
40244041
else
4042+
{
40254043
c_extra = fill_diff;
4044+
c_final = NUL;
4045+
}
40264046
# ifdef FEAT_RIGHTLEFT
40274047
if (wp->w_p_rl)
40284048
n_extra = col + 1;
@@ -4038,6 +4058,7 @@ win_line(
40384058
/* Draw 'showbreak' at the start of each broken line. */
40394059
p_extra = p_sbr;
40404060
c_extra = NUL;
4061+
c_final = NUL;
40414062
n_extra = (int)STRLEN(p_sbr);
40424063
char_attr = HL_ATTR(HLF_AT);
40434064
need_showbreak = FALSE;
@@ -4065,6 +4086,7 @@ win_line(
40654086
/* Continue item from end of wrapped line. */
40664087
n_extra = saved_n_extra;
40674088
c_extra = saved_c_extra;
4089+
c_final = saved_c_final;
40684090
p_extra = saved_p_extra;
40694091
char_attr = saved_char_attr;
40704092
}
@@ -4364,15 +4386,16 @@ win_line(
43644386
* The "p_extra" points to the extra stuff that is inserted to
43654387
* represent special characters (non-printable stuff) and other
43664388
* things. When all characters are the same, c_extra is used.
4389+
* If c_final is set, it will compulsorily be used at the end.
43674390
* "p_extra" must end in a NUL to avoid mb_ptr2len() reads past
43684391
* "p_extra[n_extra]".
43694392
* For the '$' of the 'list' option, n_extra == 1, p_extra == "".
43704393
*/
43714394
if (n_extra > 0)
43724395
{
4373-
if (c_extra != NUL)
4396+
if (c_extra != NUL || (n_extra == 1 && c_final != NUL))
43744397
{
4375-
c = c_extra;
4398+
c = (n_extra == 1 && c_final != NUL) ? c_final : c_extra;
43764399
#ifdef FEAT_MBYTE
43774400
mb_c = c; /* doesn't handle non-utf-8 multi-byte! */
43784401
if (enc_utf8 && utf_char2len(c) > 1)
@@ -4537,6 +4560,7 @@ win_line(
45374560
mb_utf8 = (c >= 0x80);
45384561
n_extra = (int)STRLEN(p_extra);
45394562
c_extra = NUL;
4563+
c_final = NUL;
45404564
if (area_attr == 0 && search_attr == 0)
45414565
{
45424566
n_attr = n_extra + 1;
@@ -4605,6 +4629,7 @@ win_line(
46054629
p_extra = extra;
46064630
n_extra = (int)STRLEN(extra) - 1;
46074631
c_extra = NUL;
4632+
c_final = NUL;
46084633
c = *p_extra++;
46094634
if (area_attr == 0 && search_attr == 0)
46104635
{
@@ -4645,6 +4670,7 @@ win_line(
46454670
{
46464671
n_extra = 1;
46474672
c_extra = MB_FILLER_CHAR;
4673+
c_final = NUL;
46484674
c = ' ';
46494675
if (area_attr == 0 && search_attr == 0)
46504676
{
@@ -4856,6 +4882,7 @@ win_line(
48564882
# else
48574883
c_extra = ' ';
48584884
# endif
4885+
c_final = NUL;
48594886
if (VIM_ISWHITE(c))
48604887
{
48614888
#ifdef FEAT_CONCEAL
@@ -5040,13 +5067,14 @@ win_line(
50405067
#endif
50415068
if (wp->w_p_list)
50425069
{
5043-
c = lcs_tab1;
5070+
c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
50445071
#ifdef FEAT_LINEBREAK
50455072
if (wp->w_p_lbr)
50465073
c_extra = NUL; /* using p_extra from above */
50475074
else
50485075
#endif
50495076
c_extra = lcs_tab2;
5077+
c_final = lcs_tab3;
50505078
n_attr = tab_len + 1;
50515079
extra_attr = HL_ATTR(HLF_8);
50525080
saved_attr2 = char_attr; /* save current attr */
@@ -5062,6 +5090,7 @@ win_line(
50625090
}
50635091
else
50645092
{
5093+
c_final = NUL;
50655094
c_extra = ' ';
50665095
c = ' ';
50675096
}
@@ -5111,6 +5140,7 @@ win_line(
51115140
p_extra = at_end_str;
51125141
n_extra = 1;
51135142
c_extra = NUL;
5143+
c_final = NUL;
51145144
}
51155145
}
51165146
if (wp->w_p_list && lcs_eol > 0)
@@ -5146,6 +5176,7 @@ win_line(
51465176
rl_mirror(p_extra); /* reverse "<12>" */
51475177
#endif
51485178
c_extra = NUL;
5179+
c_final = NUL;
51495180
#ifdef FEAT_LINEBREAK
51505181
if (wp->w_p_lbr)
51515182
{
@@ -5407,6 +5438,7 @@ win_line(
54075438
/* Double-width character being overwritten by the "precedes"
54085439
* character, need to fill up half the character. */
54095440
c_extra = MB_FILLER_CHAR;
5441+
c_final = NUL;
54105442
n_extra = 1;
54115443
n_attr = 2;
54125444
extra_attr = HL_ATTR(HLF_AT);
@@ -6064,6 +6096,7 @@ win_line(
60646096
saved_n_extra = n_extra;
60656097
saved_p_extra = p_extra;
60666098
saved_c_extra = c_extra;
6099+
saved_c_final = c_final;
60676100
saved_char_attr = char_attr;
60686101
n_extra = 0;
60696102
lcs_prec_todo = lcs_prec;

0 commit comments

Comments
 (0)