patch 8.2.0863: cannot set a separate color for underline/undercurl

Problem:    Cannot set a separate color for underline/undercurl.
Solution:   Add the t_AU and t_8u termcap codes. (Timur Celik, closes #6011)
This commit is contained in:
Bram Moolenaar
2020-05-31 16:42:30 +02:00
parent b10090928c
commit e023e88bed
12 changed files with 118 additions and 24 deletions

View File

@ -4901,6 +4901,10 @@ cterm={attr-list} *highlight-cterm*
ctermfg={color-nr} *highlight-ctermfg* *E421*
ctermbg={color-nr} *highlight-ctermbg*
ctermul={color-nr} *highlight-ctermul*
These give the foreground (ctermfg), background (ctermbg) and
underline (ctermul) color to use in the terminal.
The {color-nr} argument is a color number. Its range is zero to
(not including) the number given by the termcap entry "Co".
The actual color with this number depends on the type of terminal
@ -4978,11 +4982,11 @@ ctermbg={color-nr} *highlight-ctermbg*
needs to reset the color when exiting. This is done with the "op"
termcap entry |t_op|. If this doesn't work correctly, try setting the
't_op' option in your .vimrc.
*E419* *E420*
When Vim knows the normal foreground and background colors, "fg" and
"bg" can be used as color names. This only works after setting the
colors for the Normal group and for the MS-Windows console. Example,
for reverse video: >
*E419* *E420* *E453*
When Vim knows the normal foreground, background and underline colors,
"fg", "bg" and "ul" can be used as color names. This only works after
setting the colors for the Normal group and for the MS-Windows
console. Example, for reverse video: >
:highlight Visual ctermfg=bg ctermbg=fg
< Note that the colors are used that are valid at the moment this
command are given. If the Normal group colors are changed later, the

View File

@ -322,6 +322,7 @@ OUTPUT CODES *terminal-output-codes*
t_ZR italics end *t_ZR* *'t_ZR'*
Added by Vim (there are no standard codes for these):
t_AU set underline color (ANSI) *t_AU* *'t_AU'*
t_Ce undercurl end *t_Ce* *'t_Ce'*
t_Cs undercurl mode *t_Cs* *'t_Cs'*
t_Te strikethrough end *t_Te* *'t_Te'*
@ -350,6 +351,7 @@ Added by Vim (there are no standard codes for these):
|xterm-true-color|
t_8b set background color (R, G, B) *t_8b* *'t_8b'*
|xterm-true-color|
t_8u set underline color (R, G, B) *t_8u* *'t_8u'*
t_BE enable bracketed paste mode *t_BE* *'t_BE'*
|xterm-bracketed-paste|
t_BD disable bracketed paste mode *t_BD* *'t_BD'*

View File

@ -485,9 +485,11 @@ EXTERN char_u *use_gvimrc INIT(= NULL); // "-U" cmdline argument
EXTERN int cterm_normal_fg_color INIT(= 0);
EXTERN int cterm_normal_fg_bold INIT(= 0);
EXTERN int cterm_normal_bg_color INIT(= 0);
EXTERN int cterm_normal_ul_color INIT(= 0);
#ifdef FEAT_TERMGUICOLORS
EXTERN guicolor_T cterm_normal_fg_gui_color INIT(= INVALCOLOR);
EXTERN guicolor_T cterm_normal_bg_gui_color INIT(= INVALCOLOR);
EXTERN guicolor_T cterm_normal_ul_gui_color INIT(= INVALCOLOR);
#endif
#ifdef FEAT_TERMRESPONSE
EXTERN int is_mac_terminal INIT(= FALSE); // recognized Terminal.app

View File

@ -50,14 +50,15 @@ typedef struct
int sg_cterm_bold; // bold attr was set for light color
int sg_cterm_fg; // terminal fg color number + 1
int sg_cterm_bg; // terminal bg color number + 1
int sg_cterm_ul; // terminal ul color number + 1
int sg_cterm_attr; // Screen attr for color term mode
// for when using the GUI
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
guicolor_T sg_gui_fg; // GUI foreground color handle
guicolor_T sg_gui_bg; // GUI background color handle
guicolor_T sg_gui_sp; // GUI special color handle
#endif
#ifdef FEAT_GUI
guicolor_T sg_gui_sp; // GUI special color handle
GuiFont sg_font; // GUI font handle
#ifdef FEAT_XFONTSET
GuiFontset sg_fontset; // GUI fontset handle
@ -1095,7 +1096,8 @@ do_highlight(
}
#endif
}
else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0)
else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0
|| STRCMP(key, "CTERMUL") == 0)
{
if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
{
@ -1134,6 +1136,17 @@ do_highlight(
break;
}
}
else if (STRICMP(arg, "ul") == 0)
{
if (cterm_normal_ul_color > 0)
color = cterm_normal_ul_color - 1;
else
{
emsg(_("E453: UL color unknown"));
error = TRUE;
break;
}
}
else
{
int bold = MAYBE;
@ -1184,7 +1197,7 @@ do_highlight(
}
}
}
else
else if (key[5] == 'B')
{
HL_TABLE()[idx].sg_cterm_bg = color + 1;
if (is_normal_group)
@ -1221,6 +1234,23 @@ do_highlight(
}
}
}
else // ctermul
{
HL_TABLE()[idx].sg_cterm_ul = color + 1;
if (is_normal_group)
{
cterm_normal_ul_color = color + 1;
#ifdef FEAT_GUI
// Don't do this if the GUI is used.
if (!gui.in_use && !gui.starting)
#endif
{
must_redraw = CLEAR;
if (termcap_active && color >= 0)
term_ul_color(color);
}
}
}
}
}
else if (STRCMP(key, "GUIFG") == 0)
@ -1335,9 +1365,10 @@ do_highlight(
if (!init)
HL_TABLE()[idx].sg_set |= SG_GUI;
# ifdef FEAT_GUI
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
// In GUI guisp colors are only used when recognized
i = color_name2handle(arg);
if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use)
if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
{
HL_TABLE()[idx].sg_gui_sp = i;
# endif
@ -1350,7 +1381,7 @@ do_highlight(
*namep = NULL;
did_change = TRUE;
}
# ifdef FEAT_GUI
# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
}
# endif
}
@ -1587,6 +1618,7 @@ restore_cterm_colors(void)
# ifdef FEAT_TERMGUICOLORS
cterm_normal_fg_gui_color = INVALCOLOR;
cterm_normal_bg_gui_color = INVALCOLOR;
cterm_normal_ul_gui_color = INVALCOLOR;
# endif
#endif
}
@ -1638,9 +1670,9 @@ highlight_clear(int idx)
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
HL_TABLE()[idx].sg_gui_fg = INVALCOLOR;
HL_TABLE()[idx].sg_gui_bg = INVALCOLOR;
HL_TABLE()[idx].sg_gui_sp = INVALCOLOR;
#endif
#ifdef FEAT_GUI
HL_TABLE()[idx].sg_gui_sp = INVALCOLOR;
gui_mch_free_font(HL_TABLE()[idx].sg_font);
HL_TABLE()[idx].sg_font = NOFONT;
# ifdef FEAT_XFONTSET
@ -2098,11 +2130,15 @@ get_attr_entry(garray_T *table, attrentry_T *aep)
== taep->ae_u.cterm.fg_color
&& aep->ae_u.cterm.bg_color
== taep->ae_u.cterm.bg_color
&& aep->ae_u.cterm.ul_color
== taep->ae_u.cterm.ul_color
#ifdef FEAT_TERMGUICOLORS
&& aep->ae_u.cterm.fg_rgb
== taep->ae_u.cterm.fg_rgb
&& aep->ae_u.cterm.bg_rgb
== taep->ae_u.cterm.bg_rgb
&& aep->ae_u.cterm.ul_rgb
== taep->ae_u.cterm.ul_rgb
#endif
)))
@ -2169,9 +2205,11 @@ get_attr_entry(garray_T *table, attrentry_T *aep)
{
taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color;
taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color;
taep->ae_u.cterm.ul_color = aep->ae_u.cterm.ul_color;
#ifdef FEAT_TERMGUICOLORS
taep->ae_u.cterm.fg_rgb = aep->ae_u.cterm.fg_rgb;
taep->ae_u.cterm.bg_rgb = aep->ae_u.cterm.bg_rgb;
taep->ae_u.cterm.ul_rgb = aep->ae_u.cterm.ul_rgb;
#endif
}
++table->ga_len;
@ -2344,6 +2382,7 @@ hl_combine_attr(int char_attr, int prim_attr)
#ifdef FEAT_TERMGUICOLORS
new_en.ae_u.cterm.bg_rgb = INVALCOLOR;
new_en.ae_u.cterm.fg_rgb = INVALCOLOR;
new_en.ae_u.cterm.ul_rgb = INVALCOLOR;
#endif
if (char_attr <= HL_ALL)
new_en.ae_attr = char_attr;
@ -2362,6 +2401,8 @@ hl_combine_attr(int char_attr, int prim_attr)
new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color;
if (spell_aep->ae_u.cterm.bg_color > 0)
new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color;
if (spell_aep->ae_u.cterm.ul_color > 0)
new_en.ae_u.cterm.ul_color = spell_aep->ae_u.cterm.ul_color;
#ifdef FEAT_TERMGUICOLORS
// If both fg and bg are not set fall back to cterm colors.
// Helps for SpellBad which uses undercurl in the GUI.
@ -2380,6 +2421,8 @@ hl_combine_attr(int char_attr, int prim_attr)
if (spell_aep->ae_u.cterm.bg_rgb != INVALCOLOR)
new_en.ae_u.cterm.bg_rgb = spell_aep->ae_u.cterm.bg_rgb;
}
if (spell_aep->ae_u.cterm.ul_rgb != INVALCOLOR)
new_en.ae_u.cterm.ul_rgb = spell_aep->ae_u.cterm.ul_rgb;
#endif
}
}
@ -2497,6 +2540,8 @@ highlight_list_one(int id)
sgp->sg_cterm_fg, NULL, "ctermfg");
didh = highlight_list_arg(id, didh, LIST_INT,
sgp->sg_cterm_bg, NULL, "ctermbg");
didh = highlight_list_arg(id, didh, LIST_INT,
sgp->sg_cterm_ul, NULL, "ctermul");
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
didh = highlight_list_arg(id, didh, LIST_ATTR,
@ -2662,11 +2707,7 @@ highlight_color(
if (fg)
color = HL_TABLE()[id - 1].sg_gui_fg;
else if (sp)
# ifdef FEAT_GUI
color = HL_TABLE()[id - 1].sg_gui_sp;
# else
color = INVALCOLOR;
# endif
else
color = HL_TABLE()[id - 1].sg_gui_bg;
if (color == INVALCOLOR)
@ -2847,10 +2888,11 @@ set_hl_attr(
* For the color term mode: If there are other than "normal"
* highlighting attributes, need to allocate an attr number.
*/
if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0
if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 && sgp->sg_cterm_ul == 0
# ifdef FEAT_TERMGUICOLORS
&& sgp->sg_gui_fg == INVALCOLOR
&& sgp->sg_gui_bg == INVALCOLOR
&& sgp->sg_gui_sp == INVALCOLOR
# endif
)
sgp->sg_cterm_attr = sgp->sg_cterm;
@ -2859,6 +2901,7 @@ set_hl_attr(
at_en.ae_attr = sgp->sg_cterm;
at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg;
at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg;
at_en.ae_u.cterm.ul_color = sgp->sg_cterm_ul;
# ifdef FEAT_TERMGUICOLORS
# ifdef MSWIN
# ifdef VIMDLL
@ -2883,6 +2926,7 @@ set_hl_attr(
# endif
at_en.ae_u.cterm.fg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_fg);
at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_bg);
at_en.ae_u.cterm.ul_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_sp);
if (at_en.ae_u.cterm.fg_rgb == INVALCOLOR
&& at_en.ae_u.cterm.bg_rgb == INVALCOLOR)
{
@ -3067,9 +3111,7 @@ syn_add_group(char_u *name)
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
HL_TABLE()[highlight_ga.ga_len].sg_gui_bg = INVALCOLOR;
HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR;
# ifdef FEAT_GUI
HL_TABLE()[highlight_ga.ga_len].sg_gui_sp = INVALCOLOR;
# endif
#endif
++highlight_ga.ga_len;
@ -3230,14 +3272,12 @@ gui_do_one_color(
color_name2handle(HL_TABLE()[idx].sg_gui_bg_name);
didit = TRUE;
}
# ifdef FEAT_GUI
if (HL_TABLE()[idx].sg_gui_sp_name != NULL)
{
HL_TABLE()[idx].sg_gui_sp =
color_name2handle(HL_TABLE()[idx].sg_gui_sp_name);
didit = TRUE;
}
# endif
if (didit) // need to get a new attr number
set_hl_attr(idx);
}

View File

@ -2924,6 +2924,7 @@ static struct vimoption options[] =
p_term("t_AB", T_CAB)
p_term("t_AF", T_CAF)
p_term("t_AU", T_CAU)
p_term("t_AL", T_CAL)
p_term("t_al", T_AL)
p_term("t_bc", T_BC)
@ -3002,6 +3003,7 @@ static struct vimoption options[] =
p_term("t_ZR", T_CZR)
p_term("t_8f", T_8F)
p_term("t_8b", T_8B)
p_term("t_8u", T_8U)
// terminal key codes are not in here

View File

@ -26,9 +26,11 @@ int term_get_winpos(int *x, int *y, varnumber_T timeout);
void term_set_winsize(int height, int width);
void term_fg_color(int n);
void term_bg_color(int n);
void term_ul_color(int n);
char_u *term_bg_default(void);
void term_fg_rgb_color(guicolor_T rgb);
void term_bg_rgb_color(guicolor_T rgb);
void term_ul_rgb_color(guicolor_T rgb);
void term_settitle(char_u *title);
void term_push_title(int which);
void term_pop_title(int which);

View File

@ -1866,6 +1866,19 @@ screen_start_highlight(int attr)
if (aep->ae_u.cterm.bg_color)
term_bg_color(aep->ae_u.cterm.bg_color - 1);
}
#ifdef FEAT_TERMGUICOLORS
if (p_tgc && aep->ae_u.cterm.ul_rgb != CTERMCOLOR)
{
if (aep->ae_u.cterm.ul_rgb != INVALCOLOR)
term_ul_rgb_color(aep->ae_u.cterm.ul_rgb);
}
else
#endif
if (t_colors > 1)
{
if (aep->ae_u.cterm.ul_color)
term_ul_color(aep->ae_u.cterm.ul_color - 1);
}
if (!IS_CTERM)
{
@ -2021,6 +2034,8 @@ screen_stop_highlight(void)
term_fg_rgb_color(cterm_normal_fg_gui_color);
if (cterm_normal_bg_gui_color != INVALCOLOR)
term_bg_rgb_color(cterm_normal_bg_gui_color);
if (cterm_normal_ul_gui_color != INVALCOLOR)
term_ul_rgb_color(cterm_normal_ul_gui_color);
}
else
#endif
@ -2032,6 +2047,8 @@ screen_stop_highlight(void)
term_fg_color(cterm_normal_fg_color - 1);
if (cterm_normal_bg_color != 0)
term_bg_color(cterm_normal_bg_color - 1);
if (cterm_normal_ul_color != 0)
term_ul_color(cterm_normal_ul_color - 1);
if (cterm_normal_fg_bold)
out_str(T_MD);
}

