aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2022-03-05 15:00:07 -0500
committerGitHub <noreply@github.com>2022-03-05 15:00:07 -0500
commitc365de1d22de3e70e785267fe19cb9c43b42d355 (patch)
treeeedb8f3597ba982066a11b9f39f94e16f25f31d6 /src
parentd557a4557100e3ab48a504dafcf53f544196595c (diff)
parent7fd1182c62d6e969ac15b3891bfcc4ff480d6953 (diff)
downloadrneovim-c365de1d22de3e70e785267fe19cb9c43b42d355.tar.gz
rneovim-c365de1d22de3e70e785267fe19cb9c43b42d355.tar.bz2
rneovim-c365de1d22de3e70e785267fe19cb9c43b42d355.zip
Merge pull request #17589 from kchibisov/add-dashed-dotted-underline
Add support for double, dashed, and dotted underlines
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/keysets.lua6
-rw-r--r--src/nvim/eval/funcs.c16
-rw-r--r--src/nvim/hardcopy.c3
-rw-r--r--src/nvim/hardcopy.h3
-rw-r--r--src/nvim/highlight.c20
-rw-r--r--src/nvim/highlight_defs.h4
-rw-r--r--src/nvim/syntax.c8
-rw-r--r--src/nvim/tui/tui.c35
8 files changed, 80 insertions, 15 deletions
diff --git a/src/nvim/api/keysets.lua b/src/nvim/api/keysets.lua
index b05816f8ac..4676ec7596 100644
--- a/src/nvim/api/keysets.lua
+++ b/src/nvim/api/keysets.lua
@@ -83,7 +83,10 @@ return {
"standout";
"strikethrough";
"underline";
+ "underlineline";
"undercurl";
+ "underdot";
+ "underdash";
"italic";
"reverse";
"nocombine";
@@ -105,7 +108,10 @@ return {
"standout";
"strikethrough";
"underline";
+ "underlineline";
"undercurl";
+ "underdot";
+ "underdash";
"italic";
"reverse";
"nocombine";
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index fb2465b9fd..df1889b12d 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -11408,14 +11408,22 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
p = highlight_has_attr(id, HL_STANDOUT, modec);
}
break;
- case 'u':
- if (STRLEN(what) <= 5 || TOLOWER_ASC(what[5]) != 'c') { // underline
- p = highlight_has_attr(id, HL_UNDERLINE, modec);
- } else { // undercurl
+ case 'u': {
+ const size_t len = STRLEN(what);
+ if (len <= 5 || (TOLOWER_ASC(what[5]) == 'l' && len <= 9)) { // underline
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;
}
+ }
rettv->v_type = VAR_STRING;
rettv->vval.v_string = (char_u *)(p == NULL ? p : xstrdup(p));
diff --git a/src/nvim/hardcopy.c b/src/nvim/hardcopy.c
index eb10c65be9..93c8c53e33 100644
--- a/src/nvim/hardcopy.c
+++ b/src/nvim/hardcopy.c
@@ -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->italic = (highlight_has_attr(hl_id, HL_ITALIC, 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->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);
diff --git a/src/nvim/hardcopy.h b/src/nvim/hardcopy.h
index eba769d342..16119c5d2d 100644
--- a/src/nvim/hardcopy.h
+++ b/src/nvim/hardcopy.h
@@ -18,6 +18,9 @@ typedef struct {
TriState italic;
TriState underline;
int undercurl;
+ int underlineline;
+ int underdot;
+ int underdash;
} prt_text_attr_T;
/*
diff --git a/src/nvim/highlight.c b/src/nvim/highlight.c
index e43a56086f..a01d8369ba 100644
--- a/src/nvim/highlight.c
+++ b/src/nvim/highlight.c
@@ -558,7 +558,7 @@ int hl_blend_attrs(int back_attr, int front_attr, bool *through)
cattrs = battrs;
cattrs.rgb_fg_color = rgb_blend(ratio, battrs.rgb_fg_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,
fattrs.rgb_bg_color);
} 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,
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,
fattrs.rgb_sp_color);
} else {
@@ -743,10 +743,23 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb)
PUT(hl, "underline", BOOLEAN_OBJ(true));
}
+ if (mask & HL_UNDERLINELINE) {
+ PUT(hl, "underlineline", BOOLEAN_OBJ(true));
+ }
+
if (mask & HL_UNDERCURL) {
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) {
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, standout, , HL_STANDOUT);
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, underdot, , HL_UNDERDOT);
+ CHECK_FLAG(dict, mask, underdash, , HL_UNDERDASH);
CHECK_FLAG(dict, mask, italic, , HL_ITALIC);
CHECK_FLAG(dict, mask, reverse, , HL_INVERSE);
CHECK_FLAG(dict, mask, strikethrough, , HL_STRIKETHROUGH);
diff --git a/src/nvim/highlight_defs.h b/src/nvim/highlight_defs.h
index 50a03e0c02..dcfb9358bb 100644
--- a/src/nvim/highlight_defs.h
+++ b/src/nvim/highlight_defs.h
@@ -24,6 +24,10 @@ typedef enum {
HL_FG_INDEXED = 0x0200,
HL_DEFAULT = 0x0400,
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;
/// Stores a complete highlighting entry, including colors and attributes
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c
index 1e7801faee..54fce3d968 100644
--- a/src/nvim/syntax.c
+++ b/src/nvim/syntax.c
@@ -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
/// following names, separated by commas (but no spaces!).
static char *(hl_name_table[]) =
-{ "bold", "standout", "underline", "undercurl",
- "italic", "reverse", "inverse", "strikethrough", "nocombine", "NONE" };
+{ "bold", "standout", "underline", "underlineline", "undercurl", "underdot",
+ "underdash", "italic", "reverse", "inverse", "strikethrough", "nocombine", "NONE" };
static int hl_attr_table[] =
-{ HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE,
- HL_INVERSE, HL_STRIKETHROUGH, HL_NOCOMBINE, 0 };
+{ HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERLINELINE, HL_UNDERCURL, HL_UNDERDOT, HL_UNDERDASH,
+ HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_STRIKETHROUGH, HL_NOCOMBINE, 0 };
static char e_illegal_arg[] = N_("E390: Illegal argument: %s");
diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c
index 58061f020d..1ad82b7290 100644
--- a/src/nvim/tui/tui.c
+++ b/src/nvim/tui/tui.c
@@ -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
|| a1.cterm_bg_color != a2.cterm_bg_color
|| 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);
}
}
@@ -552,15 +552,27 @@ static void update_attrs(UI *ui, int attr_id)
bool strikethrough = attr & HL_STRIKETHROUGH;
bool underline;
+ bool underlineline;
bool undercurl;
+ bool underdot;
+ bool underdash;
if (data->unibi_ext.set_underline_style != -1) {
underline = attr & HL_UNDERLINE;
+ underlineline = attr & HL_UNDERLINELINE;
undercurl = attr & HL_UNDERCURL;
+ underdash = attr & HL_UNDERDASH;
+ underdot = attr & HL_UNDERDOT;
} else {
- underline = (attr & HL_UNDERLINE) || (attr & HL_UNDERCURL);
+ underline = attr & HL_ANY_UNDERLINE;
+ underlineline = 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 (bold || reverse || underline || 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) {
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) {
UNIBI_SET_NUM_VAR(data->params[0], 3);
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;
if (color != -1) {
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
- && !bold && !italic && !underline && !undercurl && !reverse && !standout
+ && !bold && !italic && !has_any_underline && !reverse && !standout
&& !strikethrough;
// 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
// 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);
}