Skip to content

Commit 84f5463

Browse files
committed
patch 9.0.0007: no support for double, dotted and dashed underlines
Problem: No support for double, dotted and dashed underlines. Solution: Add the termcap entries and highlight modes. (closes #9553)
1 parent 8b5901e commit 84f5463

16 files changed

Lines changed: 137 additions & 35 deletions

runtime/doc/options.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4211,7 +4211,10 @@ A jump table for the options with a short description can be found at |Q_op|.
42114211
b bold (termcap entry "md" and "me")
42124212
s standout (termcap entry "so" and "se")
42134213
u underline (termcap entry "us" and "ue")
4214-
c undercurl (termcap entry "Cs" and "Ce")
4214+
c undercurl (termcap entry "Us" and "Ce")
4215+
2 double underline (termcap entry "Ds" and "Ce")
4216+
d dotted underline (termcap entry "ds" and "Ce")
4217+
= dashed underline (termcap entry "Ds" and "Ce")
42154218
t strikethrough (termcap entry "Ts" and "Te")
42164219
n no highlighting
42174220
- no highlighting

runtime/doc/syntax.txt

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5002,14 +5002,18 @@ the same syntax file on all terminals, and use the optimal highlighting.
50025002
1. highlight arguments for normal terminals
50035003

50045004
*bold* *underline* *undercurl*
5005-
*inverse* *italic* *standout*
5006-
*nocombine* *strikethrough*
5005+
*underdouble* *underdotted*
5006+
*underdashed* *inverse* *italic*
5007+
*standout* *nocombine* *strikethrough*
50075008
term={attr-list} *attr-list* *highlight-term* *E418*
50085009
attr-list is a comma-separated list (without spaces) of the
50095010
following items (in any order):
50105011
bold
50115012
underline
50125013
undercurl not always available
5014+
underdouble not always available
5015+
underdotted not always available
5016+
underdashed not always available
50135017
strikethrough not always available
50145018
reverse
50155019
inverse same as reverse
@@ -5020,6 +5024,7 @@ term={attr-list} *attr-list* *highlight-term* *E418*
50205024

50215025
Note that "bold" can be used here and by using a bold font. They
50225026
have the same effect.
5027+
*underline-codes*
50235028
"undercurl" is a curly underline. When "undercurl" is not possible
50245029
then "underline" is used. In general "undercurl" and "strikethrough"
50255030
are only available in the GUI and some terminals. The color is set
@@ -5028,6 +5033,17 @@ term={attr-list} *attr-list* *highlight-term* *E418*
50285033
let &t_Cs = "\e[4:3m"
50295034
let &t_Ce = "\e[4:0m"
50305035
5036+
< "underdouble" is a double underline, "underdotted" is a dotted
5037+
underline and "underdashed" is a dashed underline. These are only
5038+
supported by some terminals. If your terminal supports them you may
5039+
have to specify the codes like this: >
5040+
let &t_Us = "\e[4:2m"
5041+
let &t_ds = "\e[4:4m"
5042+
let &t_Ds = "\e[4:5m"
5043+
< They are reset with |t_Ce|, the same as curly underline (undercurl).
5044+
When t_Us, t_ds or t_Ds is not set then underline will be used as a
5045+
fallback.
5046+
50315047

50325048
start={term-list} *highlight-start* *E422*
50335049
stop={term-list} *term-list* *highlight-stop*

runtime/doc/term.txt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -372,8 +372,11 @@ OUTPUT CODES *terminal-output-codes*
372372

373373
Added by Vim (there are no standard codes for these):
374374
t_AU set underline color (ANSI) *t_AU* *'t_AU'*
375-
t_Ce undercurl end *t_Ce* *'t_Ce'*
376-
t_Cs undercurl mode *t_Cs* *'t_Cs'*
375+
t_Ce undercurl and underline end *t_Ce* *'t_Ce'*
376+
t_Cs undercurl (curly underline) mode *t_Cs* *'t_Cs'*
377+
t_Us double underline mode *t_Us* *'t_Us'*
378+
t_ds dotted underline mode *t_ds* *'t_ds'*
379+
t_Ds dashed underline mode *t_Ds* *'t_Ds'*
377380
t_Te strikethrough end *t_Te* *'t_Te'*
378381
t_Ts strikethrough mode *t_Ts* *'t_Ts'*
379382
t_IS set icon text start *t_IS* *'t_IS'*

src/evalfunc.c

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10104,14 +10104,27 @@ f_synIDattr(typval_T *argvars UNUSED, typval_T *rettv)
1010410104
break;
1010510105

1010610106
case 'u':
10107-
if (TOLOWER_ASC(what[1]) == 'l') // ul
10108-
p = highlight_color(id, what, modec);
10109-
else if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c')
10107+
if (STRLEN(what) >= 9)
10108+
{
10109+
if (TOLOWER_ASC(what[5]) == 'l')
1011010110
// underline
10111-
p = highlight_has_attr(id, HL_UNDERLINE, modec);
10112-
else
10111+
p = highlight_has_attr(id, HL_UNDERLINE, modec);
10112+
else if (TOLOWER_ASC(what[5]) != 'd')
1011310113
// undercurl
10114-
p = highlight_has_attr(id, HL_UNDERCURL, modec);
10114+
p = highlight_has_attr(id, HL_UNDERCURL, modec);
10115+
else if (TOLOWER_ASC(what[6]) != 'o')
10116+
// underdashed
10117+
p = highlight_has_attr(id, HL_UNDERDASHED, modec);
10118+
else if (TOLOWER_ASC(what[7]) == 'u')
10119+
// underdouble
10120+
p = highlight_has_attr(id, HL_UNDERDOUBLE, modec);
10121+
else
10122+
// underdotted
10123+
p = highlight_has_attr(id, HL_UNDERDOTTED, modec);
10124+
}
10125+
else
10126+
// ul
10127+
p = highlight_color(id, what, modec);
1011510128
break;
1011610129
}
1011710130

