Merge pull request #17589 from kchibisov/add-dashed-dotted-underline

Add support for double, dashed, and dotted underlines
This commit is contained in:
James McCoy 2022-03-05 15:00:07 -05:00 committed by GitHub
commit c365de1d22
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 143 additions and 52 deletions

View File

@ -7937,8 +7937,11 @@ synIDattr({synID}, {what} [, {mode}]) *synIDattr()*
"inverse" "1" if inverse (= reverse) "inverse" "1" if inverse (= reverse)
"standout" "1" if standout "standout" "1" if standout
"underline" "1" if underlined "underline" "1" if underlined
"underlineline" "1" if double underlined
"undercurl" "1" if undercurled "undercurl" "1" if undercurled
"strikethrough" "1" if struckthrough "underdot" "1" if dotted underlined
"underdash" "1" if dashed underlined
"strikethrough" "1" if struckthrough
Example (echoes the color of the syntax item under the Example (echoes the color of the syntax item under the
cursor): > cursor): >

View File

@ -4875,7 +4875,8 @@ the same syntax file on all UIs.
1. TUI highlight arguments 1. TUI highlight arguments
*bold* *underline* *undercurl* *bold* *underline* *underlineline*
*undercurl* *underdot* *underdash*
*inverse* *italic* *standout* *inverse* *italic* *standout*
*nocombine* *strikethrough* *nocombine* *strikethrough*
cterm={attr-list} *attr-list* *highlight-cterm* *E418* cterm={attr-list} *attr-list* *highlight-cterm* *E418*
@ -4883,7 +4884,10 @@ cterm={attr-list} *attr-list* *highlight-cterm* *E418*
following items (in any order): following items (in any order):
bold bold
underline underline
underlineline double underline
undercurl curly underline undercurl curly underline
underdot dotted underline
underdash dashed underline
strikethrough strikethrough
reverse reverse
inverse same as reverse inverse same as reverse
@ -4894,8 +4898,9 @@ cterm={attr-list} *attr-list* *highlight-cterm* *E418*
Note that "bold" can be used here and by using a bold font. They Note that "bold" can be used here and by using a bold font. They
have the same effect. have the same effect.
"undercurl" falls back to "underline" in a terminal that does not "underlineline", "undercurl", "underdot", and "underdash" fall back
support it. The color is set using |highlight-guisp|. to "underline" in a terminal that does not support them. The color is
set using |highlight-guisp|.
start={term-list} *highlight-start* *E422* start={term-list} *highlight-start* *E422*
stop={term-list} *term-list* *highlight-stop* stop={term-list} *term-list* *highlight-stop*
@ -5028,8 +5033,8 @@ guifg={color-name} *highlight-guifg*
guibg={color-name} *highlight-guibg* guibg={color-name} *highlight-guibg*
guisp={color-name} *highlight-guisp* guisp={color-name} *highlight-guisp*
These give the foreground (guifg), background (guibg) and special These give the foreground (guifg), background (guibg) and special
(guisp) color to use in the GUI. "guisp" is used for undercurl (guisp) color to use in the GUI. "guisp" is used for various
and underline. underlines.
There are a few special names: There are a few special names:
NONE no color (transparent) NONE no color (transparent)
bg use normal background color bg use normal background color

View File

