syntax, TUI: support "strikethrough"

fix #3436

Includes:
vim-patch:8.0.1038: strike-through text not supported
This commit is contained in:
Jaskaran Singh
2019-09-14 03:16:19 +05:30
committed by Justin M. Keyes
parent 35341b34b8
commit 3afb397407
14 changed files with 81 additions and 18 deletions

View File

@@ -8397,6 +8397,7 @@ synIDattr({synID}, {what} [, {mode}]) *synIDattr()*
"standout" "1" if standout "standout" "1" if standout
"underline" "1" if underlined "underline" "1" if underlined
"undercurl" "1" if undercurled "undercurl" "1" if undercurled
"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

@@ -4720,6 +4720,7 @@ the same syntax file on all UIs.
*bold* *underline* *undercurl* *bold* *underline* *undercurl*
*inverse* *italic* *standout* *inverse* *italic* *standout*
*strikethrough*
cterm={attr-list} *attr-list* *highlight-cterm* *E418* cterm={attr-list} *attr-list* *highlight-cterm* *E418*
attr-list is a comma separated list (without spaces) of the attr-list is a comma separated list (without spaces) of the
following items (in any order): following items (in any order):
@@ -4730,6 +4731,7 @@ cterm={attr-list} *attr-list* *highlight-cterm* *E418*
inverse same as reverse inverse same as reverse
italic italic
standout standout
strikethrough
NONE no attributes used (used to reset it) NONE no attributes used (used to reset it)
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

View File

@@ -290,6 +290,7 @@ numerical highlight ids to the actual attributes.
switched. switched.
`italic`: italic text. `italic`: italic text.
`bold`: bold text. `bold`: bold text.
`strikethrough`: struckthrough text.
`underline`: underlined text. The line has `special` color. `underline`: underlined text. The line has `special` color.
`undercurl`: undercurled text. The curl has `special` color. `undercurl`: undercurled text. The curl has `special` color.
`blend`: Blend level (0-100). Could be used by UIs to support `blend`: Blend level (0-100). Could be used by UIs to support
@@ -447,6 +448,7 @@ is not active. New UIs should implement |ui-linegrid| instead.
switched. switched.
`italic`: italic text. `italic`: italic text.
`bold`: bold text. `bold`: bold text.
`strikethrough`: struckthrough text.
`underline`: underlined text. The line has `special` color. `underline`: underlined text. The line has `special` color.
`undercurl`: undercurled text. The curl has `special` color. `undercurl`: undercurled text. The curl has `special` color.

View File

