From f89fb41a7a8b499159bfa44afa26dd17a845af45 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Wed, 2 Mar 2022 00:48:11 +0300 Subject: [PATCH 1/4] feat(tui): add support for `CSI 4 : [2,4,5] m` This commit finishes support for colored and styled underlines adding `CSI 4 : [2,4,5] m` support providing double, dashed, and dotted underlines Fixes #17362. --- runtime/doc/builtin.txt | 5 +++- runtime/doc/syntax.txt | 15 +++++++---- runtime/doc/ui.txt | 36 ++++++++++++++++---------- runtime/syntax/vim.vim | 2 +- src/nvim/api/keysets.lua | 6 +++++ src/nvim/eval/funcs.c | 16 +++++++++--- src/nvim/hardcopy.c | 3 +++ src/nvim/hardcopy.h | 3 +++ src/nvim/highlight.c | 20 ++++++++++++-- src/nvim/highlight_defs.h | 4 +++ src/nvim/syntax.c | 8 +++--- src/nvim/tui/tui.c | 35 +++++++++++++++++++++---- test/functional/api/highlight_spec.lua | 15 ++++++++--- test/functional/ui/screen.lua | 9 ++++--- 14 files changed, 134 insertions(+), 43 deletions(-) diff --git a/runtime/doc/builtin.txt b/runtime/doc/builtin.txt index 03a5f98c6d..b0859d1cea 100644 --- a/runtime/doc/builtin.txt +++ b/runtime/doc/builtin.txt @@ -7937,8 +7937,11 @@ synIDattr({synID}, {what} [, {mode}]) *synIDattr()* "inverse" "1" if inverse (= reverse) "standout" "1" if standout "underline" "1" if underlined + "underlineline" "1" if double underlined "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 cursor): > diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 778f829a4e..7383848b04 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -4875,7 +4875,8 @@ the same syntax file on all UIs. 1. TUI highlight arguments - *bold* *underline* *undercurl* + *bold* *underline* *underlineline* + *undercurl* *underdot* *underdash* *inverse* *italic* *standout* *nocombine* *strikethrough* 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): bold underline + underlineline double underline undercurl curly underline + underdot dotted underline + underdash dashed underline strikethrough 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 have the same effect. - "undercurl" falls back to "underline" in a terminal that does not - support it. The color is set using |highlight-guisp|. + "underlineline", "undercurl", "underdot", and "underdash" falls back + to "underline" in a terminal that does not support it. The color is set + using |highlight-guisp|. start={term-list} *highlight-start* *E422* stop={term-list} *term-list* *highlight-stop* @@ -5028,8 +5033,8 @@ guifg={color-name} *highlight-guifg* guibg={color-name} *highlight-guibg* guisp={color-name} *highlight-guisp* These give the foreground (guifg), background (guibg) and special - (guisp) color to use in the GUI. "guisp" is used for undercurl - and underline. + (guisp) color to use in the GUI. "guisp" is used for various + underlines. There are a few special names: NONE no color (transparent) bg use normal background color diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index e7be14e732..7c394a66c2 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -283,19 +283,24 @@ numerical highlight ids to the actual attributes. attributes specified by the `rgb_attr` and `cterm_attr` dicts, with the following (all optional) keys. - `foreground`: foreground color. - `background`: background color. - `special`: color to use for underline and undercurl, when present. - `reverse`: reverse video. Foreground and background colors are - switched. - `italic`: italic text. - `bold`: bold text. - `strikethrough`: struckthrough text. - `underline`: underlined text. The line has `special` color. - `undercurl`: undercurled text. The curl has `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. + `foreground`: foreground color. + `background`: background color. + `special`: color to use for various underlines, when + present. + `reverse`: reverse video. Foreground and background colors + are switched. + `italic`: italic text. + `bold`: bold text. + `strikethrough`: struckthrough text. + `underline`: underlined text. The line has `special` color. + `underlineline`: double underlined text. The lines has `special` + color. + `undercurl`: undercurled text. The curl has `special` color. + `underdot`: underdotted text. The dots has `special` color. + `underdash`: underdashed text. The dashes has `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 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. `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 switched. `italic`: italic text. `bold`: bold text. `strikethrough`: struckthrough text. `underline`: underlined text. The line has `special` color. + `underlineline`: double underlined text. The lines has `special` color. `undercurl`: undercurled text. The curl has `special` color. + `underdot`: underdotted text. The dots has `special` color. + `underdash`: underdashed text. The dashes has `special` color. ["put", text] The (utf-8 encoded) string `text` is put at the cursor position diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index 41993b65b0..d8b8bce657 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -574,7 +574,7 @@ syn match vimHiBang contained "!" skipwhite nextgroup=@vimHighlightCluster syn match vimHiGroup contained "\i\+" 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 case match syn match vimHiAttribList contained "\i\+" contains=vimHiAttrib 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 49dde537c3..b688e087ed 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -11409,14 +11409,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': { + int 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 > 5 && 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 db10b71d38..38cb6fa861 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); } diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua index 443689754c..06cdb0bc19 100644 --- a/test/functional/api/highlight_spec.lua +++ b/test/functional/api/highlight_spec.lua @@ -28,8 +28,11 @@ describe('API: highlight',function() bold = true, italic = true, reverse = true, - undercurl = true, underline = true, + underlineline = true, + undercurl = true, + underdot = true, + underdash = true, strikethrough = true, } @@ -52,7 +55,7 @@ describe('API: highlight',function() eq('Invalid highlight id: 30000', string.match(emsg, 'Invalid.*')) -- 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)) -- Test nil argument. @@ -195,6 +198,9 @@ describe("API: set highlight", function() reverse = true, undercurl = true, underline = true, + underdash = true, + underdot = true, + underlineline = true, strikethrough = true, cterm = { italic = true, @@ -211,6 +217,9 @@ describe("API: set highlight", function() reverse = true, undercurl = true, underline = true, + underdash = true, + underdot = true, + underlineline = true, strikethrough = true, } local highlight3_result_cterm = { @@ -274,7 +283,7 @@ describe("API: set highlight", function() exec_capture('highlight Test_hl')) 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')) -- Colors are stored exactly as they are defined. diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index a5af898652..3e94fdbf44 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -1559,10 +1559,11 @@ end function Screen:_equal_attrs(a, b) return a.bold == b.bold and a.standout == b.standout and - a.underline == b.underline and a.undercurl == b.undercurl and - a.italic == b.italic 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.underline == b.underline and a.underlineline == b.underlineline and + a.undercurl == b.undercurl and a.underdot == b.underdot and + a.underdash == b.underdash and a.italic == b.italic 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.fg_indexed == b.fg_indexed and a.bg_indexed == b.bg_indexed end From 44728201820470324e70a93cf48210f0a68f56a2 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Fri, 4 Mar 2022 00:35:03 +0300 Subject: [PATCH 2/4] fix(docs): spelling in new underlines docs --- runtime/doc/syntax.txt | 6 +++--- runtime/doc/ui.txt | 12 ++++++------ 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/runtime/doc/syntax.txt b/runtime/doc/syntax.txt index 7383848b04..9084c5315a 100644 --- a/runtime/doc/syntax.txt +++ b/runtime/doc/syntax.txt @@ -4898,9 +4898,9 @@ cterm={attr-list} *attr-list* *highlight-cterm* *E418* Note that "bold" can be used here and by using a bold font. They have the same effect. - "underlineline", "undercurl", "underdot", and "underdash" falls back - to "underline" in a terminal that does not support it. The color is set - using |highlight-guisp|. + "underlineline", "undercurl", "underdot", and "underdash" fall back + to "underline" in a terminal that does not support them. The color is + set using |highlight-guisp|. start={term-list} *highlight-start* *E422* stop={term-list} *term-list* *highlight-stop* diff --git a/runtime/doc/ui.txt b/runtime/doc/ui.txt index 7c394a66c2..c5e3b60079 100644 --- a/runtime/doc/ui.txt +++ b/runtime/doc/ui.txt @@ -293,11 +293,11 @@ numerical highlight ids to the actual attributes. `bold`: bold text. `strikethrough`: struckthrough text. `underline`: underlined text. The line has `special` color. - `underlineline`: double underlined text. The lines has `special` + `underlineline`: double underlined text. The lines have `special` color. `undercurl`: undercurled text. The curl has `special` color. - `underdot`: underdotted text. The dots has `special` color. - `underdash`: underdashed text. The dashes 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. @@ -456,10 +456,10 @@ is not active. New UIs should implement |ui-linegrid| instead. `bold`: bold text. `strikethrough`: struckthrough text. `underline`: underlined text. The line has `special` color. - `underlineline`: double underlined text. The lines has `special` color. + `underlineline`: double underlined text. The lines have `special` color. `undercurl`: undercurled text. The curl has `special` color. - `underdot`: underdotted text. The dots has `special` color. - `underdash`: underdashed text. The dashes has `special` color. + `underdot`: underdotted text. The dots have `special` color. + `underdash`: underdashed text. The dashes have `special` color. ["put", text] The (utf-8 encoded) string `text` is put at the cursor position From 6795c9772b07a7eeb154bf9cc132bf50fa4ddcaa Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Fri, 4 Mar 2022 15:35:44 +0300 Subject: [PATCH 3/4] fix(syntax): remove trailing spaces in vim.vim --- runtime/syntax/vim.vim | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/runtime/syntax/vim.vim b/runtime/syntax/vim.vim index d8b8bce657..0bc233fc2a 100644 --- a/runtime/syntax/vim.vim +++ b/runtime/syntax/vim.vim @@ -46,14 +46,14 @@ syn match vimTermOption contained "t_%i" syn match vimTermOption contained "t_k;" " 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 syn case ignore " 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 -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 keyword vimOnlyHLGroup contained LineNrAbove LineNrBelow StatusLineTerm Terminal VisualNOS syn keyword nvimHLGroup contained Substitute TermCursor TermCursorNC @@ -88,10 +88,10 @@ if exists("g:vimsyn_folding") && g:vimsyn_folding =~# '[afhlmpPrt]' else com! -nargs=* VimFoldm endif - if g:vimsyn_folding =~# 'p' - com! -nargs=* VimFoldp fold - else - com! -nargs=* VimFoldp + if g:vimsyn_folding =~# 'p' + com! -nargs=* VimFoldp fold + else + com! -nargs=* VimFoldp endif if g:vimsyn_folding =~# 'P' com! -nargs=* VimFoldP 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 '\%(^\|\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[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[0-7]\+' 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 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 case ignore -syn keyword vimHiAttrib contained none bold inverse italic nocombine reverse standout strikethrough underline underlineline undercurl underdot underdash +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 case match syn match vimHiAttribList contained "\i\+" contains=vimHiAttrib From 7fd1182c62d6e969ac15b3891bfcc4ff480d6953 Mon Sep 17 00:00:00 2001 From: Kirill Chibisov Date: Sat, 5 Mar 2022 19:16:14 +0300 Subject: [PATCH 4/4] fix: bounds check for underdot --- src/nvim/eval/funcs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index b688e087ed..8a1b6f081b 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -11410,14 +11410,14 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr) } break; case 'u': { - int len = STRLEN(what); + 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 > 5 && TOLOWER_ASC(what[6]) == 'o') { // underdot + } 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);