@ -283,19 +283,24 @@ numerical highlight ids to the actual attributes.
attributes specified by the `rgb_attr` and `cterm_attr` dicts, with the attributes specified by the `rgb_attr` and `cterm_attr` dicts, with the
following (all optional) keys. following (all optional) keys.
`foreground`: foreground color. `foreground`: foreground color.
`background`: background color. `background`: background color.
`special`: color to use for underline and undercurl, when present. `special`: color to use for various underlines, when
`reverse`: reverse video. Foreground and background colors are present.
switched. `reverse`: reverse video. Foreground and background colors
`italic`: italic text. are switched.
`bold`: bold text. `italic`: italic text.
`strikethrough`: struckthrough text. `bold`: bold text.
`underline`: underlined text. The line has `special` color. `strikethrough`: struckthrough text.
`undercurl`: undercurled text. The curl has `special` color. `underline`: underlined text. The line has `special` color.
`blend`: Blend level (0-100). Could be used by UIs to support `underlineline`: double underlined text. The lines have `special`
blending floating windows to the background or to color.
signal a transparent cursor. `undercurl`: undercurled text. The curl has `special` color.
`underdot`: underdotted text. The dots have `special` color.
`underdash`: underdashed text. The dashes have `special` color.
`blend`: Blend level (0-100). Could be used by UIs to
support blending floating windows to the
background or to signal a transparent cursor.
For absent color keys the default color should be used. Don't store For absent color keys the default color should be used. Don't store
the default value in the table, rather a sentinel value, so that the default value in the table, rather a sentinel value, so that
@ -444,14 +449,17 @@ is not active. New UIs should implement |ui-linegrid| instead.
`foreground`: foreground color. `foreground`: foreground color.
`background`: background color. `background`: background color.
`special`: color to use for underline and undercurl, when present. `special`: color to use for various underlines, when present.
`reverse`: reverse video. Foreground and background colors are `reverse`: reverse video. Foreground and background colors are
switched. switched.
`italic`: italic text. `italic`: italic text.
`bold`: bold text. `bold`: bold text.
`strikethrough`: struckthrough text. `strikethrough`: struckthrough text.
`underline`: underlined text. The line has `special` color. `underline`: underlined text. The line has `special` color.
`underlineline`: double underlined text. The lines have `special` color.
`undercurl`: undercurled text. The curl has `special` color. `undercurl`: undercurled text. The curl has `special` color.
`underdot`: underdotted text. The dots have `special` color.
`underdash`: underdashed text. The dashes have `special` color.
["put", text] ["put", text]
The (utf-8 encoded) string `text` is put at the cursor position The (utf-8 encoded) string `text` is put at the cursor position

View File