@@ -17584,6 +17584,9 @@ static void f_synIDattr(typval_T *argvars, typval_T *rettv, FunPtr fptr)
case 's': { case 's': {
if (TOLOWER_ASC(what[1]) == 'p') { // sp[#] if (TOLOWER_ASC(what[1]) == 'p') { // sp[#]
p = highlight_color(id, what, modec); p = highlight_color(id, what, modec);
} else if (TOLOWER_ASC(what[1]) == 't'
&& TOLOWER_ASC(what[2]) == 'r') { // strikethrough
p = highlight_has_attr(id, HL_STRIKETHROUGH, modec);
} else { // standout } else { // standout
p = highlight_has_attr(id, HL_STANDOUT, modec); p = highlight_has_attr(id, HL_STANDOUT, modec);
} }

View File

@@ -598,6 +598,10 @@ Dictionary hlattrs2dict(HlAttrs ae, bool use_rgb)
PUT(hl, "reverse", BOOLEAN_OBJ(true)); PUT(hl, "reverse", BOOLEAN_OBJ(true));
} }
if (mask & HL_STRIKETHROUGH) {
PUT(hl, "strikethrough", BOOLEAN_OBJ(true));
}
if (use_rgb) { if (use_rgb) {
if (ae.rgb_fg_color != -1) { if (ae.rgb_fg_color != -1) {
PUT(hl, "foreground", INTEGER_OBJ(ae.rgb_fg_color)); PUT(hl, "foreground", INTEGER_OBJ(ae.rgb_fg_color));

View File

@@ -11,12 +11,13 @@ typedef int32_t RgbValue;
/// ///
/// sign bit should not be used here, as it identifies invalid highlight /// sign bit should not be used here, as it identifies invalid highlight
typedef enum { typedef enum {
HL_INVERSE = 0x01, HL_INVERSE = 0x01,
HL_BOLD = 0x02, HL_BOLD = 0x02,
HL_ITALIC = 0x04, HL_ITALIC = 0x04,
HL_UNDERLINE = 0x08, HL_UNDERLINE = 0x08,
HL_UNDERCURL = 0x10, HL_UNDERCURL = 0x10,
HL_STANDOUT = 0x20, HL_STANDOUT = 0x20,
HL_STRIKETHROUGH = 0x40,
} HlAttrFlags; } HlAttrFlags;
/// Stores a complete highlighting entry, including colors and attributes /// Stores a complete highlighting entry, including colors and attributes

View File

@@ -115,11 +115,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", "undercurl",
"italic", "reverse", "inverse", "NONE"}; "italic", "reverse", "inverse", "strikethrough", "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_UNDERCURL, HL_ITALIC, HL_INVERSE,
HL_INVERSE, 0}; HL_INVERSE, HL_STRIKETHROUGH, 0 };
// The patterns that are being searched for are stored in a syn_pattern. // The patterns that are being searched for are stored in a syn_pattern.
// A match item consists of one pattern. // A match item consists of one pattern.

View File

@@ -605,7 +605,8 @@ void terminal_get_line_attributes(Terminal *term, win_T *wp, int linenr,
int hl_attrs = (cell.attrs.bold ? HL_BOLD : 0) int hl_attrs = (cell.attrs.bold ? HL_BOLD : 0)
| (cell.attrs.italic ? HL_ITALIC : 0) | (cell.attrs.italic ? HL_ITALIC : 0)
| (cell.attrs.reverse ? HL_INVERSE : 0) | (cell.attrs.reverse ? HL_INVERSE : 0)
| (cell.attrs.underline ? HL_UNDERLINE : 0); | (cell.attrs.underline ? HL_UNDERLINE : 0)
| (cell.attrs.strike ? HL_STRIKETHROUGH: 0);
int attr_id = 0; int attr_id = 0;

View File

@@ -115,6 +115,7 @@ typedef struct {
int enable_mouse, disable_mouse; int enable_mouse, disable_mouse;
int enable_bracketed_paste, disable_bracketed_paste; int enable_bracketed_paste, disable_bracketed_paste;
int enable_lr_margin, disable_lr_margin; int enable_lr_margin, disable_lr_margin;
int enter_strikethrough_mode;
int set_rgb_foreground, set_rgb_background; int set_rgb_foreground, set_rgb_background;
int set_cursor_color; int set_cursor_color;
int reset_cursor_color; int reset_cursor_color;
@@ -208,6 +209,7 @@ static void terminfo_start(UI *ui)
data->unibi_ext.reset_cursor_color = -1; data->unibi_ext.reset_cursor_color = -1;
data->unibi_ext.enable_bracketed_paste = -1; data->unibi_ext.enable_bracketed_paste = -1;
data->unibi_ext.disable_bracketed_paste = -1; data->unibi_ext.disable_bracketed_paste = -1;
data->unibi_ext.enter_strikethrough_mode = -1;
data->unibi_ext.enable_lr_margin = -1; data->unibi_ext.enable_lr_margin = -1;
data->unibi_ext.disable_lr_margin = -1; data->unibi_ext.disable_lr_margin = -1;
data->unibi_ext.enable_focus_reporting = -1; data->unibi_ext.enable_focus_reporting = -1;
@@ -529,6 +531,7 @@ static void update_attrs(UI *ui, int attr_id)
bool italic = attr & HL_ITALIC; bool italic = attr & HL_ITALIC;
bool reverse = attr & HL_INVERSE; bool reverse = attr & HL_INVERSE;
bool standout = attr & HL_STANDOUT; bool standout = attr & HL_STANDOUT;
bool strikethrough = attr & HL_STRIKETHROUGH;
bool underline; bool underline;
bool undercurl; bool undercurl;
@@ -575,6 +578,9 @@ static void update_attrs(UI *ui, int attr_id)
if (italic) { if (italic) {
unibi_out(ui, unibi_enter_italics_mode); unibi_out(ui, unibi_enter_italics_mode);
} }
if (strikethrough && data->unibi_ext.enter_strikethrough_mode != -1) {
unibi_out_ext(ui, data->unibi_ext.enter_strikethrough_mode);
}
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);
@@ -615,13 +621,14 @@ 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 && !underline && !undercurl && !reverse && !standout
&& !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 && !underline && !undercurl
&& (data->bce || bg == -1); && !strikethrough && (data->bce || bg == -1);
} }
static void final_column_wrap(UI *ui) static void final_column_wrap(UI *ui)
@@ -1826,6 +1833,11 @@ static void augment_terminfo(TUIData *data, const char *term,
"\x1b[r"); "\x1b[r");
} }
// terminfo describes strikethrough modes as rmxx/smxx with respect
// to the ECMA-48 strikeout/crossed-out attributes.
data->unibi_ext.enter_strikethrough_mode = (int)unibi_find_ext_str(
ut, "smxx");
// Dickey ncurses terminfo does not include the setrgbf and setrgbb // Dickey ncurses terminfo does not include the setrgbf and setrgbb
// capabilities, proposed by Rüdiger Sonderfeld on 2013-10-15. Adding // capabilities, proposed by Rüdiger Sonderfeld on 2013-10-15. Adding
// them here when terminfo lacks them is an augmentation, not a fixup. // them here when terminfo lacks them is an augmentation, not a fixup.