View File

@ -1068,9 +1068,11 @@ typedef struct attr_entry
// These colors need to be > 8 bits to hold 256.
short_u fg_color; // foreground color number
short_u bg_color; // background color number
short_u ul_color; // underline color number
# ifdef FEAT_TERMGUICOLORS
guicolor_T fg_rgb; // foreground color RGB
guicolor_T bg_rgb; // background color RGB
guicolor_T ul_rgb; // underline color RGB
# endif
} cterm;
# ifdef FEAT_GUI

View File

@ -928,7 +928,9 @@ static struct builtin_term builtin_termcaps[] =
// These are printf strings, not terminal codes.
{(int)KS_8F, IF_EB("\033[38;2;%lu;%lu;%lum", ESC_STR "[38;2;%lu;%lu;%lum")},
{(int)KS_8B, IF_EB("\033[48;2;%lu;%lu;%lum", ESC_STR "[48;2;%lu;%lu;%lum")},
{(int)KS_8U, IF_EB("\033[58;2;%lu;%lu;%lum", ESC_STR "[58;2;%lu;%lu;%lum")},
# endif
{(int)KS_CAU, IF_EB("\033[58;5;%dm", ESC_STR "[58;5;%dm")},
{(int)KS_CBE, IF_EB("\033[?2004h", ESC_STR "[?2004h")},
{(int)KS_CBD, IF_EB("\033[?2004l", ESC_STR "[?2004l")},
{(int)KS_CST, IF_EB("\033[22;2t", ESC_STR "[22;2t")},
@ -1187,6 +1189,7 @@ static struct builtin_term builtin_termcaps[] =
{(int)KS_CSB, "[CSB%d]"},
{(int)KS_CSF, "[CSF%d]"},
# endif
{(int)KS_CAU, "[CAU%d]"},
{(int)KS_OP, "[OP]"},
{(int)KS_LE, "[LE]"},
{(int)KS_CL, "[CL]"},
@ -1617,7 +1620,8 @@ get_term_entries(int *height, int *width)
{KS_KE, "ke"}, {KS_TI, "ti"}, {KS_TE, "te"},
{KS_CTI, "TI"}, {KS_CTE, "TE"},
{KS_BC, "bc"}, {KS_CSB,"Sb"}, {KS_CSF,"Sf"},
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_LE, "le"},
{KS_CAB,"AB"}, {KS_CAF,"AF"}, {KS_CAU,"AU"},
{KS_LE, "le"},
{KS_ND, "nd"}, {KS_OP, "op"}, {KS_CRV, "RV"},
{KS_VS, "vs"}, {KS_CVS, "VS"},
{KS_CIS, "IS"}, {KS_CIE, "IE"},
@ -1626,7 +1630,7 @@ get_term_entries(int *height, int *width)
{KS_CWP, "WP"}, {KS_CWS, "WS"},
{KS_CSI, "SI"}, {KS_CEI, "EI"},
{KS_U7, "u7"}, {KS_RFG, "RF"}, {KS_RBG, "RB"},
{KS_8F, "8f"}, {KS_8B, "8b"},
{KS_8F, "8f"}, {KS_8B, "8b"}, {KS_8U, "8u"},
{KS_CBE, "BE"}, {KS_CBD, "BD"},
{KS_CPS, "PS"}, {KS_CPE, "PE"},
{KS_CST, "ST"}, {KS_CRT, "RT"},
@ -2881,6 +2885,13 @@ term_bg_color(int n)
term_color(T_CSB, n);
}
void
term_ul_color(int n)
{
if (*T_CAU)
term_color(T_CAU, n);
}
/*
* Return "dark" or "light" depending on the kind of terminal.
* This is just guessing! Recognized are:
@ -2952,6 +2963,12 @@ term_bg_rgb_color(guicolor_T rgb)
{
term_rgb_color(T_8B, rgb);
}
void
term_ul_rgb_color(guicolor_T rgb)
{
term_rgb_color(T_8U, rgb);
}
#endif
#if (defined(FEAT_TITLE) && (defined(UNIX) || defined(VMS) \

View File

@ -78,6 +78,7 @@ enum SpecialKey
KS_MB, // blink mode
KS_CAF, // set foreground color (ANSI)
KS_CAB, // set background color (ANSI)
KS_CAU, // set underline color (ANSI)
KS_LE, // cursor left (mostly backspace)
KS_ND, // cursor right
KS_CIS, // set icon text start
@ -100,6 +101,7 @@ enum SpecialKey
KS_U7, // request cursor position
KS_8F, // set foreground color (RGB)
KS_8B, // set background color (RGB)
KS_8U, // set underline color (RGB)
KS_CBE, // enable bracketed paste mode
KS_CBD, // disable bracketed paste mode
KS_CPS, // start of bracketed paste
@ -179,6 +181,7 @@ extern char_u *(term_strings[]); // current terminal strings
#define T_MB (TERM_STR(KS_MB)) // blink mode
#define T_CAF (TERM_STR(KS_CAF)) // set foreground color (ANSI)
#define T_CAB (TERM_STR(KS_CAB)) // set background color (ANSI)
#define T_CAU (TERM_STR(KS_CAU)) // set underline color (ANSI)
#define T_LE (TERM_STR(KS_LE)) // cursor left
#define T_ND (TERM_STR(KS_ND)) // cursor right
#define T_CIS (TERM_STR(KS_CIS)) // set icon text start
@ -200,6 +203,7 @@ extern char_u *(term_strings[]); // current terminal strings
#define T_U7 (TERM_STR(KS_U7)) // request cursor position
#define T_8F (TERM_STR(KS_8F)) // set foreground color (RGB)
#define T_8B (TERM_STR(KS_8B)) // set background color (RGB)
#define T_8U (TERM_STR(KS_8U)) // set underline color (RGB)
#define T_BE (TERM_STR(KS_CBE)) // enable bracketed paste mode
#define T_BD (TERM_STR(KS_CBD)) // disable bracketed paste mode
#define T_PS (TERM_STR(KS_CPS)) // start of bracketed paste

View File

@ -275,7 +275,7 @@ func Test_set_completion()
" Expand terminal options.
call feedkeys(":set t_A\<C-A>\<C-B>\"\<CR>", 'tx')
call assert_equal('"set t_AB t_AF t_AL', @:)
call assert_equal('"set t_AB t_AF t_AU t_AL', @:)
call assert_fails('call feedkeys(":set <t_afoo>=\<C-A>\<CR>", "xt")', 'E474:')
" Expand directories.

View File

@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
863,
/**/
862,
/**/