Problem: Cannot set a separate color for underline/undercurl.
Solution: Add the t_AU and t_8u termcap codes. (Timur Celik, closes #6011)
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
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
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'*
|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'*
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
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
}
#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))
{
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;
}
}
}
- else
+ else if (key[5] == 'B')
{
HL_TABLE()[idx].sg_cterm_bg = color + 1;
if (is_normal_group)
}
}
}
+ 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)
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
*namep = NULL;
did_change = TRUE;
}
-# ifdef FEAT_GUI
+# if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
}
# endif
}
# ifdef FEAT_TERMGUICOLORS
cterm_normal_fg_gui_color = INVALCOLOR;
cterm_normal_bg_gui_color = INVALCOLOR;
+ cterm_normal_ul_gui_color = INVALCOLOR;
# endif
#endif
}
#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
== 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
)))
{
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;
#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;
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.
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
}
}
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,
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)
* 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;
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
# 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)
{
#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;
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);
}
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)
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
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);
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)
{
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
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);
}
// 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
// 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")},
{(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]"},
{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"},
{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"},
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:
{
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) \
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
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
#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
#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
" 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.
static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 863,
/**/
862,
/**/