View File

@@ -25,6 +25,7 @@ describe('API: highlight',function()
reverse = true, reverse = true,
undercurl = true, undercurl = true,
underline = true, underline = true,
strikethrough = true,
} }
before_each(function() before_each(function()
@@ -46,7 +47,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') command('hi NewHighlight gui=underline,bold,undercurl,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.

View File

@@ -29,6 +29,7 @@ local function set_bg(num) feed_termcode('[48;5;'..num..'m') end
local function set_bold() feed_termcode('[1m') end local function set_bold() feed_termcode('[1m') end
local function set_italic() feed_termcode('[3m') end local function set_italic() feed_termcode('[3m') end
local function set_underline() feed_termcode('[4m') end local function set_underline() feed_termcode('[4m') end
local function set_strikethrough() feed_termcode('[9m') end
local function clear_attrs() feed_termcode('[0;10m') end local function clear_attrs() feed_termcode('[0;10m') end
-- mouse -- mouse
local function enable_mouse() feed_termcode('[?1002h') end local function enable_mouse() feed_termcode('[?1002h') end
@@ -113,6 +114,7 @@ return {
set_bold = set_bold, set_bold = set_bold,
set_italic = set_italic, set_italic = set_italic,
set_underline = set_underline, set_underline = set_underline,
set_strikethrough = set_strikethrough,
clear_attrs = clear_attrs, clear_attrs = clear_attrs,
enable_mouse = enable_mouse, enable_mouse = enable_mouse,
disable_mouse = disable_mouse, disable_mouse = disable_mouse,

View File

@@ -18,7 +18,7 @@ describe(':terminal highlight', function()
[1] = {foreground = 45}, [1] = {foreground = 45},
[2] = {background = 46}, [2] = {background = 46},
[3] = {foreground = 45, background = 46}, [3] = {foreground = 45, background = 46},
[4] = {bold = true, italic = true, underline = true}, [4] = {bold = true, italic = true, underline = true, strikethrough = true},
[5] = {bold = true}, [5] = {bold = true},
[6] = {foreground = 12}, [6] = {foreground = 12},
[7] = {bold = true, reverse = true}, [7] = {bold = true, reverse = true},
@@ -108,10 +108,11 @@ describe(':terminal highlight', function()
thelpers.set_fg(45) thelpers.set_fg(45)
thelpers.set_bg(46) thelpers.set_bg(46)
end) end)
descr('bold, italics and underline', 4, function() descr('bold, italics, underline and strikethrough', 4, function()
thelpers.set_bold() thelpers.set_bold()
thelpers.set_italic() thelpers.set_italic()
thelpers.set_underline() thelpers.set_underline()
thelpers.set_strikethrough()
end) end)
end) end)
@@ -215,7 +216,7 @@ describe('synIDattr()', function()
screen = Screen.new(50, 7) screen = Screen.new(50, 7)
command('highlight Normal ctermfg=252 guifg=#ff0000 guibg=Black') command('highlight Normal ctermfg=252 guifg=#ff0000 guibg=Black')
-- Salmon #fa8072 Maroon #800000 -- Salmon #fa8072 Maroon #800000
command('highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon') command('highlight Keyword ctermfg=79 guifg=Salmon guisp=Maroon cterm=strikethrough gui=strikethrough')
end) end)
it('returns cterm-color if RGB-capable UI is _not_ attached', function() it('returns cterm-color if RGB-capable UI is _not_ attached', function()
@@ -255,6 +256,12 @@ describe('synIDattr()', function()
eq('252', eval('synIDattr(hlID("Normal"), "fg")')) eq('252', eval('synIDattr(hlID("Normal"), "fg")'))
eq('79', eval('synIDattr(hlID("Keyword"), "fg")')) eq('79', eval('synIDattr(hlID("Keyword"), "fg")'))
end) end)
it('returns "1" if group has "strikethrough" attribute', function()
eq('', eval('synIDattr(hlID("Normal"), "strikethrough")'))
eq('1', eval('synIDattr(hlID("Keyword"), "strikethrough")'))
eq('1', eval('synIDattr(hlID("Keyword"), "strikethrough", "gui")'))
end)
end) end)
describe('fg/bg special colors', function() describe('fg/bg special colors', function()

View File

@@ -412,6 +412,32 @@ describe('highlight', function()
]]) ]])
end) end)
it('strikethrough', function()
screen:detach()
screen = Screen.new(25,6)
screen:attach()
feed_command('syntax on')
feed_command('syn keyword TmpKeyword foo')
feed_command('hi! Awesome cterm=strikethrough gui=strikethrough')
feed_command('hi link TmpKeyword Awesome')
insert([[
foo
foo bar
foobarfoobar
]])
screen:expect([[
{1:foo} |
{1:foo} bar |
foobarfoobar |
^ |
{2:~ }|
|
]],{
[1] = {strikethrough = true},
[2] = {bold = true, foreground = Screen.colors.Blue1},
})
end)
it('guisp (special/undercurl)', function() it('guisp (special/undercurl)', function()
feed_command('syntax on') feed_command('syntax on')
feed_command('syn keyword TmpKeyword neovim') feed_command('syn keyword TmpKeyword neovim')

View File

@@ -1509,7 +1509,8 @@ function Screen:_equal_attrs(a, b)
a.underline == b.underline and a.undercurl == b.undercurl and a.underline == b.underline and a.undercurl == b.undercurl and
a.italic == b.italic and a.reverse == b.reverse and a.italic == b.italic and a.reverse == b.reverse and
a.foreground == b.foreground and a.background == b.background and a.foreground == b.foreground and a.background == b.background and
a.special == b.special and a.blend == b.blend a.special == b.special and a.blend == b.blend and
a.strikethrough == b.strikethrough
end end
function Screen:_equal_info(a, b) function Screen:_equal_info(a, b)