@ -46,14 +46,14 @@ syn match vimTermOption contained "t_%i"
syn match vimTermOption contained "t_k;" syn match vimTermOption contained "t_k;"
" unsupported settings: these are supported by vi but don't do anything in vim {{{2 " unsupported settings: these are supported by vi but don't do anything in vim {{{2
syn keyword vimErrSetting contained hardtabs ht w1200 w300 w9600 syn keyword vimErrSetting contained hardtabs ht w1200 w300 w9600
"}}}2 "}}}2
syn case ignore syn case ignore
" Highlight commonly used Groupnames {{{2 " Highlight commonly used Groupnames {{{2
syn keyword vimGroup contained Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo syn keyword vimGroup contained Comment Constant String Character Number Boolean Float Identifier Function Statement Conditional Repeat Label Operator Keyword Exception PreProc Include Define Macro PreCondit Type StorageClass Structure Typedef Special SpecialChar Tag Delimiter SpecialComment Debug Underlined Ignore Error Todo
" Default highlighting groups {{{2 " Default highlighting groups {{{2
syn keyword vimHLGroup contained ColorColumn Cursor CursorColumn CursorIM CursorLine CursorLineFold CursorLineNr CursorLineSign DiffAdd DiffChange DiffDelete DiffText Directory EndOfBuffer ErrorMsg FoldColumn Folded IncSearch LineNr MatchParen Menu ModeMsg MoreMsg NonText Normal Pmenu PmenuSbar PmenuSel PmenuThumb Question QuickFixLine Scrollbar Search SignColumn SpecialKey SpellBad SpellCap SpellLocal SpellRare StatusLine StatusLineNC TabLine TabLineFill TabLineSel Title Tooltip VertSplit Visual WarningMsg WildMenu syn keyword vimHLGroup contained ColorColumn Cursor CursorColumn CursorIM CursorLine CursorLineFold CursorLineNr CursorLineSign DiffAdd DiffChange DiffDelete DiffText Directory EndOfBuffer ErrorMsg FoldColumn Folded IncSearch LineNr MatchParen Menu ModeMsg MoreMsg NonText Normal Pmenu PmenuSbar PmenuSel PmenuThumb Question QuickFixLine Scrollbar Search SignColumn SpecialKey SpellBad SpellCap SpellLocal SpellRare StatusLine StatusLineNC TabLine TabLineFill TabLineSel Title Tooltip VertSplit Visual WarningMsg WildMenu
syn match vimHLGroup contained "Conceal" syn match vimHLGroup contained "Conceal"
syn keyword vimOnlyHLGroup contained LineNrAbove LineNrBelow StatusLineTerm Terminal VisualNOS syn keyword vimOnlyHLGroup contained LineNrAbove LineNrBelow StatusLineTerm Terminal VisualNOS
syn keyword nvimHLGroup contained Substitute TermCursor TermCursorNC syn keyword nvimHLGroup contained Substitute TermCursor TermCursorNC
@ -88,10 +88,10 @@ if exists("g:vimsyn_folding") && g:vimsyn_folding =~# '[afhlmpPrt]'
else else
com! -nargs=* VimFoldm <args> com! -nargs=* VimFoldm <args>
endif endif
if g:vimsyn_folding =~# 'p' if g:vimsyn_folding =~# 'p'
com! -nargs=* VimFoldp <args> fold com! -nargs=* VimFoldp <args> fold
else else
com! -nargs=* VimFoldp <args> com! -nargs=* VimFoldp <args>
endif endif
if g:vimsyn_folding =~# 'P' if g:vimsyn_folding =~# 'P'
com! -nargs=* VimFoldP <args> fold com! -nargs=* VimFoldP <args> fold
@ -148,8 +148,8 @@ syn match vimNumber '-\d\+\%(\.\d\+\%([eE][+-]\=\d\+\)\=\)\=' skipwhite nextgro
syn match vimNumber '\<0[xX]\x\+' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment syn match vimNumber '\<0[xX]\x\+' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment
syn match vimNumber '\%(^\|\A\)\zs#\x\{6}' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment syn match vimNumber '\%(^\|\A\)\zs#\x\{6}' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment
syn match vimNumber '\<0[zZ][a-zA-Z0-9.]\+' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment syn match vimNumber '\<0[zZ][a-zA-Z0-9.]\+' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment
syn match vimNumber '0[0-7]\+' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment syn match vimNumber '0[0-7]\+' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment
syn match vimNumber '0[bB][01]\+' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment syn match vimNumber '0[bB][01]\+' skipwhite nextgroup=vimGlobal,vimSubst,vimCommand,vimComment,vim9Comment
" All vimCommands are contained by vimIsCommand. {{{2 " All vimCommands are contained by vimIsCommand. {{{2
syn match vimCmdSep "[:|]\+" skipwhite nextgroup=vimAddress,vimAutoCmd,vimEcho,vimIsCommand,vimExtCmd,vimFilter,vimLet,vimMap,vimMark,vimSet,vimSyntax,vimUserCmd syn match vimCmdSep "[:|]\+" skipwhite nextgroup=vimAddress,vimAutoCmd,vimEcho,vimIsCommand,vimExtCmd,vimFilter,vimLet,vimMap,vimMark,vimSet,vimSyntax,vimUserCmd
@ -574,7 +574,7 @@ syn match vimHiBang contained "!" skipwhite nextgroup=@vimHighlightCluster
syn match vimHiGroup contained "\i\+" syn match vimHiGroup contained "\i\+"
syn case ignore syn case ignore
syn keyword vimHiAttrib contained none bold inverse italic nocombine reverse standout strikethrough underline undercurl syn keyword vimHiAttrib contained none bold inverse italic nocombine reverse standout strikethrough underline underlineline undercurl underdot underdash
syn keyword vimFgBgAttrib contained none bg background fg foreground syn keyword vimFgBgAttrib contained none bg background fg foreground
syn case match syn case match
syn match vimHiAttribList contained "\i\+" contains=vimHiAttrib syn match vimHiAttribList contained "\i\+" contains=vimHiAttrib

View File

@ -83,7 +83,10 @@ return {
"standout"; "standout";
"strikethrough"; "strikethrough";
"underline"; "underline";
"underlineline";
"undercurl"; "undercurl";
"underdot";
"underdash";
"italic"; "italic";
"reverse"; "reverse";
"nocombine"; "nocombine";
@ -105,7 +108,10 @@ return {
"standout"; "standout";
"strikethrough"; "strikethrough";
"underline"; "underline";
"underlineline";
"undercurl"; "undercurl";
"underdot";
"underdash";
"italic"; "italic";
"reverse"; "reverse";
"nocombine"; "nocombine";

View File

@ -11408,14 +11408,22 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
p = highlight_has_attr(id, HL_STANDOUT, modec); p = highlight_has_attr(id, HL_STANDOUT, modec);
} }
break; break;
case 'u': case 'u': {
if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline const size_t len = STRLEN(what);
p = highlight_has_attr(id, HL_UNDERLINE, modec); if (len <= 5 || (TOLOWER_ASC(what[5]) == 'l' && len <= 9)) { // underline
} else { // undercurl
p = highlight_has_attr(id, HL_UNDERCURL, modec); p = highlight_has_attr(id, HL_UNDERCURL, modec);
} else if (TOLOWER_ASC(what[5]) == 'c') { // undercurl
p = highlight_has_attr(id, HL_UNDERCURL, modec);
} else if (len > 9 && TOLOWER_ASC(what[9]) == 'l') { // underlineline
p = highlight_has_attr(id, HL_UNDERLINELINE, modec);
} else if (len > 6 && TOLOWER_ASC(what[6]) == 'o') { // underdot
p = highlight_has_attr(id, HL_UNDERDOT, modec);
} else { // underdash
p = highlight_has_attr(id, HL_UNDERDASH, modec);
} }
break; break;
} }
}
rettv->v_type = VAR_STRING; rettv->v_type = VAR_STRING;
rettv->vval.v_string = (char_u *)(p == NULL ? p : xstrdup(p)); rettv->vval.v_string = (char_u *)(p == NULL ? p : xstrdup(p));

View File

@ -420,7 +420,10 @@ static void prt_get_attr(int hl_id, prt_text_attr_T *pattr, int modec)
pattr->bold = (highlight_has_attr(hl_id, HL_BOLD, modec) != NULL); pattr->bold = (highlight_has_attr(hl_id, HL_BOLD, modec) != NULL);
pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL); pattr->italic = (highlight_has_attr(hl_id, HL_ITALIC, modec) != NULL);
pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL); pattr->underline = (highlight_has_attr(hl_id, HL_UNDERLINE, modec) != NULL);
pattr->underlineline = (highlight_has_attr(hl_id, HL_UNDERLINELINE, modec) != NULL);
pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL); pattr->undercurl = (highlight_has_attr(hl_id, HL_UNDERCURL, modec) != NULL);
pattr->underdot = (highlight_has_attr(hl_id, HL_UNDERDOT, modec) != NULL);
pattr->underdash = (highlight_has_attr(hl_id, HL_UNDERDASH, modec) != NULL);
uint32_t fg_color = prt_get_color(hl_id, modec); uint32_t fg_color = prt_get_color(hl_id, modec);

View File

@ -18,6 +18,9 @@ typedef struct {
TriState italic; TriState italic;
TriState underline; TriState underline;
int undercurl; int undercurl;
int underlineline;
int underdot;
int underdash;
} prt_text_attr_T; } prt_text_attr_T;
/* /*

View File

@ -558,7 +558,7 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through)
cattrs = battrs; cattrs = battrs;
cattrs.rgb_fg_color = rgb_blend(ratio, battrs.rgb_fg_color, cattrs.rgb_fg_color = rgb_blend(ratio, battrs.rgb_fg_color,
fattrs.rgb_bg_color); fattrs.rgb_bg_color);
if (cattrs.rgb_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)) { if (cattrs.rgb_ae_attr & (HL_ANY_UNDERLINE)) {
cattrs.rgb_sp_color = rgb_blend(ratio, battrs.rgb_sp_color, cattrs.rgb_sp_color = rgb_blend(ratio, battrs.rgb_sp_color,
fattrs.rgb_bg_color); fattrs.rgb_bg_color);
} else { } else {
@ -576,7 +576,7 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through)
} }
cattrs.rgb_fg_color = rgb_blend(ratio/2, battrs.rgb_fg_color, cattrs.rgb_fg_color = rgb_blend(ratio/2, battrs.rgb_fg_color,
fattrs.rgb_fg_color); fattrs.rgb_fg_color);
if (cattrs.rgb_ae_attr & (HL_UNDERLINE|HL_UNDERCURL)) { if (cattrs.rgb_ae_attr & (HL_ANY_UNDERLINE)) {
cattrs.rgb_sp_color = rgb_blend(ratio/2, battrs.rgb_bg_color, cattrs.rgb_sp_color = rgb_blend(ratio/2, battrs.rgb_bg_color,
fattrs.rgb_sp_color); fattrs.rgb_sp_color);
} else { } else {
@ -743,10 +743,23 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb)
PUT(hl, "underline", BOOLEAN_OBJ(true)); PUT(hl, "underline", BOOLEAN_OBJ(true));
} }
if (mask & HL_UNDERLINELINE) {
PUT(hl, "underlineline", BOOLEAN_OBJ(true));
}
if (mask & HL_UNDERCURL) { if (mask & HL_UNDERCURL) {
PUT(hl, "undercurl", BOOLEAN_OBJ(true)); PUT(hl, "undercurl", BOOLEAN_OBJ(true));
} }
if (mask & HL_UNDERDOT) {
PUT(hl, "underdot", BOOLEAN_OBJ(true));
}
if (mask & HL_UNDERDASH) {
PUT(hl, "underdash", BOOLEAN_OBJ(true));
}
if (mask & HL_ITALIC) { if (mask & HL_ITALIC) {
PUT(hl, "italic", BOOLEAN_OBJ(true)); PUT(hl, "italic", BOOLEAN_OBJ(true));
} }
@ -813,7 +826,10 @@ HlAttrs dict2hlattrs(Dict(highlight) *dict, bool use_rgb, int *link_id, Error *e
CHECK_FLAG(dict, mask, bold, , HL_BOLD); CHECK_FLAG(dict, mask, bold, , HL_BOLD);
CHECK_FLAG(dict, mask, standout, , HL_STANDOUT); CHECK_FLAG(dict, mask, standout, , HL_STANDOUT);
CHECK_FLAG(dict, mask, underline, , HL_UNDERLINE); CHECK_FLAG(dict, mask, underline, , HL_UNDERLINE);
CHECK_FLAG(dict, mask, underlineline, , HL_UNDERLINELINE);
CHECK_FLAG(dict, mask, undercurl, , HL_UNDERCURL); CHECK_FLAG(dict, mask, undercurl, , HL_UNDERCURL);
CHECK_FLAG(dict, mask, underdot, , HL_UNDERDOT);
CHECK_FLAG(dict, mask, underdash, , HL_UNDERDASH);
CHECK_FLAG(dict, mask, italic, , HL_ITALIC); CHECK_FLAG(dict, mask, italic, , HL_ITALIC);
CHECK_FLAG(dict, mask, reverse, , HL_INVERSE); CHECK_FLAG(dict, mask, reverse, , HL_INVERSE);
CHECK_FLAG(dict, mask, strikethrough, , HL_STRIKETHROUGH); CHECK_FLAG(dict, mask, strikethrough, , HL_STRIKETHROUGH);

View File

@ -24,6 +24,10 @@ typedef enum {
HL_FG_INDEXED = 0x0200, HL_FG_INDEXED = 0x0200,
HL_DEFAULT = 0x0400, HL_DEFAULT = 0x0400,
HL_GLOBAL = 0x0800, HL_GLOBAL = 0x0800,
HL_UNDERLINELINE = 0x1000,
HL_UNDERDOT = 0x2000,
HL_UNDERDASH = 0x4000,
HL_ANY_UNDERLINE = HL_UNDERLINE | HL_UNDERLINELINE | HL_UNDERCURL | HL_UNDERDOT | HL_UNDERDASH,
} HlAttrFlags; } HlAttrFlags;
/// Stores a complete highlighting entry, including colors and attributes /// Stores a complete highlighting entry, including colors and attributes

View File

@ -121,11 +121,11 @@ static int include_link = 0; // when 2 include "nvim/link" and "clear"
/// The "term", "cterm" and "gui" arguments can be any combination of the /// The "term", "cterm" and "gui" arguments can be any combination of the
/// following names, separated by commas (but no spaces!). /// following names, separated by commas (but no spaces!).
static char *(hl_name_table[]) = static char *(hl_name_table[]) =
{ "bold", "standout", "underline", "undercurl", { "bold", "standout", "underline", "underlineline", "undercurl", "underdot",
"italic", "reverse", "inverse", "strikethrough", "nocombine", "NONE" }; "underdash", "italic", "reverse", "inverse", "strikethrough", "nocombine", "NONE" };
static int hl_attr_table[] = static int hl_attr_table[] =
{ HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, { HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERLINELINE, HL_UNDERCURL, HL_UNDERDOT, HL_UNDERDASH,
HL_INVERSE, HL_STRIKETHROUGH, HL_NOCOMBINE, 0 }; HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_STRIKETHROUGH, HL_NOCOMBINE, 0 };
static char e_illegal_arg[] = N_("E390: Illegal argument: %s"); static char e_illegal_arg[] = N_("E390: Illegal argument: %s");

View File

@ -528,7 +528,7 @@ static bool attrs_differ(UI *ui, int id1, int id2, bool rgb)
return a1.cterm_fg_color != a2.cterm_fg_color return a1.cterm_fg_color != a2.cterm_fg_color
|| a1.cterm_bg_color != a2.cterm_bg_color || a1.cterm_bg_color != a2.cterm_bg_color
|| a1.cterm_ae_attr != a2.cterm_ae_attr || a1.cterm_ae_attr != a2.cterm_ae_attr
|| (a1.cterm_ae_attr & (HL_UNDERLINE|HL_UNDERCURL) || (a1.cterm_ae_attr & HL_ANY_UNDERLINE
&& a1.rgb_sp_color != a2.rgb_sp_color); && a1.rgb_sp_color != a2.rgb_sp_color);
} }
} }
@ -552,15 +552,27 @@ static void update_attrs(UI *ui, int attr_id)
bool strikethrough = attr & HL_STRIKETHROUGH; bool strikethrough = attr & HL_STRIKETHROUGH;
bool underline; bool underline;
bool underlineline;
bool undercurl; bool undercurl;
bool underdot;
bool underdash;
if (data->unibi_ext.set_underline_style != -1) { if (data->unibi_ext.set_underline_style != -1) {
underline = attr & HL_UNDERLINE; underline = attr & HL_UNDERLINE;
underlineline = attr & HL_UNDERLINELINE;
undercurl = attr & HL_UNDERCURL; undercurl = attr & HL_UNDERCURL;
underdash = attr & HL_UNDERDASH;
underdot = attr & HL_UNDERDOT;
} else { } else {
underline = (attr & HL_UNDERLINE) || (attr & HL_UNDERCURL); underline = attr & HL_ANY_UNDERLINE;
underlineline = false;
undercurl = false; undercurl = false;
underdot = false;
underdash = false;
} }
bool has_any_underline = undercurl || underline
|| underdot || underdash || underlineline;
if (unibi_get_str(data->ut, unibi_set_attributes)) { if (unibi_get_str(data->ut, unibi_set_attributes)) {
if (bold || reverse || underline || standout) { if (bold || reverse || underline || standout) {
UNIBI_SET_NUM_VAR(data->params[0], standout); UNIBI_SET_NUM_VAR(data->params[0], standout);
@ -599,11 +611,24 @@ static void update_attrs(UI *ui, int attr_id)
if (strikethrough && data->unibi_ext.enter_strikethrough_mode != -1) { if (strikethrough && data->unibi_ext.enter_strikethrough_mode != -1) {
unibi_out_ext(ui, data->unibi_ext.enter_strikethrough_mode); unibi_out_ext(ui, data->unibi_ext.enter_strikethrough_mode);
} }
if (underlineline && data->unibi_ext.set_underline_style != -1) {
UNIBI_SET_NUM_VAR(data->params[0], 2);
unibi_out_ext(ui, data->unibi_ext.set_underline_style);
}
if (undercurl && data->unibi_ext.set_underline_style != -1) { if (undercurl && data->unibi_ext.set_underline_style != -1) {
UNIBI_SET_NUM_VAR(data->params[0], 3); UNIBI_SET_NUM_VAR(data->params[0], 3);
unibi_out_ext(ui, data->unibi_ext.set_underline_style); unibi_out_ext(ui, data->unibi_ext.set_underline_style);
} }
if ((undercurl || underline) && data->unibi_ext.set_underline_color != -1) { if (underdot && data->unibi_ext.set_underline_style != -1) {
UNIBI_SET_NUM_VAR(data->params[0], 4);
unibi_out_ext(ui, data->unibi_ext.set_underline_style);
}
if (underdash && data->unibi_ext.set_underline_style != -1) {
UNIBI_SET_NUM_VAR(data->params[0], 5);
unibi_out_ext(ui, data->unibi_ext.set_underline_style);
}
if (has_any_underline && data->unibi_ext.set_underline_color != -1) {
int color = attrs.rgb_sp_color; int color = attrs.rgb_sp_color;
if (color != -1) { if (color != -1) {
UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red UNIBI_SET_NUM_VAR(data->params[0], (color >> 16) & 0xff); // red
@ -652,13 +677,13 @@ static void update_attrs(UI *ui, int attr_id)
data->default_attr = fg == -1 && bg == -1 data->default_attr = fg == -1 && bg == -1
&& !bold && !italic && !underline && !undercurl && !reverse && !standout && !bold && !italic && !has_any_underline && !reverse && !standout
&& !strikethrough; && !strikethrough;
// Non-BCE terminals can't clear with non-default background color. Some BCE // Non-BCE terminals can't clear with non-default background color. Some BCE
// terminals don't support attributes either, so don't rely on it. But assume // terminals don't support attributes either, so don't rely on it. But assume
// italic and bold has no effect if there is no text. // italic and bold has no effect if there is no text.
data->can_clear_attr = !reverse && !standout && !underline && !undercurl data->can_clear_attr = !reverse && !standout && !has_any_underline
&& !strikethrough && (data->bce || bg == -1); && !strikethrough && (data->bce || bg == -1);
} }

View File

@ -28,8 +28,11 @@ describe('API: highlight',function()
bold = true, bold = true,
italic = true, italic = true,
reverse = true, reverse = true,
undercurl = true,
underline = true, underline = true,
underlineline = true,
undercurl = true,
underdot = true,
underdash = true,
strikethrough = true, strikethrough = true,
} }
@ -52,7 +55,7 @@ describe('API: highlight',function()
eq('Invalid highlight id: 30000', string.match(emsg, 'Invalid.*')) eq('Invalid highlight id: 30000', string.match(emsg, 'Invalid.*'))
-- Test all highlight properties. -- Test all highlight properties.
command('hi NewHighlight gui=underline,bold,undercurl,italic,reverse,strikethrough') command('hi NewHighlight gui=underline,bold,underlineline,undercurl,underdot,underdash,italic,reverse,strikethrough')
eq(expected_rgb2, nvim("get_hl_by_id", hl_id, true)) eq(expected_rgb2, nvim("get_hl_by_id", hl_id, true))
-- Test nil argument. -- Test nil argument.
@ -195,6 +198,9 @@ describe("API: set highlight", function()
reverse = true, reverse = true,
undercurl = true, undercurl = true,
underline = true, underline = true,
underdash = true,
underdot = true,
underlineline = true,
strikethrough = true, strikethrough = true,
cterm = { cterm = {
italic = true, italic = true,
@ -211,6 +217,9 @@ describe("API: set highlight", function()
reverse = true, reverse = true,
undercurl = true, undercurl = true,
underline = true, underline = true,
underdash = true,
underdot = true,
underlineline = true,
strikethrough = true, strikethrough = true,
} }
local highlight3_result_cterm = { local highlight3_result_cterm = {
@ -274,7 +283,7 @@ describe("API: set highlight", function()
exec_capture('highlight Test_hl')) exec_capture('highlight Test_hl'))
meths.set_hl(0, 'Test_hl2', highlight3_config) meths.set_hl(0, 'Test_hl2', highlight3_config)
eq('Test_hl2 xxx cterm=undercurl,italic,reverse,strikethrough ctermfg=8 ctermbg=15 gui=bold,underline,undercurl,italic,reverse,strikethrough guifg=#ff0000 guibg=#0032aa', eq('Test_hl2 xxx cterm=undercurl,italic,reverse,strikethrough ctermfg=8 ctermbg=15 gui=bold,underline,underlineline,undercurl,underdot,underdash,italic,reverse,strikethrough guifg=#ff0000 guibg=#0032aa',
exec_capture('highlight Test_hl2')) exec_capture('highlight Test_hl2'))
-- Colors are stored exactly as they are defined. -- Colors are stored exactly as they are defined.

View File

@ -1559,10 +1559,11 @@ end
function Screen:_equal_attrs(a, b) function Screen:_equal_attrs(a, b)
return a.bold == b.bold and a.standout == b.standout and return a.bold == b.bold and a.standout == b.standout and
a.underline == b.underline and a.undercurl == b.undercurl and a.underline == b.underline and a.underlineline == b.underlineline and
a.italic == b.italic and a.reverse == b.reverse and a.undercurl == b.undercurl and a.underdot == b.underdot and
a.foreground == b.foreground and a.background == b.background and a.underdash == b.underdash and a.italic == b.italic and
a.special == b.special and a.blend == b.blend and a.reverse == b.reverse and a.foreground == b.foreground and
a.background == b.background and a.special == b.special and a.blend == b.blend and
a.strikethrough == b.strikethrough and a.strikethrough == b.strikethrough and
a.fg_indexed == b.fg_indexed and a.bg_indexed == b.bg_indexed a.fg_indexed == b.fg_indexed and a.bg_indexed == b.bg_indexed
end end