Skip to content

Commit eed9d46

Browse files
committed
patch 8.2.2518: 'listchars' should be window-local
Problem: 'listchars' should be window-local. Solution: Make 'listchars' global-local. (Yegappan Lakshmanan, Marco Hinz, closes #5206, closes #7850)
1 parent 7c5b3c0 commit eed9d46

20 files changed

Lines changed: 302 additions & 112 deletions

runtime/doc/options.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4854,7 +4854,7 @@ A jump table for the options with a short description can be found at |Q_op|.
48544854

48554855
*'listchars'* *'lcs'*
48564856
'listchars' 'lcs' string (default "eol:$")
4857-
global
4857+
global or local to window |global-local|
48584858
Strings to use in 'list' mode and for the |:list| command. It is a
48594859
comma separated list of string settings.
48604860
*lcs-eol*

src/buffer.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4549,7 +4549,7 @@ build_stl_str_hl(
45494549
case STL_VIRTCOL_ALT:
45504550
// In list mode virtcol needs to be recomputed
45514551
virtcol = wp->w_virtcol;
4552-
if (wp->w_p_list && lcs_tab1 == NUL)
4552+
if (wp->w_p_list && wp->w_lcs_chars.tab1 == NUL)
45534553
{
45544554
wp->w_p_list = FALSE;
45554555
getvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);

src/charset.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -753,15 +753,15 @@ vim_strnsize(char_u *s, int len)
753753

754754
#ifdef FEAT_VARTABS
755755
# define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
756-
if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
756+
if (*(p) == TAB && (!(wp)->w_p_list || wp->w_lcs_chars.tab1)) \
757757
{ \
758758
return tabstop_padding(col, (buf)->b_p_ts, (buf)->b_p_vts_array); \
759759
} \
760760
else \
761761
return ptr2cells(p);
762762
#else
763763
# define RET_WIN_BUF_CHARTABSIZE(wp, buf, p, col) \
764-
if (*(p) == TAB && (!(wp)->w_p_list || lcs_tab1)) \
764+
if (*(p) == TAB && (!(wp)->w_p_list || wp->w_lcs_chars.tab1)) \
765765
{ \
766766
int ts; \
767767
ts = (buf)->b_p_ts; \
@@ -1153,7 +1153,7 @@ win_nolbr_chartabsize(
11531153
{
11541154
int n;
11551155

1156-
if (*s == TAB && (!wp->w_p_list || lcs_tab1))
1156+
if (*s == TAB && (!wp->w_p_list || wp->w_lcs_chars.tab1))
11571157
{
11581158
# ifdef FEAT_VARTABS
11591159
return tabstop_padding(col, wp->w_buffer->b_p_ts,
@@ -1248,7 +1248,7 @@ getvcol(
12481248
* use a simple loop.
12491249
* Also use this when 'list' is set but tabs take their normal size.
12501250
*/
1251-
if ((!wp->w_p_list || lcs_tab1 != NUL)
1251+
if ((!wp->w_p_list || wp->w_lcs_chars.tab1 != NUL)
12521252
#ifdef FEAT_LINEBREAK
12531253
&& !wp->w_p_lbr && *get_showbreak_value(wp) == NUL && !wp->w_p_bri
12541254
#endif

src/drawline.c

Lines changed: 47 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,9 @@ win_line(
248248
int c_final = NUL; // final char, mandatory if set
249249
int extra_attr = 0; // attributes when n_extra != 0
250250
static char_u *at_end_str = (char_u *)""; // used for p_extra when
251-
// displaying lcs_eol at end-of-line
252-
int lcs_eol_one = lcs_eol; // lcs_eol until it's been used
253-
int lcs_prec_todo = lcs_prec; // lcs_prec until it's been used
251+
// displaying eol at end-of-line
252+
int lcs_eol_one = wp->w_lcs_chars.eol; // eol until it's been used
253+
int lcs_prec_todo = wp->w_lcs_chars.prec; // prec until it's been used
254254

255255
// saved "extra" items for when draw_state becomes WL_LINE (again)
256256
int saved_n_extra = 0;
@@ -735,19 +735,22 @@ win_line(
735735

736736
if (wp->w_p_list)
737737
{
738-
if (lcs_space || lcs_trail || lcs_lead || lcs_nbsp)
738+
if (wp->w_lcs_chars.space
739+
|| wp->w_lcs_chars.trail
740+
|| wp->w_lcs_chars.lead
741+
|| wp->w_lcs_chars.nbsp)
739742
extra_check = TRUE;
740743

741744
// find start of trailing whitespace
742-
if (lcs_trail)
745+
if (wp->w_lcs_chars.trail)
743746
{
744747
trailcol = (colnr_T)STRLEN(ptr);
745748
while (trailcol > (colnr_T)0 && VIM_ISWHITE(ptr[trailcol - 1]))
746749
--trailcol;
747750
trailcol += (colnr_T) (ptr - line);
748751
}
749752
// find end of leading whitespace
750-
if (lcs_lead)
753+
if (wp->w_lcs_chars.lead)
751754
{
752755
leadcol = 0;
753756
while (VIM_ISWHITE(ptr[leadcol]))
@@ -2000,22 +2003,23 @@ win_line(
20002003
}
20012004
#endif
20022005

2003-
// 'list': Change char 160 to lcs_nbsp and space to lcs_space.
2004-
// But not when the character is followed by a composing
2005-
// character (use mb_l to check that).
2006+
// 'list': Change char 160 to 'nbsp' and space to 'space'
2007+
// setting in 'listchars'. But not when the character is
2008+
// followed by a composing character (use mb_l to check that).
20062009
if (wp->w_p_list
20072010
&& ((((c == 160 && mb_l == 1)
20082011
|| (mb_utf8
20092012
&& ((mb_c == 160 && mb_l == 2)
20102013
|| (mb_c == 0x202f && mb_l == 3))))
2011-
&& lcs_nbsp)
2014+
&& wp->w_lcs_chars.nbsp)
20122015
|| (c == ' '
20132016
&& mb_l == 1
2014-
&& lcs_space
2017+
&& wp->w_lcs_chars.space
20152018
&& ptr - line >= leadcol
20162019
&& ptr - line <= trailcol)))
20172020
{
2018-
c = (c == ' ') ? lcs_space : lcs_nbsp;
2021+
c = (c == ' ') ? wp->w_lcs_chars.space :
2022+
wp->w_lcs_chars.nbsp;
20192023
if (area_attr == 0 && search_attr == 0)
20202024
{
20212025
n_attr = 1;
@@ -2036,7 +2040,8 @@ win_line(
20362040
if ((trailcol != MAXCOL && ptr > line + trailcol && c == ' ')
20372041
|| (leadcol != 0 && ptr < line + leadcol && c == ' '))
20382042
{
2039-
c = (ptr > line + trailcol) ? lcs_trail : lcs_lead;
2043+
c = (ptr > line + trailcol) ? wp->w_lcs_chars.trail
2044+
: wp->w_lcs_chars.lead;
20402045
if (!attr_pri)
20412046
{
20422047
n_attr = 1;
@@ -2061,7 +2066,7 @@ win_line(
20612066
// when getting a character from the file, we may have to
20622067
// turn it into something else on the way to putting it
20632068
// into "ScreenLines".
2064-
if (c == TAB && (!wp->w_p_list || lcs_tab1))
2069+
if (c == TAB && (!wp->w_p_list || wp->w_lcs_chars.tab1))
20652070
{
20662071
int tab_len = 0;
20672072
long vcol_adjusted = vcol; // removed showbreak length
@@ -2101,37 +2106,38 @@ win_line(
21012106
// there are characters to conceal
21022107
tab_len += vcol_off;
21032108
// boguscols before FIX_FOR_BOGUSCOLS macro from above
2104-
if (wp->w_p_list && lcs_tab1 && old_boguscols > 0
2105-
&& n_extra > tab_len)
2109+
if (wp->w_p_list && wp->w_lcs_chars.tab1
2110+
&& old_boguscols > 0
2111+
&& n_extra > tab_len)
21062112
tab_len += n_extra - tab_len;
21072113
#endif
21082114

21092115
// if n_extra > 0, it gives the number of chars, to
21102116
// use for a tab, else we need to calculate the width
21112117
// for a tab
2112-
len = (tab_len * mb_char2len(lcs_tab2));
2118+
len = (tab_len * mb_char2len(wp->w_lcs_chars.tab2));
21132119
if (n_extra > 0)
21142120
len += n_extra - tab_len;
2115-
c = lcs_tab1;
2121+
c = wp->w_lcs_chars.tab1;
21162122
p = alloc(len + 1);
21172123
vim_memset(p, ' ', len);
21182124
p[len] = NUL;
21192125
vim_free(p_extra_free);
21202126
p_extra_free = p;
21212127
for (i = 0; i < tab_len; i++)
21222128
{
2123-
int lcs = lcs_tab2;
2129+
int lcs = wp->w_lcs_chars.tab2;
21242130

21252131
if (*p == NUL)
21262132
{
21272133
tab_len = i;
21282134
break;
21292135
}
21302136

2131-
// if lcs_tab3 is given, need to change the char
2137+
// if tab3 is given, need to change the char
21322138
// for tab
2133-
if (lcs_tab3 && i == tab_len - 1)
2134-
lcs = lcs_tab3;
2139+
if (wp->w_lcs_chars.tab3 && i == tab_len - 1)
2140+
lcs = wp->w_lcs_chars.tab3;
21352141
mb_char2bytes(lcs, p);
21362142
p += mb_char2len(lcs);
21372143
n_extra += mb_char2len(lcs)
@@ -2162,21 +2168,23 @@ win_line(
21622168
// correctly set further below (effectively reverts the
21632169
// FIX_FOR_BOGSUCOLS macro
21642170
if (n_extra == tab_len + vc_saved && wp->w_p_list
2165-
&& lcs_tab1)
2171+
&& wp->w_lcs_chars.tab1)
21662172
tab_len += vc_saved;
21672173
}
21682174
#endif
21692175
mb_utf8 = FALSE; // don't draw as UTF-8
21702176
if (wp->w_p_list)
21712177
{
2172-
c = (n_extra == 0 && lcs_tab3) ? lcs_tab3 : lcs_tab1;
2178+
c = (n_extra == 0 && wp->w_lcs_chars.tab3)
2179+
? wp->w_lcs_chars.tab3
2180+
: wp->w_lcs_chars.tab1;
21732181
#ifdef FEAT_LINEBREAK
21742182
if (wp->w_p_lbr)
21752183
c_extra = NUL; // using p_extra from above
21762184
else
21772185
#endif
2178-
c_extra = lcs_tab2;
2179-
c_final = lcs_tab3;
2186+
c_extra = wp->w_lcs_chars.tab2;
2187+
c_final = wp->w_lcs_chars.tab3;
21802188
n_attr = tab_len + 1;
21812189
extra_attr = hl_combine_attr(win_attr, HL_ATTR(HLF_8));
21822190
saved_attr2 = char_attr; // save current attr
@@ -2241,8 +2249,8 @@ win_line(
22412249
c_final = NUL;
22422250
}
22432251
}
2244-
if (wp->w_p_list && lcs_eol > 0)
2245-
c = lcs_eol;
2252+
if (wp->w_p_list && wp->w_lcs_chars.eol > 0)
2253+
c = wp->w_lcs_chars.eol;
22462254
else
22472255
c = ' ';
22482256
lcs_eol_one = -1;
@@ -2344,7 +2352,8 @@ win_line(
23442352
// don't do search HL for the rest of the line
23452353
if (line_attr != 0 && char_attr == search_attr
23462354
&& (did_line_attr > 1
2347-
|| (wp->w_p_list && lcs_eol > 0)))
2355+
|| (wp->w_p_list &&
2356+
wp->w_lcs_chars.eol > 0)))
23482357
char_attr = line_attr;
23492358
# ifdef FEAT_DIFF
23502359
if (diff_hlf == HLF_TXD)
@@ -2404,8 +2413,8 @@ win_line(
24042413
c = match_conc;
24052414
else if (syn_get_sub_char() != NUL)
24062415
c = syn_get_sub_char();
2407-
else if (lcs_conceal != NUL)
2408-
c = lcs_conceal;
2416+
else if (wp->w_lcs_chars.conceal != NUL)
2417+
c = wp->w_lcs_chars.conceal;
24092418
else
24102419
c = ' ';
24112420

@@ -2548,7 +2557,7 @@ win_line(
25482557
&& draw_state > WL_NR
25492558
&& c != NUL)
25502559
{
2551-
c = lcs_prec;
2560+
c = wp->w_lcs_chars.prec;
25522561
lcs_prec_todo = NUL;
25532562
if (has_mbyte && (*mb_char2cells)(mb_c) > 1)
25542563
{
@@ -2594,7 +2603,7 @@ win_line(
25942603
// highlight match at end of line. If it's beyond the last
25952604
// char on the screen, just overwrite that one (tricky!) Not
25962605
// needed when a '$' was displayed for 'list'.
2597-
if (lcs_eol == lcs_eol_one
2606+
if (wp->w_lcs_chars.eol == lcs_eol_one
25982607
&& ((area_attr != 0 && vcol == fromcol
25992608
&& (VIsual_mode != Ctrl_V
26002609
|| lnum == VIsual.lnum
@@ -2764,7 +2773,7 @@ win_line(
27642773

27652774
// Show "extends" character from 'listchars' if beyond the line end and
27662775
// 'list' is set.
2767-
if (lcs_ext != NUL
2776+
if (wp->w_lcs_chars.ext != NUL
27682777
&& wp->w_p_list
27692778
&& !wp->w_p_wrap
27702779
#ifdef FEAT_DIFF
@@ -2779,7 +2788,7 @@ win_line(
27792788
|| (wp->w_p_list && lcs_eol_one > 0)
27802789
|| (n_extra && (c_extra != NUL || *p_extra != NUL))))
27812790
{
2782-
c = lcs_ext;
2791+
c = wp->w_lcs_chars.ext;
27832792
char_attr = hl_combine_attr(win_attr, HL_ATTR(HLF_AT));
27842793
mb_c = c;
27852794
if (enc_utf8 && utf_char2len(c) > 1)
@@ -3036,7 +3045,8 @@ win_line(
30363045
#ifdef FEAT_DIFF
30373046
|| filler_todo > 0
30383047
#endif
3039-
|| (wp->w_p_list && lcs_eol != NUL && p_extra != at_end_str)
3048+
|| (wp->w_p_list && wp->w_lcs_chars.eol != NUL
3049+
&& p_extra != at_end_str)
30403050
|| (n_extra != 0 && (c_extra != NUL || *p_extra != NUL)))
30413051
)
30423052
{
@@ -3161,7 +3171,7 @@ win_line(
31613171
#endif
31623172
saved_char_attr = 0;
31633173
n_extra = 0;
3164-
lcs_prec_todo = lcs_prec;
3174+
lcs_prec_todo = wp->w_lcs_chars.prec;
31653175
#ifdef FEAT_LINEBREAK
31663176
# ifdef FEAT_DIFF
31673177
if (filler_todo <= 0)

src/drawscreen.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -696,7 +696,7 @@ win_redr_ruler(win_T *wp, int always, int ignore_pum)
696696

697697
// In list mode virtcol needs to be recomputed
698698
virtcol = wp->w_virtcol;
699-
if (wp->w_p_list && lcs_tab1 == NUL)
699+
if (wp->w_p_list && wp->w_lcs_chars.tab1 == NUL)
700700
{
701701
wp->w_p_list = FALSE;
702702
getvvcol(wp, &wp->w_cursor, NULL, &virtcol, NULL);

src/evalfunc.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9736,7 +9736,8 @@ f_synconcealed(typval_T *argvars UNUSED, typval_T *rettv)
97369736
{
97379737
cchar = syn_get_sub_char();
97389738
if (cchar == NUL && curwin->w_p_cole == 1)
9739-
cchar = (lcs_conceal == NUL) ? ' ' : lcs_conceal;
9739+
cchar = (curwin->w_lcs_chars.conceal == NUL) ? ' '
9740+
: curwin->w_lcs_chars.conceal;
97409741
if (cchar != NUL)
97419742
{
97429743
if (has_mbyte)

src/globals.h

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1342,21 +1342,6 @@ EXTERN char_u *homedir INIT(= NULL);
13421342
// directory is not a local directory, globaldir is NULL.
13431343
EXTERN char_u *globaldir INIT(= NULL);
13441344

1345-
// Characters from 'listchars' option
1346-
EXTERN int lcs_eol INIT(= '$');
1347-
EXTERN int lcs_ext INIT(= NUL);
1348-
EXTERN int lcs_prec INIT(= NUL);
1349-
EXTERN int lcs_nbsp INIT(= NUL);
1350-
EXTERN int lcs_space INIT(= NUL);
1351-
EXTERN int lcs_tab1 INIT(= NUL);
1352-
EXTERN int lcs_tab2 INIT(= NUL);
1353-
EXTERN int lcs_tab3 INIT(= NUL);
1354-
EXTERN int lcs_trail INIT(= NUL);
1355-
EXTERN int lcs_lead INIT(= NUL);
1356-
#ifdef FEAT_CONCEAL
1357-
EXTERN int lcs_conceal INIT(= ' ');
1358-
#endif
1359-
13601345
// Characters from 'fillchars' option
13611346
EXTERN int fill_stl INIT(= ' ');
13621347
EXTERN int fill_stlnc INIT(= ' ');

src/indent.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -432,7 +432,8 @@ get_indent_str(
432432
{
433433
if (*ptr == TAB)
434434
{
435-
if (!list || lcs_tab1) // count a tab for what it is worth
435+
if (!list || curwin->w_lcs_chars.tab1)
436+
// count a tab for what it is worth
436437
count += ts - (count % ts);
437438
else
438439
// In list mode, when tab is not set, count screen char width
@@ -462,7 +463,7 @@ get_indent_str_vtab(char_u *ptr, int ts, int *vts, int list)
462463
{
463464
if (*ptr == TAB) // count a tab for what it is worth
464465
{
465-
if (!list || lcs_tab1)
466+
if (!list || curwin->w_lcs_chars.tab1)
466467
count += tabstop_padding(count, ts, vts);
467468
else
468469
// In list mode, when tab is not set, count screen char width

0 commit comments

Comments
 (0)