src/gui.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2501,6 +2501,8 @@ gui_outstr_nowrap(
25012501
if (hl_mask_todo & HL_UNDERCURL)
25022502
draw_flags |= DRAW_UNDERC;
25032503

2504+
// TODO: HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED
2505+
25042506
// Do we strikethrough the text?
25052507
if (hl_mask_todo & HL_STRIKETHROUGH)
25062508
draw_flags |= DRAW_STRIKE;

src/hardcopy.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ prt_get_attr(
293293
pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL);
294294
pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL);
295295
pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL);
296+
// TODO: HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED
296297

297298
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
298299
if (USE_24BIT)

src/highlight.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@
2525
* following names, separated by commas (but no spaces!).
2626
*/
2727
static char *(hl_name_table[]) =
28-
{"bold", "standout", "underline", "undercurl",
29-
"italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"};
28+
{"bold", "standout", "underline",
29+
"undercurl", "underdouble", "underdotted", "underdashed",
30+
"italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"};
3031
static int hl_attr_table[] =
31-
{HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0};
32+
{HL_BOLD, HL_STANDOUT, HL_UNDERLINE,
33+
HL_UNDERCURL, HL_UNDERDOUBLE, HL_UNDERDOTTED, HL_UNDERDASHED,
34+
HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0};
35+
// length of all attribute names, plus commas, together (and a bit more)
36+
#define MAX_ATTR_LEN 120
37+
3238
#define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? (attr_b) : (attr_a)) | (attr_b))
3339

3440
/*
@@ -2963,7 +2969,7 @@ highlight_list_arg(
29632969
char_u *sarg,
29642970
char *name)
29652971
{
2966-
char_u buf[100];
2972+
char_u buf[MAX_ATTR_LEN];
29672973
char_u *ts;
29682974
int i;
29692975

@@ -2984,8 +2990,8 @@ highlight_list_arg(
29842990
if (iarg & hl_attr_table[i])
29852991
{
29862992
if (buf[0] != NUL)
2987-
vim_strcat(buf, (char_u *)",", 100);
2988-
vim_strcat(buf, (char_u *)hl_name_table[i], 100);
2993+
vim_strcat(buf, (char_u *)",", MAX_ATTR_LEN);
2994+
vim_strcat(buf, (char_u *)hl_name_table[i], MAX_ATTR_LEN);
29892995
iarg &= ~hl_attr_table[i]; // don't want "inverse"
29902996
}
29912997
}
@@ -3287,7 +3293,8 @@ set_hl_attr(
32873293
at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_bg);
32883294
// Only use the underline/undercurl color when used, it may clear the
32893295
// background color if not supported.
3290-
if (sgp->sg_cterm & (HL_UNDERLINE | HL_UNDERCURL))
3296+
if (sgp->sg_cterm & (HL_UNDERLINE | HL_UNDERCURL
3297+
| HL_UNDERDOUBLE | HL_UNDERDOTTED | HL_UNDERDASHED))
32913298
at_en.ae_u.cterm.ul_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_sp);
32923299
else
32933300
at_en.ae_u.cterm.ul_rgb = INVALCOLOR;
@@ -3801,6 +3808,12 @@ highlight_changed(void)
38013808
break;
38023809
case 'c': attr |= HL_UNDERCURL;
38033810
break;
3811+
case '2': attr |= HL_UNDERDOUBLE;
3812+
break;
3813+
case 'd': attr |= HL_UNDERDOTTED;
3814+
break;
3815+
case '=': attr |= HL_UNDERDASHED;
3816+
break;
38043817
case 't': attr |= HL_STRIKETHROUGH;
38053818
break;
38063819
case ':': ++p; // highlight group name
@@ -4362,9 +4375,9 @@ hlg_add_or_update(dict_T *dict)
43624375
{
43634376
char_u *name;
43644377
int error;
4365-
char_u term_attr[80];
4366-
char_u cterm_attr[80];
4367-
char_u gui_attr[80];
4378+
char_u term_attr[MAX_ATTR_LEN];
4379+
char_u cterm_attr[MAX_ATTR_LEN];
4380+
char_u gui_attr[MAX_ATTR_LEN];
43684381
char_u *start;
43694382
char_u *stop;
43704383
char_u *ctermfg;

src/optiondefs.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2893,9 +2893,9 @@ static struct vimoption options[] =
28932893
p_term("t_BD", T_BD)
28942894
p_term("t_cd", T_CD)
28952895
p_term("t_ce", T_CE)
2896+
p_term("t_Ce", T_UCE)
28962897
p_term("t_cl", T_CL)
28972898
p_term("t_cm", T_CM)
2898-
p_term("t_Ce", T_UCE)
28992899
p_term("t_Co", T_CCO)
29002900
p_term("t_CS", T_CCS)
29012901
p_term("t_Cs", T_UCS)
@@ -2905,6 +2905,8 @@ static struct vimoption options[] =
29052905
p_term("t_db", T_DB)
29062906
p_term("t_DL", T_CDL)
29072907
p_term("t_dl", T_DL)
2908+
p_term("t_ds", T_DS)
2909+
p_term("t_Ds", T_CDS)
29082910
p_term("t_EC", T_CEC)
29092911
p_term("t_EI", T_CEI)
29102912
p_term("t_fs", T_FS)
@@ -2952,6 +2954,7 @@ static struct vimoption options[] =
29522954
p_term("t_u7", T_U7)
29532955
p_term("t_ue", T_UE)
29542956
p_term("t_us", T_US)
2957+
p_term("t_Us", T_USS)
29552958
p_term("t_ut", T_UT)
29562959
p_term("t_vb", T_VB)
29572960
p_term("t_ve", T_VE)

src/screen.c

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,8 +1855,17 @@ screen_start_highlight(int attr)
18551855
out_str(T_SO);
18561856
if ((attr & HL_UNDERCURL) && *T_UCS != NUL) // undercurl
18571857
out_str(T_UCS);
1858-
if (((attr & HL_UNDERLINE) // underline or undercurl
1859-
|| ((attr & HL_UNDERCURL) && *T_UCS == NUL))
1858+
if ((attr & HL_UNDERDOUBLE) && *T_USS != NUL) // double underline
1859+
out_str(T_USS);
1860+
if ((attr & HL_UNDERDOTTED) && *T_DS != NUL) // dotted underline
1861+
out_str(T_DS);
1862+
if ((attr & HL_UNDERDASHED) && *T_CDS != NUL) // dashed underline
1863+
out_str(T_CDS);
1864+
if (((attr & HL_UNDERLINE) // underline or undercurl, etc.
1865+
|| ((attr & HL_UNDERCURL) && *T_UCS == NUL)
1866+
|| ((attr & HL_UNDERDOUBLE) && *T_USS == NUL)
1867+
|| ((attr & HL_UNDERDOTTED) && *T_DS == NUL)
1868+
|| ((attr & HL_UNDERDASHED) && *T_CDS == NUL))
18601869
&& *T_US != NUL)
18611870
out_str(T_US);
18621871
if ((attr & HL_ITALIC) && *T_CZH != NUL) // italic
@@ -1951,6 +1960,8 @@ screen_stop_highlight(void)
19511960
else
19521961
#endif
19531962
{
1963+
int is_under;
1964+
19541965
if (screen_attr > HL_ALL) // special HL attr.
19551966
{
19561967
attrentry_T *aep;
@@ -2030,15 +2041,16 @@ screen_stop_highlight(void)
20302041
else
20312042
out_str(T_SE);
20322043
}
2033-
if ((screen_attr & HL_UNDERCURL) && *T_UCE != NUL)
2044+
is_under = (screen_attr & (HL_UNDERCURL
2045+
| HL_UNDERDOUBLE | HL_UNDERDOTTED | HL_UNDERDASHED));
2046+
if (is_under && *T_UCE != NUL)
20342047
{
20352048
if (STRCMP(T_UCE, T_ME) == 0)
20362049
do_ME = TRUE;
20372050
else
20382051
out_str(T_UCE);
20392052
}
2040-
if ((screen_attr & HL_UNDERLINE)
2041-
|| ((screen_attr & HL_UNDERCURL) && *T_UCE == NUL))
2053+
if ((screen_attr & HL_UNDERLINE) || (is_under && *T_UCE == NUL))
20422054
{
20432055
if (STRCMP(T_UE, T_ME) == 0)
20442056
do_ME = TRUE;

src/term.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1187,6 +1187,9 @@ static struct builtin_term builtin_termcaps[] =
11871187
{(int)KS_US, "[US]"},
11881188
{(int)KS_UCE, "[UCE]"},
11891189
{(int)KS_UCS, "[UCS]"},
1190+
{(int)KS_USS, "[USS]"},
1191+
{(int)KS_DS, "[DS]"},
1192+
{(int)KS_CDS, "[CDS]"},
11901193
{(int)KS_STE, "[STE]"},
11911194
{(int)KS_STS, "[STS]"},
11921195
{(int)KS_MS, "[MS]"},
@@ -1669,6 +1672,7 @@ get_term_entries(int *height, int *width)
16691672
{KS_MD, "md"}, {KS_SE, "se"}, {KS_SO, "so"},
16701673
{KS_CZH,"ZH"}, {KS_CZR,"ZR"}, {KS_UE, "ue"},
16711674
{KS_US, "us"}, {KS_UCE, "Ce"}, {KS_UCS, "Cs"},
1675+
{KS_USS, "Us"}, {KS_DS, "ds"}, {KS_CDS, "Ds"},
16721676
{KS_STE,"Te"}, {KS_STS,"Ts"},
16731677
{KS_CM, "cm"}, {KS_SR, "sr"},
16741678
{KS_CRI,"RI"}, {KS_VB, "vb"}, {KS_KS, "ks"},

0 commit comments

Comments
 (0)