1*f9cc9f20SBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet: 2*f9cc9f20SBram Moolenaar * 3*f9cc9f20SBram Moolenaar * VIM - Vi IMproved by Bram Moolenaar 4*f9cc9f20SBram Moolenaar * 5*f9cc9f20SBram Moolenaar * Do ":help uganda" in Vim to read copying and usage conditions. 6*f9cc9f20SBram Moolenaar * Do ":help credits" in Vim to see a list of people who contributed. 7*f9cc9f20SBram Moolenaar * See README.txt for an overview of the Vim source code. 8*f9cc9f20SBram Moolenaar */ 9*f9cc9f20SBram Moolenaar 10*f9cc9f20SBram Moolenaar /* 11*f9cc9f20SBram Moolenaar * Highlighting stuff 12*f9cc9f20SBram Moolenaar */ 13*f9cc9f20SBram Moolenaar 14*f9cc9f20SBram Moolenaar #include "vim.h" 15*f9cc9f20SBram Moolenaar 16*f9cc9f20SBram Moolenaar #define SG_TERM 1 // term has been set 17*f9cc9f20SBram Moolenaar #define SG_CTERM 2 // cterm has been set 18*f9cc9f20SBram Moolenaar #define SG_GUI 4 // gui has been set 19*f9cc9f20SBram Moolenaar #define SG_LINK 8 // link has been set 20*f9cc9f20SBram Moolenaar 21*f9cc9f20SBram Moolenaar /* 22*f9cc9f20SBram Moolenaar * The "term", "cterm" and "gui" arguments can be any combination of the 23*f9cc9f20SBram Moolenaar * following names, separated by commas (but no spaces!). 24*f9cc9f20SBram Moolenaar */ 25*f9cc9f20SBram Moolenaar static char *(hl_name_table[]) = 26*f9cc9f20SBram Moolenaar {"bold", "standout", "underline", "undercurl", 27*f9cc9f20SBram Moolenaar "italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"}; 28*f9cc9f20SBram Moolenaar static int hl_attr_table[] = 29*f9cc9f20SBram Moolenaar {HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0}; 30*f9cc9f20SBram Moolenaar #define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? attr_b : (attr_a)) | (attr_b)) 31*f9cc9f20SBram Moolenaar 32*f9cc9f20SBram Moolenaar static void syn_unadd_group(void); 33*f9cc9f20SBram Moolenaar static void set_hl_attr(int idx); 34*f9cc9f20SBram Moolenaar static void highlight_list_one(int id); 35*f9cc9f20SBram Moolenaar static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name); 36*f9cc9f20SBram Moolenaar static int syn_add_group(char_u *name); 37*f9cc9f20SBram Moolenaar static int hl_has_settings(int idx, int check_link); 38*f9cc9f20SBram Moolenaar static void highlight_clear(int idx); 39*f9cc9f20SBram Moolenaar 40*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 41*f9cc9f20SBram Moolenaar static void gui_do_one_color(int idx, int do_menu, int do_tooltip); 42*f9cc9f20SBram Moolenaar #endif 43*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 44*f9cc9f20SBram Moolenaar static int set_group_colors(char_u *name, guicolor_T *fgp, guicolor_T *bgp, int do_menu, int use_norm, int do_tooltip); 45*f9cc9f20SBram Moolenaar static void hl_do_font(int idx, char_u *arg, int do_normal, int do_menu, int do_tooltip, int free_font); 46*f9cc9f20SBram Moolenaar #endif 47*f9cc9f20SBram Moolenaar 48*f9cc9f20SBram Moolenaar /* 49*f9cc9f20SBram Moolenaar * An attribute number is the index in attr_table plus ATTR_OFF. 50*f9cc9f20SBram Moolenaar */ 51*f9cc9f20SBram Moolenaar #define ATTR_OFF (HL_ALL + 1) 52*f9cc9f20SBram Moolenaar 53*f9cc9f20SBram Moolenaar /* 54*f9cc9f20SBram Moolenaar * The default highlight groups. These are compiled-in for fast startup and 55*f9cc9f20SBram Moolenaar * they still work when the runtime files can't be found. 56*f9cc9f20SBram Moolenaar * When making changes here, also change runtime/colors/default.vim! 57*f9cc9f20SBram Moolenaar * The #ifdefs are needed to reduce the amount of static data. Helps to make 58*f9cc9f20SBram Moolenaar * the 16 bit DOS (museum) version compile. 59*f9cc9f20SBram Moolenaar */ 60*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 61*f9cc9f20SBram Moolenaar # define CENT(a, b) b 62*f9cc9f20SBram Moolenaar #else 63*f9cc9f20SBram Moolenaar # define CENT(a, b) a 64*f9cc9f20SBram Moolenaar #endif 65*f9cc9f20SBram Moolenaar static char *(highlight_init_both[]) = { 66*f9cc9f20SBram Moolenaar CENT("ErrorMsg term=standout ctermbg=DarkRed ctermfg=White", 67*f9cc9f20SBram Moolenaar "ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White"), 68*f9cc9f20SBram Moolenaar CENT("IncSearch term=reverse cterm=reverse", 69*f9cc9f20SBram Moolenaar "IncSearch term=reverse cterm=reverse gui=reverse"), 70*f9cc9f20SBram Moolenaar CENT("ModeMsg term=bold cterm=bold", 71*f9cc9f20SBram Moolenaar "ModeMsg term=bold cterm=bold gui=bold"), 72*f9cc9f20SBram Moolenaar CENT("NonText term=bold ctermfg=Blue", 73*f9cc9f20SBram Moolenaar "NonText term=bold ctermfg=Blue gui=bold guifg=Blue"), 74*f9cc9f20SBram Moolenaar CENT("StatusLine term=reverse,bold cterm=reverse,bold", 75*f9cc9f20SBram Moolenaar "StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold"), 76*f9cc9f20SBram Moolenaar CENT("StatusLineNC term=reverse cterm=reverse", 77*f9cc9f20SBram Moolenaar "StatusLineNC term=reverse cterm=reverse gui=reverse"), 78*f9cc9f20SBram Moolenaar "default link EndOfBuffer NonText", 79*f9cc9f20SBram Moolenaar CENT("VertSplit term=reverse cterm=reverse", 80*f9cc9f20SBram Moolenaar "VertSplit term=reverse cterm=reverse gui=reverse"), 81*f9cc9f20SBram Moolenaar #ifdef FEAT_CLIPBOARD 82*f9cc9f20SBram Moolenaar CENT("VisualNOS term=underline,bold cterm=underline,bold", 83*f9cc9f20SBram Moolenaar "VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold"), 84*f9cc9f20SBram Moolenaar #endif 85*f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF 86*f9cc9f20SBram Moolenaar CENT("DiffText term=reverse cterm=bold ctermbg=Red", 87*f9cc9f20SBram Moolenaar "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red"), 88*f9cc9f20SBram Moolenaar #endif 89*f9cc9f20SBram Moolenaar #ifdef FEAT_INS_EXPAND 90*f9cc9f20SBram Moolenaar CENT("PmenuSbar ctermbg=Grey", 91*f9cc9f20SBram Moolenaar "PmenuSbar ctermbg=Grey guibg=Grey"), 92*f9cc9f20SBram Moolenaar #endif 93*f9cc9f20SBram Moolenaar CENT("TabLineSel term=bold cterm=bold", 94*f9cc9f20SBram Moolenaar "TabLineSel term=bold cterm=bold gui=bold"), 95*f9cc9f20SBram Moolenaar CENT("TabLineFill term=reverse cterm=reverse", 96*f9cc9f20SBram Moolenaar "TabLineFill term=reverse cterm=reverse gui=reverse"), 97*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 98*f9cc9f20SBram Moolenaar "Cursor guibg=fg guifg=bg", 99*f9cc9f20SBram Moolenaar "lCursor guibg=fg guifg=bg", // should be different, but what? 100*f9cc9f20SBram Moolenaar #endif 101*f9cc9f20SBram Moolenaar "default link QuickFixLine Search", 102*f9cc9f20SBram Moolenaar CENT("Normal cterm=NONE", "Normal gui=NONE"), 103*f9cc9f20SBram Moolenaar NULL 104*f9cc9f20SBram Moolenaar }; 105*f9cc9f20SBram Moolenaar 106*f9cc9f20SBram Moolenaar /* Default colors only used with a light background. */ 107*f9cc9f20SBram Moolenaar static char *(highlight_init_light[]) = { 108*f9cc9f20SBram Moolenaar CENT("Directory term=bold ctermfg=DarkBlue", 109*f9cc9f20SBram Moolenaar "Directory term=bold ctermfg=DarkBlue guifg=Blue"), 110*f9cc9f20SBram Moolenaar CENT("LineNr term=underline ctermfg=Brown", 111*f9cc9f20SBram Moolenaar "LineNr term=underline ctermfg=Brown guifg=Brown"), 112*f9cc9f20SBram Moolenaar CENT("CursorLineNr term=bold ctermfg=Brown", 113*f9cc9f20SBram Moolenaar "CursorLineNr term=bold ctermfg=Brown gui=bold guifg=Brown"), 114*f9cc9f20SBram Moolenaar CENT("MoreMsg term=bold ctermfg=DarkGreen", 115*f9cc9f20SBram Moolenaar "MoreMsg term=bold ctermfg=DarkGreen gui=bold guifg=SeaGreen"), 116*f9cc9f20SBram Moolenaar CENT("Question term=standout ctermfg=DarkGreen", 117*f9cc9f20SBram Moolenaar "Question term=standout ctermfg=DarkGreen gui=bold guifg=SeaGreen"), 118*f9cc9f20SBram Moolenaar CENT("Search term=reverse ctermbg=Yellow ctermfg=NONE", 119*f9cc9f20SBram Moolenaar "Search term=reverse ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE"), 120*f9cc9f20SBram Moolenaar #ifdef FEAT_SPELL 121*f9cc9f20SBram Moolenaar CENT("SpellBad term=reverse ctermbg=LightRed", 122*f9cc9f20SBram Moolenaar "SpellBad term=reverse ctermbg=LightRed guisp=Red gui=undercurl"), 123*f9cc9f20SBram Moolenaar CENT("SpellCap term=reverse ctermbg=LightBlue", 124*f9cc9f20SBram Moolenaar "SpellCap term=reverse ctermbg=LightBlue guisp=Blue gui=undercurl"), 125*f9cc9f20SBram Moolenaar CENT("SpellRare term=reverse ctermbg=LightMagenta", 126*f9cc9f20SBram Moolenaar "SpellRare term=reverse ctermbg=LightMagenta guisp=Magenta gui=undercurl"), 127*f9cc9f20SBram Moolenaar CENT("SpellLocal term=underline ctermbg=Cyan", 128*f9cc9f20SBram Moolenaar "SpellLocal term=underline ctermbg=Cyan guisp=DarkCyan gui=undercurl"), 129*f9cc9f20SBram Moolenaar #endif 130*f9cc9f20SBram Moolenaar #ifdef FEAT_INS_EXPAND 131*f9cc9f20SBram Moolenaar CENT("PmenuThumb ctermbg=Black", 132*f9cc9f20SBram Moolenaar "PmenuThumb ctermbg=Black guibg=Black"), 133*f9cc9f20SBram Moolenaar CENT("Pmenu ctermbg=LightMagenta ctermfg=Black", 134*f9cc9f20SBram Moolenaar "Pmenu ctermbg=LightMagenta ctermfg=Black guibg=LightMagenta"), 135*f9cc9f20SBram Moolenaar CENT("PmenuSel ctermbg=LightGrey ctermfg=Black", 136*f9cc9f20SBram Moolenaar "PmenuSel ctermbg=LightGrey ctermfg=Black guibg=Grey"), 137*f9cc9f20SBram Moolenaar #endif 138*f9cc9f20SBram Moolenaar CENT("SpecialKey term=bold ctermfg=DarkBlue", 139*f9cc9f20SBram Moolenaar "SpecialKey term=bold ctermfg=DarkBlue guifg=Blue"), 140*f9cc9f20SBram Moolenaar CENT("Title term=bold ctermfg=DarkMagenta", 141*f9cc9f20SBram Moolenaar "Title term=bold ctermfg=DarkMagenta gui=bold guifg=Magenta"), 142*f9cc9f20SBram Moolenaar CENT("WarningMsg term=standout ctermfg=DarkRed", 143*f9cc9f20SBram Moolenaar "WarningMsg term=standout ctermfg=DarkRed guifg=Red"), 144*f9cc9f20SBram Moolenaar #ifdef FEAT_WILDMENU 145*f9cc9f20SBram Moolenaar CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black", 146*f9cc9f20SBram Moolenaar "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), 147*f9cc9f20SBram Moolenaar #endif 148*f9cc9f20SBram Moolenaar #ifdef FEAT_FOLDING 149*f9cc9f20SBram Moolenaar CENT("Folded term=standout ctermbg=Grey ctermfg=DarkBlue", 150*f9cc9f20SBram Moolenaar "Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue"), 151*f9cc9f20SBram Moolenaar CENT("FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue", 152*f9cc9f20SBram Moolenaar "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"), 153*f9cc9f20SBram Moolenaar #endif 154*f9cc9f20SBram Moolenaar #ifdef FEAT_SIGNS 155*f9cc9f20SBram Moolenaar CENT("SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue", 156*f9cc9f20SBram Moolenaar "SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"), 157*f9cc9f20SBram Moolenaar #endif 158*f9cc9f20SBram Moolenaar CENT("Visual term=reverse", 159*f9cc9f20SBram Moolenaar "Visual term=reverse guibg=LightGrey"), 160*f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF 161*f9cc9f20SBram Moolenaar CENT("DiffAdd term=bold ctermbg=LightBlue", 162*f9cc9f20SBram Moolenaar "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue"), 163*f9cc9f20SBram Moolenaar CENT("DiffChange term=bold ctermbg=LightMagenta", 164*f9cc9f20SBram Moolenaar "DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta"), 165*f9cc9f20SBram Moolenaar CENT("DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan", 166*f9cc9f20SBram Moolenaar "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan"), 167*f9cc9f20SBram Moolenaar #endif 168*f9cc9f20SBram Moolenaar CENT("TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey", 169*f9cc9f20SBram Moolenaar "TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey gui=underline guibg=LightGrey"), 170*f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL 171*f9cc9f20SBram Moolenaar CENT("CursorColumn term=reverse ctermbg=LightGrey", 172*f9cc9f20SBram Moolenaar "CursorColumn term=reverse ctermbg=LightGrey guibg=Grey90"), 173*f9cc9f20SBram Moolenaar CENT("CursorLine term=underline cterm=underline", 174*f9cc9f20SBram Moolenaar "CursorLine term=underline cterm=underline guibg=Grey90"), 175*f9cc9f20SBram Moolenaar CENT("ColorColumn term=reverse ctermbg=LightRed", 176*f9cc9f20SBram Moolenaar "ColorColumn term=reverse ctermbg=LightRed guibg=LightRed"), 177*f9cc9f20SBram Moolenaar #endif 178*f9cc9f20SBram Moolenaar #ifdef FEAT_CONCEAL 179*f9cc9f20SBram Moolenaar CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey", 180*f9cc9f20SBram Moolenaar "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"), 181*f9cc9f20SBram Moolenaar #endif 182*f9cc9f20SBram Moolenaar CENT("MatchParen term=reverse ctermbg=Cyan", 183*f9cc9f20SBram Moolenaar "MatchParen term=reverse ctermbg=Cyan guibg=Cyan"), 184*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 185*f9cc9f20SBram Moolenaar CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen", 186*f9cc9f20SBram Moolenaar "StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen gui=bold guifg=bg guibg=DarkGreen"), 187*f9cc9f20SBram Moolenaar CENT("StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen", 188*f9cc9f20SBram Moolenaar "StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen guifg=bg guibg=DarkGreen"), 189*f9cc9f20SBram Moolenaar #endif 190*f9cc9f20SBram Moolenaar #ifdef FEAT_MENU 191*f9cc9f20SBram Moolenaar CENT("ToolbarLine term=underline ctermbg=LightGrey", 192*f9cc9f20SBram Moolenaar "ToolbarLine term=underline ctermbg=LightGrey guibg=LightGrey"), 193*f9cc9f20SBram Moolenaar CENT("ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey", 194*f9cc9f20SBram Moolenaar "ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey gui=bold guifg=White guibg=Grey40"), 195*f9cc9f20SBram Moolenaar #endif 196*f9cc9f20SBram Moolenaar NULL 197*f9cc9f20SBram Moolenaar }; 198*f9cc9f20SBram Moolenaar 199*f9cc9f20SBram Moolenaar /* Default colors only used with a dark background. */ 200*f9cc9f20SBram Moolenaar static char *(highlight_init_dark[]) = { 201*f9cc9f20SBram Moolenaar CENT("Directory term=bold ctermfg=LightCyan", 202*f9cc9f20SBram Moolenaar "Directory term=bold ctermfg=LightCyan guifg=Cyan"), 203*f9cc9f20SBram Moolenaar CENT("LineNr term=underline ctermfg=Yellow", 204*f9cc9f20SBram Moolenaar "LineNr term=underline ctermfg=Yellow guifg=Yellow"), 205*f9cc9f20SBram Moolenaar CENT("CursorLineNr term=bold ctermfg=Yellow", 206*f9cc9f20SBram Moolenaar "CursorLineNr term=bold ctermfg=Yellow gui=bold guifg=Yellow"), 207*f9cc9f20SBram Moolenaar CENT("MoreMsg term=bold ctermfg=LightGreen", 208*f9cc9f20SBram Moolenaar "MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen"), 209*f9cc9f20SBram Moolenaar CENT("Question term=standout ctermfg=LightGreen", 210*f9cc9f20SBram Moolenaar "Question term=standout ctermfg=LightGreen gui=bold guifg=Green"), 211*f9cc9f20SBram Moolenaar CENT("Search term=reverse ctermbg=Yellow ctermfg=Black", 212*f9cc9f20SBram Moolenaar "Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), 213*f9cc9f20SBram Moolenaar CENT("SpecialKey term=bold ctermfg=LightBlue", 214*f9cc9f20SBram Moolenaar "SpecialKey term=bold ctermfg=LightBlue guifg=Cyan"), 215*f9cc9f20SBram Moolenaar #ifdef FEAT_SPELL 216*f9cc9f20SBram Moolenaar CENT("SpellBad term=reverse ctermbg=Red", 217*f9cc9f20SBram Moolenaar "SpellBad term=reverse ctermbg=Red guisp=Red gui=undercurl"), 218*f9cc9f20SBram Moolenaar CENT("SpellCap term=reverse ctermbg=Blue", 219*f9cc9f20SBram Moolenaar "SpellCap term=reverse ctermbg=Blue guisp=Blue gui=undercurl"), 220*f9cc9f20SBram Moolenaar CENT("SpellRare term=reverse ctermbg=Magenta", 221*f9cc9f20SBram Moolenaar "SpellRare term=reverse ctermbg=Magenta guisp=Magenta gui=undercurl"), 222*f9cc9f20SBram Moolenaar CENT("SpellLocal term=underline ctermbg=Cyan", 223*f9cc9f20SBram Moolenaar "SpellLocal term=underline ctermbg=Cyan guisp=Cyan gui=undercurl"), 224*f9cc9f20SBram Moolenaar #endif 225*f9cc9f20SBram Moolenaar #ifdef FEAT_INS_EXPAND 226*f9cc9f20SBram Moolenaar CENT("PmenuThumb ctermbg=White", 227*f9cc9f20SBram Moolenaar "PmenuThumb ctermbg=White guibg=White"), 228*f9cc9f20SBram Moolenaar CENT("Pmenu ctermbg=Magenta ctermfg=Black", 229*f9cc9f20SBram Moolenaar "Pmenu ctermbg=Magenta ctermfg=Black guibg=Magenta"), 230*f9cc9f20SBram Moolenaar CENT("PmenuSel ctermbg=Black ctermfg=DarkGrey", 231*f9cc9f20SBram Moolenaar "PmenuSel ctermbg=Black ctermfg=DarkGrey guibg=DarkGrey"), 232*f9cc9f20SBram Moolenaar #endif 233*f9cc9f20SBram Moolenaar CENT("Title term=bold ctermfg=LightMagenta", 234*f9cc9f20SBram Moolenaar "Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta"), 235*f9cc9f20SBram Moolenaar CENT("WarningMsg term=standout ctermfg=LightRed", 236*f9cc9f20SBram Moolenaar "WarningMsg term=standout ctermfg=LightRed guifg=Red"), 237*f9cc9f20SBram Moolenaar #ifdef FEAT_WILDMENU 238*f9cc9f20SBram Moolenaar CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black", 239*f9cc9f20SBram Moolenaar "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), 240*f9cc9f20SBram Moolenaar #endif 241*f9cc9f20SBram Moolenaar #ifdef FEAT_FOLDING 242*f9cc9f20SBram Moolenaar CENT("Folded term=standout ctermbg=DarkGrey ctermfg=Cyan", 243*f9cc9f20SBram Moolenaar "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan"), 244*f9cc9f20SBram Moolenaar CENT("FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan", 245*f9cc9f20SBram Moolenaar "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"), 246*f9cc9f20SBram Moolenaar #endif 247*f9cc9f20SBram Moolenaar #ifdef FEAT_SIGNS 248*f9cc9f20SBram Moolenaar CENT("SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan", 249*f9cc9f20SBram Moolenaar "SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"), 250*f9cc9f20SBram Moolenaar #endif 251*f9cc9f20SBram Moolenaar CENT("Visual term=reverse", 252*f9cc9f20SBram Moolenaar "Visual term=reverse guibg=DarkGrey"), 253*f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF 254*f9cc9f20SBram Moolenaar CENT("DiffAdd term=bold ctermbg=DarkBlue", 255*f9cc9f20SBram Moolenaar "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue"), 256*f9cc9f20SBram Moolenaar CENT("DiffChange term=bold ctermbg=DarkMagenta", 257*f9cc9f20SBram Moolenaar "DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta"), 258*f9cc9f20SBram Moolenaar CENT("DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan", 259*f9cc9f20SBram Moolenaar "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan"), 260*f9cc9f20SBram Moolenaar #endif 261*f9cc9f20SBram Moolenaar CENT("TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey", 262*f9cc9f20SBram Moolenaar "TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey gui=underline guibg=DarkGrey"), 263*f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL 264*f9cc9f20SBram Moolenaar CENT("CursorColumn term=reverse ctermbg=DarkGrey", 265*f9cc9f20SBram Moolenaar "CursorColumn term=reverse ctermbg=DarkGrey guibg=Grey40"), 266*f9cc9f20SBram Moolenaar CENT("CursorLine term=underline cterm=underline", 267*f9cc9f20SBram Moolenaar "CursorLine term=underline cterm=underline guibg=Grey40"), 268*f9cc9f20SBram Moolenaar CENT("ColorColumn term=reverse ctermbg=DarkRed", 269*f9cc9f20SBram Moolenaar "ColorColumn term=reverse ctermbg=DarkRed guibg=DarkRed"), 270*f9cc9f20SBram Moolenaar #endif 271*f9cc9f20SBram Moolenaar CENT("MatchParen term=reverse ctermbg=DarkCyan", 272*f9cc9f20SBram Moolenaar "MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan"), 273*f9cc9f20SBram Moolenaar #ifdef FEAT_CONCEAL 274*f9cc9f20SBram Moolenaar CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey", 275*f9cc9f20SBram Moolenaar "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"), 276*f9cc9f20SBram Moolenaar #endif 277*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 278*f9cc9f20SBram Moolenaar CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen", 279*f9cc9f20SBram Moolenaar "StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen gui=bold guifg=bg guibg=LightGreen"), 280*f9cc9f20SBram Moolenaar CENT("StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen", 281*f9cc9f20SBram Moolenaar "StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen guifg=bg guibg=LightGreen"), 282*f9cc9f20SBram Moolenaar #endif 283*f9cc9f20SBram Moolenaar #ifdef FEAT_MENU 284*f9cc9f20SBram Moolenaar CENT("ToolbarLine term=underline ctermbg=DarkGrey", 285*f9cc9f20SBram Moolenaar "ToolbarLine term=underline ctermbg=DarkGrey guibg=Grey50"), 286*f9cc9f20SBram Moolenaar CENT("ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey", 287*f9cc9f20SBram Moolenaar "ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey gui=bold guifg=Black guibg=LightGrey"), 288*f9cc9f20SBram Moolenaar #endif 289*f9cc9f20SBram Moolenaar NULL 290*f9cc9f20SBram Moolenaar }; 291*f9cc9f20SBram Moolenaar 292*f9cc9f20SBram Moolenaar void 293*f9cc9f20SBram Moolenaar init_highlight( 294*f9cc9f20SBram Moolenaar int both, // include groups where 'bg' doesn't matter 295*f9cc9f20SBram Moolenaar int reset) // clear group first 296*f9cc9f20SBram Moolenaar { 297*f9cc9f20SBram Moolenaar int i; 298*f9cc9f20SBram Moolenaar char **pp; 299*f9cc9f20SBram Moolenaar static int had_both = FALSE; 300*f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 301*f9cc9f20SBram Moolenaar char_u *p; 302*f9cc9f20SBram Moolenaar 303*f9cc9f20SBram Moolenaar /* 304*f9cc9f20SBram Moolenaar * Try finding the color scheme file. Used when a color file was loaded 305*f9cc9f20SBram Moolenaar * and 'background' or 't_Co' is changed. 306*f9cc9f20SBram Moolenaar */ 307*f9cc9f20SBram Moolenaar p = get_var_value((char_u *)"g:colors_name"); 308*f9cc9f20SBram Moolenaar if (p != NULL) 309*f9cc9f20SBram Moolenaar { 310*f9cc9f20SBram Moolenaar // The value of g:colors_name could be freed when sourcing the script, 311*f9cc9f20SBram Moolenaar // making "p" invalid, so copy it. 312*f9cc9f20SBram Moolenaar char_u *copy_p = vim_strsave(p); 313*f9cc9f20SBram Moolenaar int r; 314*f9cc9f20SBram Moolenaar 315*f9cc9f20SBram Moolenaar if (copy_p != NULL) 316*f9cc9f20SBram Moolenaar { 317*f9cc9f20SBram Moolenaar r = load_colors(copy_p); 318*f9cc9f20SBram Moolenaar vim_free(copy_p); 319*f9cc9f20SBram Moolenaar if (r == OK) 320*f9cc9f20SBram Moolenaar return; 321*f9cc9f20SBram Moolenaar } 322*f9cc9f20SBram Moolenaar } 323*f9cc9f20SBram Moolenaar 324*f9cc9f20SBram Moolenaar #endif 325*f9cc9f20SBram Moolenaar 326*f9cc9f20SBram Moolenaar /* 327*f9cc9f20SBram Moolenaar * Didn't use a color file, use the compiled-in colors. 328*f9cc9f20SBram Moolenaar */ 329*f9cc9f20SBram Moolenaar if (both) 330*f9cc9f20SBram Moolenaar { 331*f9cc9f20SBram Moolenaar had_both = TRUE; 332*f9cc9f20SBram Moolenaar pp = highlight_init_both; 333*f9cc9f20SBram Moolenaar for (i = 0; pp[i] != NULL; ++i) 334*f9cc9f20SBram Moolenaar do_highlight((char_u *)pp[i], reset, TRUE); 335*f9cc9f20SBram Moolenaar } 336*f9cc9f20SBram Moolenaar else if (!had_both) 337*f9cc9f20SBram Moolenaar // Don't do anything before the call with both == TRUE from main(). 338*f9cc9f20SBram Moolenaar // Not everything has been setup then, and that call will overrule 339*f9cc9f20SBram Moolenaar // everything anyway. 340*f9cc9f20SBram Moolenaar return; 341*f9cc9f20SBram Moolenaar 342*f9cc9f20SBram Moolenaar if (*p_bg == 'l') 343*f9cc9f20SBram Moolenaar pp = highlight_init_light; 344*f9cc9f20SBram Moolenaar else 345*f9cc9f20SBram Moolenaar pp = highlight_init_dark; 346*f9cc9f20SBram Moolenaar for (i = 0; pp[i] != NULL; ++i) 347*f9cc9f20SBram Moolenaar do_highlight((char_u *)pp[i], reset, TRUE); 348*f9cc9f20SBram Moolenaar 349*f9cc9f20SBram Moolenaar // Reverse looks ugly, but grey may not work for 8 colors. Thus let it 350*f9cc9f20SBram Moolenaar // depend on the number of colors available. 351*f9cc9f20SBram Moolenaar // With 8 colors brown is equal to yellow, need to use black for Search fg 352*f9cc9f20SBram Moolenaar // to avoid Statement highlighted text disappears. 353*f9cc9f20SBram Moolenaar // Clear the attributes, needed when changing the t_Co value. 354*f9cc9f20SBram Moolenaar if (t_colors > 8) 355*f9cc9f20SBram Moolenaar do_highlight((char_u *)(*p_bg == 'l' 356*f9cc9f20SBram Moolenaar ? "Visual cterm=NONE ctermbg=LightGrey" 357*f9cc9f20SBram Moolenaar : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE, TRUE); 358*f9cc9f20SBram Moolenaar else 359*f9cc9f20SBram Moolenaar { 360*f9cc9f20SBram Moolenaar do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE", 361*f9cc9f20SBram Moolenaar FALSE, TRUE); 362*f9cc9f20SBram Moolenaar if (*p_bg == 'l') 363*f9cc9f20SBram Moolenaar do_highlight((char_u *)"Search ctermfg=black", FALSE, TRUE); 364*f9cc9f20SBram Moolenaar } 365*f9cc9f20SBram Moolenaar 366*f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL 367*f9cc9f20SBram Moolenaar /* 368*f9cc9f20SBram Moolenaar * If syntax highlighting is enabled load the highlighting for it. 369*f9cc9f20SBram Moolenaar */ 370*f9cc9f20SBram Moolenaar if (get_var_value((char_u *)"g:syntax_on") != NULL) 371*f9cc9f20SBram Moolenaar { 372*f9cc9f20SBram Moolenaar static int recursive = 0; 373*f9cc9f20SBram Moolenaar 374*f9cc9f20SBram Moolenaar if (recursive >= 5) 375*f9cc9f20SBram Moolenaar emsg(_("E679: recursive loop loading syncolor.vim")); 376*f9cc9f20SBram Moolenaar else 377*f9cc9f20SBram Moolenaar { 378*f9cc9f20SBram Moolenaar ++recursive; 379*f9cc9f20SBram Moolenaar (void)source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL); 380*f9cc9f20SBram Moolenaar --recursive; 381*f9cc9f20SBram Moolenaar } 382*f9cc9f20SBram Moolenaar } 383*f9cc9f20SBram Moolenaar #endif 384*f9cc9f20SBram Moolenaar } 385*f9cc9f20SBram Moolenaar 386*f9cc9f20SBram Moolenaar /* 387*f9cc9f20SBram Moolenaar * Load color file "name". 388*f9cc9f20SBram Moolenaar * Return OK for success, FAIL for failure. 389*f9cc9f20SBram Moolenaar */ 390*f9cc9f20SBram Moolenaar int 391*f9cc9f20SBram Moolenaar load_colors(char_u *name) 392*f9cc9f20SBram Moolenaar { 393*f9cc9f20SBram Moolenaar char_u *buf; 394*f9cc9f20SBram Moolenaar int retval = FAIL; 395*f9cc9f20SBram Moolenaar static int recursive = FALSE; 396*f9cc9f20SBram Moolenaar 397*f9cc9f20SBram Moolenaar // When being called recursively, this is probably because setting 398*f9cc9f20SBram Moolenaar // 'background' caused the highlighting to be reloaded. This means it is 399*f9cc9f20SBram Moolenaar // working, thus we should return OK. 400*f9cc9f20SBram Moolenaar if (recursive) 401*f9cc9f20SBram Moolenaar return OK; 402*f9cc9f20SBram Moolenaar 403*f9cc9f20SBram Moolenaar recursive = TRUE; 404*f9cc9f20SBram Moolenaar buf = alloc(STRLEN(name) + 12); 405*f9cc9f20SBram Moolenaar if (buf != NULL) 406*f9cc9f20SBram Moolenaar { 407*f9cc9f20SBram Moolenaar apply_autocmds(EVENT_COLORSCHEMEPRE, name, 408*f9cc9f20SBram Moolenaar curbuf->b_fname, FALSE, curbuf); 409*f9cc9f20SBram Moolenaar sprintf((char *)buf, "colors/%s.vim", name); 410*f9cc9f20SBram Moolenaar retval = source_runtime(buf, DIP_START + DIP_OPT); 411*f9cc9f20SBram Moolenaar vim_free(buf); 412*f9cc9f20SBram Moolenaar apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); 413*f9cc9f20SBram Moolenaar } 414*f9cc9f20SBram Moolenaar recursive = FALSE; 415*f9cc9f20SBram Moolenaar 416*f9cc9f20SBram Moolenaar return retval; 417*f9cc9f20SBram Moolenaar } 418*f9cc9f20SBram Moolenaar 419*f9cc9f20SBram Moolenaar static char *(color_names[28]) = { 420*f9cc9f20SBram Moolenaar "Black", "DarkBlue", "DarkGreen", "DarkCyan", 421*f9cc9f20SBram Moolenaar "DarkRed", "DarkMagenta", "Brown", "DarkYellow", 422*f9cc9f20SBram Moolenaar "Gray", "Grey", "LightGray", "LightGrey", 423*f9cc9f20SBram Moolenaar "DarkGray", "DarkGrey", 424*f9cc9f20SBram Moolenaar "Blue", "LightBlue", "Green", "LightGreen", 425*f9cc9f20SBram Moolenaar "Cyan", "LightCyan", "Red", "LightRed", "Magenta", 426*f9cc9f20SBram Moolenaar "LightMagenta", "Yellow", "LightYellow", "White", "NONE"}; 427*f9cc9f20SBram Moolenaar // indices: 428*f9cc9f20SBram Moolenaar // 0, 1, 2, 3, 429*f9cc9f20SBram Moolenaar // 4, 5, 6, 7, 430*f9cc9f20SBram Moolenaar // 8, 9, 10, 11, 431*f9cc9f20SBram Moolenaar // 12, 13, 432*f9cc9f20SBram Moolenaar // 14, 15, 16, 17, 433*f9cc9f20SBram Moolenaar // 18, 19, 20, 21, 22, 434*f9cc9f20SBram Moolenaar // 23, 24, 25, 26, 27 435*f9cc9f20SBram Moolenaar static int color_numbers_16[28] = {0, 1, 2, 3, 436*f9cc9f20SBram Moolenaar 4, 5, 6, 6, 437*f9cc9f20SBram Moolenaar 7, 7, 7, 7, 438*f9cc9f20SBram Moolenaar 8, 8, 439*f9cc9f20SBram Moolenaar 9, 9, 10, 10, 440*f9cc9f20SBram Moolenaar 11, 11, 12, 12, 13, 441*f9cc9f20SBram Moolenaar 13, 14, 14, 15, -1}; 442*f9cc9f20SBram Moolenaar // for xterm with 88 colors... 443*f9cc9f20SBram Moolenaar static int color_numbers_88[28] = {0, 4, 2, 6, 444*f9cc9f20SBram Moolenaar 1, 5, 32, 72, 445*f9cc9f20SBram Moolenaar 84, 84, 7, 7, 446*f9cc9f20SBram Moolenaar 82, 82, 447*f9cc9f20SBram Moolenaar 12, 43, 10, 61, 448*f9cc9f20SBram Moolenaar 14, 63, 9, 74, 13, 449*f9cc9f20SBram Moolenaar 75, 11, 78, 15, -1}; 450*f9cc9f20SBram Moolenaar // for xterm with 256 colors... 451*f9cc9f20SBram Moolenaar static int color_numbers_256[28] = {0, 4, 2, 6, 452*f9cc9f20SBram Moolenaar 1, 5, 130, 130, 453*f9cc9f20SBram Moolenaar 248, 248, 7, 7, 454*f9cc9f20SBram Moolenaar 242, 242, 455*f9cc9f20SBram Moolenaar 12, 81, 10, 121, 456*f9cc9f20SBram Moolenaar 14, 159, 9, 224, 13, 457*f9cc9f20SBram Moolenaar 225, 11, 229, 15, -1}; 458*f9cc9f20SBram Moolenaar // for terminals with less than 16 colors... 459*f9cc9f20SBram Moolenaar static int color_numbers_8[28] = {0, 4, 2, 6, 460*f9cc9f20SBram Moolenaar 1, 5, 3, 3, 461*f9cc9f20SBram Moolenaar 7, 7, 7, 7, 462*f9cc9f20SBram Moolenaar 0+8, 0+8, 463*f9cc9f20SBram Moolenaar 4+8, 4+8, 2+8, 2+8, 464*f9cc9f20SBram Moolenaar 6+8, 6+8, 1+8, 1+8, 5+8, 465*f9cc9f20SBram Moolenaar 5+8, 3+8, 3+8, 7+8, -1}; 466*f9cc9f20SBram Moolenaar 467*f9cc9f20SBram Moolenaar /* 468*f9cc9f20SBram Moolenaar * Lookup the "cterm" value to be used for color with index "idx" in 469*f9cc9f20SBram Moolenaar * color_names[]. 470*f9cc9f20SBram Moolenaar * "boldp" will be set to TRUE or FALSE for a foreground color when using 8 471*f9cc9f20SBram Moolenaar * colors, otherwise it will be unchanged. 472*f9cc9f20SBram Moolenaar */ 473*f9cc9f20SBram Moolenaar int 474*f9cc9f20SBram Moolenaar lookup_color(int idx, int foreground, int *boldp) 475*f9cc9f20SBram Moolenaar { 476*f9cc9f20SBram Moolenaar int color = color_numbers_16[idx]; 477*f9cc9f20SBram Moolenaar char_u *p; 478*f9cc9f20SBram Moolenaar 479*f9cc9f20SBram Moolenaar // Use the _16 table to check if it's a valid color name. 480*f9cc9f20SBram Moolenaar if (color < 0) 481*f9cc9f20SBram Moolenaar return -1; 482*f9cc9f20SBram Moolenaar 483*f9cc9f20SBram Moolenaar if (t_colors == 8) 484*f9cc9f20SBram Moolenaar { 485*f9cc9f20SBram Moolenaar // t_Co is 8: use the 8 colors table 486*f9cc9f20SBram Moolenaar #if defined(__QNXNTO__) 487*f9cc9f20SBram Moolenaar color = color_numbers_8_qansi[idx]; 488*f9cc9f20SBram Moolenaar #else 489*f9cc9f20SBram Moolenaar color = color_numbers_8[idx]; 490*f9cc9f20SBram Moolenaar #endif 491*f9cc9f20SBram Moolenaar if (foreground) 492*f9cc9f20SBram Moolenaar { 493*f9cc9f20SBram Moolenaar // set/reset bold attribute to get light foreground 494*f9cc9f20SBram Moolenaar // colors (on some terminals, e.g. "linux") 495*f9cc9f20SBram Moolenaar if (color & 8) 496*f9cc9f20SBram Moolenaar *boldp = TRUE; 497*f9cc9f20SBram Moolenaar else 498*f9cc9f20SBram Moolenaar *boldp = FALSE; 499*f9cc9f20SBram Moolenaar } 500*f9cc9f20SBram Moolenaar color &= 7; // truncate to 8 colors 501*f9cc9f20SBram Moolenaar } 502*f9cc9f20SBram Moolenaar else if (t_colors == 16 || t_colors == 88 503*f9cc9f20SBram Moolenaar || t_colors >= 256) 504*f9cc9f20SBram Moolenaar { 505*f9cc9f20SBram Moolenaar /* 506*f9cc9f20SBram Moolenaar * Guess: if the termcap entry ends in 'm', it is 507*f9cc9f20SBram Moolenaar * probably an xterm-like terminal. Use the changed 508*f9cc9f20SBram Moolenaar * order for colors. 509*f9cc9f20SBram Moolenaar */ 510*f9cc9f20SBram Moolenaar if (*T_CAF != NUL) 511*f9cc9f20SBram Moolenaar p = T_CAF; 512*f9cc9f20SBram Moolenaar else 513*f9cc9f20SBram Moolenaar p = T_CSF; 514*f9cc9f20SBram Moolenaar if (*p != NUL && (t_colors > 256 515*f9cc9f20SBram Moolenaar || *(p + STRLEN(p) - 1) == 'm')) 516*f9cc9f20SBram Moolenaar { 517*f9cc9f20SBram Moolenaar if (t_colors == 88) 518*f9cc9f20SBram Moolenaar color = color_numbers_88[idx]; 519*f9cc9f20SBram Moolenaar else if (t_colors >= 256) 520*f9cc9f20SBram Moolenaar color = color_numbers_256[idx]; 521*f9cc9f20SBram Moolenaar else 522*f9cc9f20SBram Moolenaar color = color_numbers_8[idx]; 523*f9cc9f20SBram Moolenaar } 524*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMRESPONSE 525*f9cc9f20SBram Moolenaar if (t_colors >= 256 && color == 15 && is_mac_terminal) 526*f9cc9f20SBram Moolenaar // Terminal.app has a bug: 15 is light grey. Use white 527*f9cc9f20SBram Moolenaar // from the color cube instead. 528*f9cc9f20SBram Moolenaar color = 231; 529*f9cc9f20SBram Moolenaar #endif 530*f9cc9f20SBram Moolenaar } 531*f9cc9f20SBram Moolenaar return color; 532*f9cc9f20SBram Moolenaar } 533*f9cc9f20SBram Moolenaar 534*f9cc9f20SBram Moolenaar /* 535*f9cc9f20SBram Moolenaar * Handle the ":highlight .." command. 536*f9cc9f20SBram Moolenaar * When using ":hi clear" this is called recursively for each group with 537*f9cc9f20SBram Moolenaar * "forceit" and "init" both TRUE. 538*f9cc9f20SBram Moolenaar */ 539*f9cc9f20SBram Moolenaar void 540*f9cc9f20SBram Moolenaar do_highlight( 541*f9cc9f20SBram Moolenaar char_u *line, 542*f9cc9f20SBram Moolenaar int forceit, 543*f9cc9f20SBram Moolenaar int init) // TRUE when called for initializing 544*f9cc9f20SBram Moolenaar { 545*f9cc9f20SBram Moolenaar char_u *name_end; 546*f9cc9f20SBram Moolenaar char_u *p; 547*f9cc9f20SBram Moolenaar char_u *linep; 548*f9cc9f20SBram Moolenaar char_u *key_start; 549*f9cc9f20SBram Moolenaar char_u *arg_start; 550*f9cc9f20SBram Moolenaar char_u *key = NULL, *arg = NULL; 551*f9cc9f20SBram Moolenaar long i; 552*f9cc9f20SBram Moolenaar int off; 553*f9cc9f20SBram Moolenaar int len; 554*f9cc9f20SBram Moolenaar int attr; 555*f9cc9f20SBram Moolenaar int id; 556*f9cc9f20SBram Moolenaar int idx; 557*f9cc9f20SBram Moolenaar hl_group_T item_before; 558*f9cc9f20SBram Moolenaar int did_change = FALSE; 559*f9cc9f20SBram Moolenaar int dodefault = FALSE; 560*f9cc9f20SBram Moolenaar int doclear = FALSE; 561*f9cc9f20SBram Moolenaar int dolink = FALSE; 562*f9cc9f20SBram Moolenaar int error = FALSE; 563*f9cc9f20SBram Moolenaar int color; 564*f9cc9f20SBram Moolenaar int is_normal_group = FALSE; // "Normal" group 565*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 566*f9cc9f20SBram Moolenaar int is_terminal_group = FALSE; // "Terminal" group 567*f9cc9f20SBram Moolenaar #endif 568*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI_X11 569*f9cc9f20SBram Moolenaar int is_menu_group = FALSE; // "Menu" group 570*f9cc9f20SBram Moolenaar int is_scrollbar_group = FALSE; // "Scrollbar" group 571*f9cc9f20SBram Moolenaar int is_tooltip_group = FALSE; // "Tooltip" group 572*f9cc9f20SBram Moolenaar int do_colors = FALSE; // need to update colors? 573*f9cc9f20SBram Moolenaar #else 574*f9cc9f20SBram Moolenaar # define is_menu_group 0 575*f9cc9f20SBram Moolenaar # define is_tooltip_group 0 576*f9cc9f20SBram Moolenaar #endif 577*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 578*f9cc9f20SBram Moolenaar int did_highlight_changed = FALSE; 579*f9cc9f20SBram Moolenaar #endif 580*f9cc9f20SBram Moolenaar 581*f9cc9f20SBram Moolenaar /* 582*f9cc9f20SBram Moolenaar * If no argument, list current highlighting. 583*f9cc9f20SBram Moolenaar */ 584*f9cc9f20SBram Moolenaar if (ends_excmd(*line)) 585*f9cc9f20SBram Moolenaar { 586*f9cc9f20SBram Moolenaar for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i) 587*f9cc9f20SBram Moolenaar // TODO: only call when the group has attributes set 588*f9cc9f20SBram Moolenaar highlight_list_one((int)i); 589*f9cc9f20SBram Moolenaar return; 590*f9cc9f20SBram Moolenaar } 591*f9cc9f20SBram Moolenaar 592*f9cc9f20SBram Moolenaar /* 593*f9cc9f20SBram Moolenaar * Isolate the name. 594*f9cc9f20SBram Moolenaar */ 595*f9cc9f20SBram Moolenaar name_end = skiptowhite(line); 596*f9cc9f20SBram Moolenaar linep = skipwhite(name_end); 597*f9cc9f20SBram Moolenaar 598*f9cc9f20SBram Moolenaar /* 599*f9cc9f20SBram Moolenaar * Check for "default" argument. 600*f9cc9f20SBram Moolenaar */ 601*f9cc9f20SBram Moolenaar if (STRNCMP(line, "default", name_end - line) == 0) 602*f9cc9f20SBram Moolenaar { 603*f9cc9f20SBram Moolenaar dodefault = TRUE; 604*f9cc9f20SBram Moolenaar line = linep; 605*f9cc9f20SBram Moolenaar name_end = skiptowhite(line); 606*f9cc9f20SBram Moolenaar linep = skipwhite(name_end); 607*f9cc9f20SBram Moolenaar } 608*f9cc9f20SBram Moolenaar 609*f9cc9f20SBram Moolenaar /* 610*f9cc9f20SBram Moolenaar * Check for "clear" or "link" argument. 611*f9cc9f20SBram Moolenaar */ 612*f9cc9f20SBram Moolenaar if (STRNCMP(line, "clear", name_end - line) == 0) 613*f9cc9f20SBram Moolenaar doclear = TRUE; 614*f9cc9f20SBram Moolenaar if (STRNCMP(line, "link", name_end - line) == 0) 615*f9cc9f20SBram Moolenaar dolink = TRUE; 616*f9cc9f20SBram Moolenaar 617*f9cc9f20SBram Moolenaar /* 618*f9cc9f20SBram Moolenaar * ":highlight {group-name}": list highlighting for one group. 619*f9cc9f20SBram Moolenaar */ 620*f9cc9f20SBram Moolenaar if (!doclear && !dolink && ends_excmd(*linep)) 621*f9cc9f20SBram Moolenaar { 622*f9cc9f20SBram Moolenaar id = syn_namen2id(line, (int)(name_end - line)); 623*f9cc9f20SBram Moolenaar if (id == 0) 624*f9cc9f20SBram Moolenaar semsg(_("E411: highlight group not found: %s"), line); 625*f9cc9f20SBram Moolenaar else 626*f9cc9f20SBram Moolenaar highlight_list_one(id); 627*f9cc9f20SBram Moolenaar return; 628*f9cc9f20SBram Moolenaar } 629*f9cc9f20SBram Moolenaar 630*f9cc9f20SBram Moolenaar /* 631*f9cc9f20SBram Moolenaar * Handle ":highlight link {from} {to}" command. 632*f9cc9f20SBram Moolenaar */ 633*f9cc9f20SBram Moolenaar if (dolink) 634*f9cc9f20SBram Moolenaar { 635*f9cc9f20SBram Moolenaar char_u *from_start = linep; 636*f9cc9f20SBram Moolenaar char_u *from_end; 637*f9cc9f20SBram Moolenaar char_u *to_start; 638*f9cc9f20SBram Moolenaar char_u *to_end; 639*f9cc9f20SBram Moolenaar int from_id; 640*f9cc9f20SBram Moolenaar int to_id; 641*f9cc9f20SBram Moolenaar 642*f9cc9f20SBram Moolenaar from_end = skiptowhite(from_start); 643*f9cc9f20SBram Moolenaar to_start = skipwhite(from_end); 644*f9cc9f20SBram Moolenaar to_end = skiptowhite(to_start); 645*f9cc9f20SBram Moolenaar 646*f9cc9f20SBram Moolenaar if (ends_excmd(*from_start) || ends_excmd(*to_start)) 647*f9cc9f20SBram Moolenaar { 648*f9cc9f20SBram Moolenaar semsg(_("E412: Not enough arguments: \":highlight link %s\""), 649*f9cc9f20SBram Moolenaar from_start); 650*f9cc9f20SBram Moolenaar return; 651*f9cc9f20SBram Moolenaar } 652*f9cc9f20SBram Moolenaar 653*f9cc9f20SBram Moolenaar if (!ends_excmd(*skipwhite(to_end))) 654*f9cc9f20SBram Moolenaar { 655*f9cc9f20SBram Moolenaar semsg(_("E413: Too many arguments: \":highlight link %s\""), from_start); 656*f9cc9f20SBram Moolenaar return; 657*f9cc9f20SBram Moolenaar } 658*f9cc9f20SBram Moolenaar 659*f9cc9f20SBram Moolenaar from_id = syn_check_group(from_start, (int)(from_end - from_start)); 660*f9cc9f20SBram Moolenaar if (STRNCMP(to_start, "NONE", 4) == 0) 661*f9cc9f20SBram Moolenaar to_id = 0; 662*f9cc9f20SBram Moolenaar else 663*f9cc9f20SBram Moolenaar to_id = syn_check_group(to_start, (int)(to_end - to_start)); 664*f9cc9f20SBram Moolenaar 665*f9cc9f20SBram Moolenaar if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0)) 666*f9cc9f20SBram Moolenaar { 667*f9cc9f20SBram Moolenaar /* 668*f9cc9f20SBram Moolenaar * Don't allow a link when there already is some highlighting 669*f9cc9f20SBram Moolenaar * for the group, unless '!' is used 670*f9cc9f20SBram Moolenaar */ 671*f9cc9f20SBram Moolenaar if (to_id > 0 && !forceit && !init 672*f9cc9f20SBram Moolenaar && hl_has_settings(from_id - 1, dodefault)) 673*f9cc9f20SBram Moolenaar { 674*f9cc9f20SBram Moolenaar if (sourcing_name == NULL && !dodefault) 675*f9cc9f20SBram Moolenaar emsg(_("E414: group has settings, highlight link ignored")); 676*f9cc9f20SBram Moolenaar } 677*f9cc9f20SBram Moolenaar else if (HL_TABLE()[from_id - 1].sg_link != to_id 678*f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 679*f9cc9f20SBram Moolenaar || HL_TABLE()[from_id - 1].sg_script_ctx.sc_sid 680*f9cc9f20SBram Moolenaar != current_sctx.sc_sid 681*f9cc9f20SBram Moolenaar #endif 682*f9cc9f20SBram Moolenaar || HL_TABLE()[from_id - 1].sg_cleared) 683*f9cc9f20SBram Moolenaar { 684*f9cc9f20SBram Moolenaar if (!init) 685*f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_set |= SG_LINK; 686*f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_link = to_id; 687*f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 688*f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx; 689*f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += sourcing_lnum; 690*f9cc9f20SBram Moolenaar #endif 691*f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_cleared = FALSE; 692*f9cc9f20SBram Moolenaar redraw_all_later(SOME_VALID); 693*f9cc9f20SBram Moolenaar 694*f9cc9f20SBram Moolenaar // Only call highlight_changed() once after multiple changes. 695*f9cc9f20SBram Moolenaar need_highlight_changed = TRUE; 696*f9cc9f20SBram Moolenaar } 697*f9cc9f20SBram Moolenaar } 698*f9cc9f20SBram Moolenaar 699*f9cc9f20SBram Moolenaar return; 700*f9cc9f20SBram Moolenaar } 701*f9cc9f20SBram Moolenaar 702*f9cc9f20SBram Moolenaar if (doclear) 703*f9cc9f20SBram Moolenaar { 704*f9cc9f20SBram Moolenaar /* 705*f9cc9f20SBram Moolenaar * ":highlight clear [group]" command. 706*f9cc9f20SBram Moolenaar */ 707*f9cc9f20SBram Moolenaar line = linep; 708*f9cc9f20SBram Moolenaar if (ends_excmd(*line)) 709*f9cc9f20SBram Moolenaar { 710*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 711*f9cc9f20SBram Moolenaar // First, we do not destroy the old values, but allocate the new 712*f9cc9f20SBram Moolenaar // ones and update the display. THEN we destroy the old values. 713*f9cc9f20SBram Moolenaar // If we destroy the old values first, then the old values 714*f9cc9f20SBram Moolenaar // (such as GuiFont's or GuiFontset's) will still be displayed but 715*f9cc9f20SBram Moolenaar // invalid because they were free'd. 716*f9cc9f20SBram Moolenaar if (gui.in_use) 717*f9cc9f20SBram Moolenaar { 718*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP 719*f9cc9f20SBram Moolenaar gui_init_tooltip_font(); 720*f9cc9f20SBram Moolenaar # endif 721*f9cc9f20SBram Moolenaar # if defined(FEAT_MENU) && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF)) 722*f9cc9f20SBram Moolenaar gui_init_menu_font(); 723*f9cc9f20SBram Moolenaar # endif 724*f9cc9f20SBram Moolenaar } 725*f9cc9f20SBram Moolenaar # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_X11) 726*f9cc9f20SBram Moolenaar gui_mch_def_colors(); 727*f9cc9f20SBram Moolenaar # endif 728*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11 729*f9cc9f20SBram Moolenaar # ifdef FEAT_MENU 730*f9cc9f20SBram Moolenaar 731*f9cc9f20SBram Moolenaar // This only needs to be done when there is no Menu highlight 732*f9cc9f20SBram Moolenaar // group defined by default, which IS currently the case. 733*f9cc9f20SBram Moolenaar gui_mch_new_menu_colors(); 734*f9cc9f20SBram Moolenaar # endif 735*f9cc9f20SBram Moolenaar if (gui.in_use) 736*f9cc9f20SBram Moolenaar { 737*f9cc9f20SBram Moolenaar gui_new_scrollbar_colors(); 738*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 739*f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors(); 740*f9cc9f20SBram Moolenaar # endif 741*f9cc9f20SBram Moolenaar # ifdef FEAT_MENU 742*f9cc9f20SBram Moolenaar gui_mch_new_menu_font(); 743*f9cc9f20SBram Moolenaar # endif 744*f9cc9f20SBram Moolenaar } 745*f9cc9f20SBram Moolenaar # endif 746*f9cc9f20SBram Moolenaar 747*f9cc9f20SBram Moolenaar // Ok, we're done allocating the new default graphics items. 748*f9cc9f20SBram Moolenaar // The screen should already be refreshed at this point. 749*f9cc9f20SBram Moolenaar // It is now Ok to clear out the old data. 750*f9cc9f20SBram Moolenaar #endif 751*f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 752*f9cc9f20SBram Moolenaar do_unlet((char_u *)"colors_name", TRUE); 753*f9cc9f20SBram Moolenaar #endif 754*f9cc9f20SBram Moolenaar restore_cterm_colors(); 755*f9cc9f20SBram Moolenaar 756*f9cc9f20SBram Moolenaar /* 757*f9cc9f20SBram Moolenaar * Clear all default highlight groups and load the defaults. 758*f9cc9f20SBram Moolenaar */ 759*f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx) 760*f9cc9f20SBram Moolenaar highlight_clear(idx); 761*f9cc9f20SBram Moolenaar init_highlight(TRUE, TRUE); 762*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 763*f9cc9f20SBram Moolenaar if (USE_24BIT) 764*f9cc9f20SBram Moolenaar highlight_gui_started(); 765*f9cc9f20SBram Moolenaar else 766*f9cc9f20SBram Moolenaar #endif 767*f9cc9f20SBram Moolenaar highlight_changed(); 768*f9cc9f20SBram Moolenaar redraw_later_clear(); 769*f9cc9f20SBram Moolenaar return; 770*f9cc9f20SBram Moolenaar } 771*f9cc9f20SBram Moolenaar name_end = skiptowhite(line); 772*f9cc9f20SBram Moolenaar linep = skipwhite(name_end); 773*f9cc9f20SBram Moolenaar } 774*f9cc9f20SBram Moolenaar 775*f9cc9f20SBram Moolenaar /* 776*f9cc9f20SBram Moolenaar * Find the group name in the table. If it does not exist yet, add it. 777*f9cc9f20SBram Moolenaar */ 778*f9cc9f20SBram Moolenaar id = syn_check_group(line, (int)(name_end - line)); 779*f9cc9f20SBram Moolenaar if (id == 0) // failed (out of memory) 780*f9cc9f20SBram Moolenaar return; 781*f9cc9f20SBram Moolenaar idx = id - 1; // index is ID minus one 782*f9cc9f20SBram Moolenaar 783*f9cc9f20SBram Moolenaar // Return if "default" was used and the group already has settings. 784*f9cc9f20SBram Moolenaar if (dodefault && hl_has_settings(idx, TRUE)) 785*f9cc9f20SBram Moolenaar return; 786*f9cc9f20SBram Moolenaar 787*f9cc9f20SBram Moolenaar // Make a copy so we can check if any attribute actually changed. 788*f9cc9f20SBram Moolenaar item_before = HL_TABLE()[idx]; 789*f9cc9f20SBram Moolenaar 790*f9cc9f20SBram Moolenaar if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0) 791*f9cc9f20SBram Moolenaar is_normal_group = TRUE; 792*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 793*f9cc9f20SBram Moolenaar else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TERMINAL") == 0) 794*f9cc9f20SBram Moolenaar is_terminal_group = TRUE; 795*f9cc9f20SBram Moolenaar #endif 796*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI_X11 797*f9cc9f20SBram Moolenaar else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0) 798*f9cc9f20SBram Moolenaar is_menu_group = TRUE; 799*f9cc9f20SBram Moolenaar else if (STRCMP(HL_TABLE()[idx].sg_name_u, "SCROLLBAR") == 0) 800*f9cc9f20SBram Moolenaar is_scrollbar_group = TRUE; 801*f9cc9f20SBram Moolenaar else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TOOLTIP") == 0) 802*f9cc9f20SBram Moolenaar is_tooltip_group = TRUE; 803*f9cc9f20SBram Moolenaar #endif 804*f9cc9f20SBram Moolenaar 805*f9cc9f20SBram Moolenaar // Clear the highlighting for ":hi clear {group}" and ":hi clear". 806*f9cc9f20SBram Moolenaar if (doclear || (forceit && init)) 807*f9cc9f20SBram Moolenaar { 808*f9cc9f20SBram Moolenaar highlight_clear(idx); 809*f9cc9f20SBram Moolenaar if (!doclear) 810*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set = 0; 811*f9cc9f20SBram Moolenaar } 812*f9cc9f20SBram Moolenaar 813*f9cc9f20SBram Moolenaar if (!doclear) 814*f9cc9f20SBram Moolenaar while (!ends_excmd(*linep)) 815*f9cc9f20SBram Moolenaar { 816*f9cc9f20SBram Moolenaar key_start = linep; 817*f9cc9f20SBram Moolenaar if (*linep == '=') 818*f9cc9f20SBram Moolenaar { 819*f9cc9f20SBram Moolenaar semsg(_("E415: unexpected equal sign: %s"), key_start); 820*f9cc9f20SBram Moolenaar error = TRUE; 821*f9cc9f20SBram Moolenaar break; 822*f9cc9f20SBram Moolenaar } 823*f9cc9f20SBram Moolenaar 824*f9cc9f20SBram Moolenaar /* 825*f9cc9f20SBram Moolenaar * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or 826*f9cc9f20SBram Moolenaar * "guibg"). 827*f9cc9f20SBram Moolenaar */ 828*f9cc9f20SBram Moolenaar while (*linep && !VIM_ISWHITE(*linep) && *linep != '=') 829*f9cc9f20SBram Moolenaar ++linep; 830*f9cc9f20SBram Moolenaar vim_free(key); 831*f9cc9f20SBram Moolenaar key = vim_strnsave_up(key_start, (int)(linep - key_start)); 832*f9cc9f20SBram Moolenaar if (key == NULL) 833*f9cc9f20SBram Moolenaar { 834*f9cc9f20SBram Moolenaar error = TRUE; 835*f9cc9f20SBram Moolenaar break; 836*f9cc9f20SBram Moolenaar } 837*f9cc9f20SBram Moolenaar linep = skipwhite(linep); 838*f9cc9f20SBram Moolenaar 839*f9cc9f20SBram Moolenaar if (STRCMP(key, "NONE") == 0) 840*f9cc9f20SBram Moolenaar { 841*f9cc9f20SBram Moolenaar if (!init || HL_TABLE()[idx].sg_set == 0) 842*f9cc9f20SBram Moolenaar { 843*f9cc9f20SBram Moolenaar if (!init) 844*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI; 845*f9cc9f20SBram Moolenaar highlight_clear(idx); 846*f9cc9f20SBram Moolenaar } 847*f9cc9f20SBram Moolenaar continue; 848*f9cc9f20SBram Moolenaar } 849*f9cc9f20SBram Moolenaar 850*f9cc9f20SBram Moolenaar /* 851*f9cc9f20SBram Moolenaar * Check for the equal sign. 852*f9cc9f20SBram Moolenaar */ 853*f9cc9f20SBram Moolenaar if (*linep != '=') 854*f9cc9f20SBram Moolenaar { 855*f9cc9f20SBram Moolenaar semsg(_("E416: missing equal sign: %s"), key_start); 856*f9cc9f20SBram Moolenaar error = TRUE; 857*f9cc9f20SBram Moolenaar break; 858*f9cc9f20SBram Moolenaar } 859*f9cc9f20SBram Moolenaar ++linep; 860*f9cc9f20SBram Moolenaar 861*f9cc9f20SBram Moolenaar /* 862*f9cc9f20SBram Moolenaar * Isolate the argument. 863*f9cc9f20SBram Moolenaar */ 864*f9cc9f20SBram Moolenaar linep = skipwhite(linep); 865*f9cc9f20SBram Moolenaar if (*linep == '\'') // guifg='color name' 866*f9cc9f20SBram Moolenaar { 867*f9cc9f20SBram Moolenaar arg_start = ++linep; 868*f9cc9f20SBram Moolenaar linep = vim_strchr(linep, '\''); 869*f9cc9f20SBram Moolenaar if (linep == NULL) 870*f9cc9f20SBram Moolenaar { 871*f9cc9f20SBram Moolenaar semsg(_(e_invarg2), key_start); 872*f9cc9f20SBram Moolenaar error = TRUE; 873*f9cc9f20SBram Moolenaar break; 874*f9cc9f20SBram Moolenaar } 875*f9cc9f20SBram Moolenaar } 876*f9cc9f20SBram Moolenaar else 877*f9cc9f20SBram Moolenaar { 878*f9cc9f20SBram Moolenaar arg_start = linep; 879*f9cc9f20SBram Moolenaar linep = skiptowhite(linep); 880*f9cc9f20SBram Moolenaar } 881*f9cc9f20SBram Moolenaar if (linep == arg_start) 882*f9cc9f20SBram Moolenaar { 883*f9cc9f20SBram Moolenaar semsg(_("E417: missing argument: %s"), key_start); 884*f9cc9f20SBram Moolenaar error = TRUE; 885*f9cc9f20SBram Moolenaar break; 886*f9cc9f20SBram Moolenaar } 887*f9cc9f20SBram Moolenaar vim_free(arg); 888*f9cc9f20SBram Moolenaar arg = vim_strnsave(arg_start, (int)(linep - arg_start)); 889*f9cc9f20SBram Moolenaar if (arg == NULL) 890*f9cc9f20SBram Moolenaar { 891*f9cc9f20SBram Moolenaar error = TRUE; 892*f9cc9f20SBram Moolenaar break; 893*f9cc9f20SBram Moolenaar } 894*f9cc9f20SBram Moolenaar if (*linep == '\'') 895*f9cc9f20SBram Moolenaar ++linep; 896*f9cc9f20SBram Moolenaar 897*f9cc9f20SBram Moolenaar /* 898*f9cc9f20SBram Moolenaar * Store the argument. 899*f9cc9f20SBram Moolenaar */ 900*f9cc9f20SBram Moolenaar if ( STRCMP(key, "TERM") == 0 901*f9cc9f20SBram Moolenaar || STRCMP(key, "CTERM") == 0 902*f9cc9f20SBram Moolenaar || STRCMP(key, "GUI") == 0) 903*f9cc9f20SBram Moolenaar { 904*f9cc9f20SBram Moolenaar attr = 0; 905*f9cc9f20SBram Moolenaar off = 0; 906*f9cc9f20SBram Moolenaar while (arg[off] != NUL) 907*f9cc9f20SBram Moolenaar { 908*f9cc9f20SBram Moolenaar for (i = sizeof(hl_attr_table) / sizeof(int); --i >= 0; ) 909*f9cc9f20SBram Moolenaar { 910*f9cc9f20SBram Moolenaar len = (int)STRLEN(hl_name_table[i]); 911*f9cc9f20SBram Moolenaar if (STRNICMP(arg + off, hl_name_table[i], len) == 0) 912*f9cc9f20SBram Moolenaar { 913*f9cc9f20SBram Moolenaar attr |= hl_attr_table[i]; 914*f9cc9f20SBram Moolenaar off += len; 915*f9cc9f20SBram Moolenaar break; 916*f9cc9f20SBram Moolenaar } 917*f9cc9f20SBram Moolenaar } 918*f9cc9f20SBram Moolenaar if (i < 0) 919*f9cc9f20SBram Moolenaar { 920*f9cc9f20SBram Moolenaar semsg(_("E418: Illegal value: %s"), arg); 921*f9cc9f20SBram Moolenaar error = TRUE; 922*f9cc9f20SBram Moolenaar break; 923*f9cc9f20SBram Moolenaar } 924*f9cc9f20SBram Moolenaar if (arg[off] == ',') // another one follows 925*f9cc9f20SBram Moolenaar ++off; 926*f9cc9f20SBram Moolenaar } 927*f9cc9f20SBram Moolenaar if (error) 928*f9cc9f20SBram Moolenaar break; 929*f9cc9f20SBram Moolenaar if (*key == 'T') 930*f9cc9f20SBram Moolenaar { 931*f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM)) 932*f9cc9f20SBram Moolenaar { 933*f9cc9f20SBram Moolenaar if (!init) 934*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_TERM; 935*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term = attr; 936*f9cc9f20SBram Moolenaar } 937*f9cc9f20SBram Moolenaar } 938*f9cc9f20SBram Moolenaar else if (*key == 'C') 939*f9cc9f20SBram Moolenaar { 940*f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) 941*f9cc9f20SBram Moolenaar { 942*f9cc9f20SBram Moolenaar if (!init) 943*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_CTERM; 944*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm = attr; 945*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = FALSE; 946*f9cc9f20SBram Moolenaar } 947*f9cc9f20SBram Moolenaar } 948*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 949*f9cc9f20SBram Moolenaar else 950*f9cc9f20SBram Moolenaar { 951*f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) 952*f9cc9f20SBram Moolenaar { 953*f9cc9f20SBram Moolenaar if (!init) 954*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI; 955*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui = attr; 956*f9cc9f20SBram Moolenaar } 957*f9cc9f20SBram Moolenaar } 958*f9cc9f20SBram Moolenaar #endif 959*f9cc9f20SBram Moolenaar } 960*f9cc9f20SBram Moolenaar else if (STRCMP(key, "FONT") == 0) 961*f9cc9f20SBram Moolenaar { 962*f9cc9f20SBram Moolenaar // in non-GUI fonts are simply ignored 963*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 964*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font_name != NULL 965*f9cc9f20SBram Moolenaar && STRCMP(HL_TABLE()[idx].sg_font_name, arg) == 0) 966*f9cc9f20SBram Moolenaar { 967*f9cc9f20SBram Moolenaar // Font name didn't change, ignore. 968*f9cc9f20SBram Moolenaar } 969*f9cc9f20SBram Moolenaar else if (!gui.shell_created) 970*f9cc9f20SBram Moolenaar { 971*f9cc9f20SBram Moolenaar // GUI not started yet, always accept the name. 972*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name); 973*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg); 974*f9cc9f20SBram Moolenaar did_change = TRUE; 975*f9cc9f20SBram Moolenaar } 976*f9cc9f20SBram Moolenaar else 977*f9cc9f20SBram Moolenaar { 978*f9cc9f20SBram Moolenaar GuiFont temp_sg_font = HL_TABLE()[idx].sg_font; 979*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 980*f9cc9f20SBram Moolenaar GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset; 981*f9cc9f20SBram Moolenaar # endif 982*f9cc9f20SBram Moolenaar // First, save the current font/fontset. 983*f9cc9f20SBram Moolenaar // Then try to allocate the font/fontset. 984*f9cc9f20SBram Moolenaar // If the allocation fails, HL_TABLE()[idx].sg_font OR 985*f9cc9f20SBram Moolenaar // sg_fontset will be set to NOFONT or NOFONTSET respectively. 986*f9cc9f20SBram Moolenaar 987*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT; 988*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 989*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET; 990*f9cc9f20SBram Moolenaar # endif 991*f9cc9f20SBram Moolenaar hl_do_font(idx, arg, is_normal_group, is_menu_group, 992*f9cc9f20SBram Moolenaar is_tooltip_group, FALSE); 993*f9cc9f20SBram Moolenaar 994*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 995*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_fontset != NOFONTSET) 996*f9cc9f20SBram Moolenaar { 997*f9cc9f20SBram Moolenaar // New fontset was accepted. Free the old one, if there 998*f9cc9f20SBram Moolenaar // was one. 999*f9cc9f20SBram Moolenaar gui_mch_free_fontset(temp_sg_fontset); 1000*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name); 1001*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg); 1002*f9cc9f20SBram Moolenaar did_change = TRUE; 1003*f9cc9f20SBram Moolenaar } 1004*f9cc9f20SBram Moolenaar else 1005*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = temp_sg_fontset; 1006*f9cc9f20SBram Moolenaar # endif 1007*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font != NOFONT) 1008*f9cc9f20SBram Moolenaar { 1009*f9cc9f20SBram Moolenaar // New font was accepted. Free the old one, if there was 1010*f9cc9f20SBram Moolenaar // one. 1011*f9cc9f20SBram Moolenaar gui_mch_free_font(temp_sg_font); 1012*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name); 1013*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg); 1014*f9cc9f20SBram Moolenaar did_change = TRUE; 1015*f9cc9f20SBram Moolenaar } 1016*f9cc9f20SBram Moolenaar else 1017*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = temp_sg_font; 1018*f9cc9f20SBram Moolenaar } 1019*f9cc9f20SBram Moolenaar #endif 1020*f9cc9f20SBram Moolenaar } 1021*f9cc9f20SBram Moolenaar else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) 1022*f9cc9f20SBram Moolenaar { 1023*f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) 1024*f9cc9f20SBram Moolenaar { 1025*f9cc9f20SBram Moolenaar if (!init) 1026*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_CTERM; 1027*f9cc9f20SBram Moolenaar 1028*f9cc9f20SBram Moolenaar // When setting the foreground color, and previously the "bold" 1029*f9cc9f20SBram Moolenaar // flag was set for a light color, reset it now 1030*f9cc9f20SBram Moolenaar if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold) 1031*f9cc9f20SBram Moolenaar { 1032*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; 1033*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = FALSE; 1034*f9cc9f20SBram Moolenaar } 1035*f9cc9f20SBram Moolenaar 1036*f9cc9f20SBram Moolenaar if (VIM_ISDIGIT(*arg)) 1037*f9cc9f20SBram Moolenaar color = atoi((char *)arg); 1038*f9cc9f20SBram Moolenaar else if (STRICMP(arg, "fg") == 0) 1039*f9cc9f20SBram Moolenaar { 1040*f9cc9f20SBram Moolenaar if (cterm_normal_fg_color) 1041*f9cc9f20SBram Moolenaar color = cterm_normal_fg_color - 1; 1042*f9cc9f20SBram Moolenaar else 1043*f9cc9f20SBram Moolenaar { 1044*f9cc9f20SBram Moolenaar emsg(_("E419: FG color unknown")); 1045*f9cc9f20SBram Moolenaar error = TRUE; 1046*f9cc9f20SBram Moolenaar break; 1047*f9cc9f20SBram Moolenaar } 1048*f9cc9f20SBram Moolenaar } 1049*f9cc9f20SBram Moolenaar else if (STRICMP(arg, "bg") == 0) 1050*f9cc9f20SBram Moolenaar { 1051*f9cc9f20SBram Moolenaar if (cterm_normal_bg_color > 0) 1052*f9cc9f20SBram Moolenaar color = cterm_normal_bg_color - 1; 1053*f9cc9f20SBram Moolenaar else 1054*f9cc9f20SBram Moolenaar { 1055*f9cc9f20SBram Moolenaar emsg(_("E420: BG color unknown")); 1056*f9cc9f20SBram Moolenaar error = TRUE; 1057*f9cc9f20SBram Moolenaar break; 1058*f9cc9f20SBram Moolenaar } 1059*f9cc9f20SBram Moolenaar } 1060*f9cc9f20SBram Moolenaar else 1061*f9cc9f20SBram Moolenaar { 1062*f9cc9f20SBram Moolenaar int bold = MAYBE; 1063*f9cc9f20SBram Moolenaar 1064*f9cc9f20SBram Moolenaar #if defined(__QNXNTO__) 1065*f9cc9f20SBram Moolenaar static int *color_numbers_8_qansi = color_numbers_8; 1066*f9cc9f20SBram Moolenaar // On qnx, the 8 & 16 color arrays are the same 1067*f9cc9f20SBram Moolenaar if (STRNCMP(T_NAME, "qansi", 5) == 0) 1068*f9cc9f20SBram Moolenaar color_numbers_8_qansi = color_numbers_16; 1069*f9cc9f20SBram Moolenaar #endif 1070*f9cc9f20SBram Moolenaar 1071*f9cc9f20SBram Moolenaar // reduce calls to STRICMP a bit, it can be slow 1072*f9cc9f20SBram Moolenaar off = TOUPPER_ASC(*arg); 1073*f9cc9f20SBram Moolenaar for (i = (sizeof(color_names) / sizeof(char *)); --i >= 0; ) 1074*f9cc9f20SBram Moolenaar if (off == color_names[i][0] 1075*f9cc9f20SBram Moolenaar && STRICMP(arg + 1, color_names[i] + 1) == 0) 1076*f9cc9f20SBram Moolenaar break; 1077*f9cc9f20SBram Moolenaar if (i < 0) 1078*f9cc9f20SBram Moolenaar { 1079*f9cc9f20SBram Moolenaar semsg(_("E421: Color name or number not recognized: %s"), key_start); 1080*f9cc9f20SBram Moolenaar error = TRUE; 1081*f9cc9f20SBram Moolenaar break; 1082*f9cc9f20SBram Moolenaar } 1083*f9cc9f20SBram Moolenaar 1084*f9cc9f20SBram Moolenaar color = lookup_color(i, key[5] == 'F', &bold); 1085*f9cc9f20SBram Moolenaar 1086*f9cc9f20SBram Moolenaar // set/reset bold attribute to get light foreground 1087*f9cc9f20SBram Moolenaar // colors (on some terminals, e.g. "linux") 1088*f9cc9f20SBram Moolenaar if (bold == TRUE) 1089*f9cc9f20SBram Moolenaar { 1090*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm |= HL_BOLD; 1091*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = TRUE; 1092*f9cc9f20SBram Moolenaar } 1093*f9cc9f20SBram Moolenaar else if (bold == FALSE) 1094*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; 1095*f9cc9f20SBram Moolenaar } 1096*f9cc9f20SBram Moolenaar 1097*f9cc9f20SBram Moolenaar // Add one to the argument, to avoid zero. Zero is used for 1098*f9cc9f20SBram Moolenaar // "NONE", then "color" is -1. 1099*f9cc9f20SBram Moolenaar if (key[5] == 'F') 1100*f9cc9f20SBram Moolenaar { 1101*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_fg = color + 1; 1102*f9cc9f20SBram Moolenaar if (is_normal_group) 1103*f9cc9f20SBram Moolenaar { 1104*f9cc9f20SBram Moolenaar cterm_normal_fg_color = color + 1; 1105*f9cc9f20SBram Moolenaar cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD); 1106*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1107*f9cc9f20SBram Moolenaar // Don't do this if the GUI is used. 1108*f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting) 1109*f9cc9f20SBram Moolenaar #endif 1110*f9cc9f20SBram Moolenaar { 1111*f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1112*f9cc9f20SBram Moolenaar if (termcap_active && color >= 0) 1113*f9cc9f20SBram Moolenaar term_fg_color(color); 1114*f9cc9f20SBram Moolenaar } 1115*f9cc9f20SBram Moolenaar } 1116*f9cc9f20SBram Moolenaar } 1117*f9cc9f20SBram Moolenaar else 1118*f9cc9f20SBram Moolenaar { 1119*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bg = color + 1; 1120*f9cc9f20SBram Moolenaar if (is_normal_group) 1121*f9cc9f20SBram Moolenaar { 1122*f9cc9f20SBram Moolenaar cterm_normal_bg_color = color + 1; 1123*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1124*f9cc9f20SBram Moolenaar // Don't mess with 'background' if the GUI is used. 1125*f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting) 1126*f9cc9f20SBram Moolenaar #endif 1127*f9cc9f20SBram Moolenaar { 1128*f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1129*f9cc9f20SBram Moolenaar if (color >= 0) 1130*f9cc9f20SBram Moolenaar { 1131*f9cc9f20SBram Moolenaar int dark = -1; 1132*f9cc9f20SBram Moolenaar 1133*f9cc9f20SBram Moolenaar if (termcap_active) 1134*f9cc9f20SBram Moolenaar term_bg_color(color); 1135*f9cc9f20SBram Moolenaar if (t_colors < 16) 1136*f9cc9f20SBram Moolenaar dark = (color == 0 || color == 4); 1137*f9cc9f20SBram Moolenaar // Limit the heuristic to the standard 16 colors 1138*f9cc9f20SBram Moolenaar else if (color < 16) 1139*f9cc9f20SBram Moolenaar dark = (color < 7 || color == 8); 1140*f9cc9f20SBram Moolenaar // Set the 'background' option if the value is 1141*f9cc9f20SBram Moolenaar // wrong. 1142*f9cc9f20SBram Moolenaar if (dark != -1 1143*f9cc9f20SBram Moolenaar && dark != (*p_bg == 'd') 1144*f9cc9f20SBram Moolenaar && !option_was_set((char_u *)"bg")) 1145*f9cc9f20SBram Moolenaar { 1146*f9cc9f20SBram Moolenaar set_option_value((char_u *)"bg", 0L, 1147*f9cc9f20SBram Moolenaar (char_u *)(dark ? "dark" : "light"), 0); 1148*f9cc9f20SBram Moolenaar reset_option_was_set((char_u *)"bg"); 1149*f9cc9f20SBram Moolenaar } 1150*f9cc9f20SBram Moolenaar } 1151*f9cc9f20SBram Moolenaar } 1152*f9cc9f20SBram Moolenaar } 1153*f9cc9f20SBram Moolenaar } 1154*f9cc9f20SBram Moolenaar } 1155*f9cc9f20SBram Moolenaar } 1156*f9cc9f20SBram Moolenaar else if (STRCMP(key, "GUIFG") == 0) 1157*f9cc9f20SBram Moolenaar { 1158*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1159*f9cc9f20SBram Moolenaar char_u **namep = &HL_TABLE()[idx].sg_gui_fg_name; 1160*f9cc9f20SBram Moolenaar 1161*f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) 1162*f9cc9f20SBram Moolenaar { 1163*f9cc9f20SBram Moolenaar if (!init) 1164*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI; 1165*f9cc9f20SBram Moolenaar 1166*f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1167*f9cc9f20SBram Moolenaar // In GUI guifg colors are only used when recognized 1168*f9cc9f20SBram Moolenaar i = color_name2handle(arg); 1169*f9cc9f20SBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) 1170*f9cc9f20SBram Moolenaar { 1171*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg = i; 1172*f9cc9f20SBram Moolenaar # endif 1173*f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0) 1174*f9cc9f20SBram Moolenaar { 1175*f9cc9f20SBram Moolenaar vim_free(*namep); 1176*f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0) 1177*f9cc9f20SBram Moolenaar *namep = vim_strsave(arg); 1178*f9cc9f20SBram Moolenaar else 1179*f9cc9f20SBram Moolenaar *namep = NULL; 1180*f9cc9f20SBram Moolenaar did_change = TRUE; 1181*f9cc9f20SBram Moolenaar } 1182*f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1183*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11 1184*f9cc9f20SBram Moolenaar if (is_menu_group && gui.menu_fg_pixel != i) 1185*f9cc9f20SBram Moolenaar { 1186*f9cc9f20SBram Moolenaar gui.menu_fg_pixel = i; 1187*f9cc9f20SBram Moolenaar do_colors = TRUE; 1188*f9cc9f20SBram Moolenaar } 1189*f9cc9f20SBram Moolenaar if (is_scrollbar_group && gui.scroll_fg_pixel != i) 1190*f9cc9f20SBram Moolenaar { 1191*f9cc9f20SBram Moolenaar gui.scroll_fg_pixel = i; 1192*f9cc9f20SBram Moolenaar do_colors = TRUE; 1193*f9cc9f20SBram Moolenaar } 1194*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1195*f9cc9f20SBram Moolenaar if (is_tooltip_group && gui.tooltip_fg_pixel != i) 1196*f9cc9f20SBram Moolenaar { 1197*f9cc9f20SBram Moolenaar gui.tooltip_fg_pixel = i; 1198*f9cc9f20SBram Moolenaar do_colors = TRUE; 1199*f9cc9f20SBram Moolenaar } 1200*f9cc9f20SBram Moolenaar # endif 1201*f9cc9f20SBram Moolenaar # endif 1202*f9cc9f20SBram Moolenaar } 1203*f9cc9f20SBram Moolenaar # endif 1204*f9cc9f20SBram Moolenaar } 1205*f9cc9f20SBram Moolenaar #endif 1206*f9cc9f20SBram Moolenaar } 1207*f9cc9f20SBram Moolenaar else if (STRCMP(key, "GUIBG") == 0) 1208*f9cc9f20SBram Moolenaar { 1209*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1210*f9cc9f20SBram Moolenaar char_u **namep = &HL_TABLE()[idx].sg_gui_bg_name; 1211*f9cc9f20SBram Moolenaar 1212*f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) 1213*f9cc9f20SBram Moolenaar { 1214*f9cc9f20SBram Moolenaar if (!init) 1215*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI; 1216*f9cc9f20SBram Moolenaar 1217*f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1218*f9cc9f20SBram Moolenaar // In GUI guifg colors are only used when recognized 1219*f9cc9f20SBram Moolenaar i = color_name2handle(arg); 1220*f9cc9f20SBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) 1221*f9cc9f20SBram Moolenaar { 1222*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg = i; 1223*f9cc9f20SBram Moolenaar # endif 1224*f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0) 1225*f9cc9f20SBram Moolenaar { 1226*f9cc9f20SBram Moolenaar vim_free(*namep); 1227*f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0) 1228*f9cc9f20SBram Moolenaar *namep = vim_strsave(arg); 1229*f9cc9f20SBram Moolenaar else 1230*f9cc9f20SBram Moolenaar *namep = NULL; 1231*f9cc9f20SBram Moolenaar did_change = TRUE; 1232*f9cc9f20SBram Moolenaar } 1233*f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1234*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11 1235*f9cc9f20SBram Moolenaar if (is_menu_group && gui.menu_bg_pixel != i) 1236*f9cc9f20SBram Moolenaar { 1237*f9cc9f20SBram Moolenaar gui.menu_bg_pixel = i; 1238*f9cc9f20SBram Moolenaar do_colors = TRUE; 1239*f9cc9f20SBram Moolenaar } 1240*f9cc9f20SBram Moolenaar if (is_scrollbar_group && gui.scroll_bg_pixel != i) 1241*f9cc9f20SBram Moolenaar { 1242*f9cc9f20SBram Moolenaar gui.scroll_bg_pixel = i; 1243*f9cc9f20SBram Moolenaar do_colors = TRUE; 1244*f9cc9f20SBram Moolenaar } 1245*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1246*f9cc9f20SBram Moolenaar if (is_tooltip_group && gui.tooltip_bg_pixel != i) 1247*f9cc9f20SBram Moolenaar { 1248*f9cc9f20SBram Moolenaar gui.tooltip_bg_pixel = i; 1249*f9cc9f20SBram Moolenaar do_colors = TRUE; 1250*f9cc9f20SBram Moolenaar } 1251*f9cc9f20SBram Moolenaar # endif 1252*f9cc9f20SBram Moolenaar # endif 1253*f9cc9f20SBram Moolenaar } 1254*f9cc9f20SBram Moolenaar # endif 1255*f9cc9f20SBram Moolenaar } 1256*f9cc9f20SBram Moolenaar #endif 1257*f9cc9f20SBram Moolenaar } 1258*f9cc9f20SBram Moolenaar else if (STRCMP(key, "GUISP") == 0) 1259*f9cc9f20SBram Moolenaar { 1260*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1261*f9cc9f20SBram Moolenaar char_u **namep = &HL_TABLE()[idx].sg_gui_sp_name; 1262*f9cc9f20SBram Moolenaar 1263*f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) 1264*f9cc9f20SBram Moolenaar { 1265*f9cc9f20SBram Moolenaar if (!init) 1266*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI; 1267*f9cc9f20SBram Moolenaar 1268*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 1269*f9cc9f20SBram Moolenaar i = color_name2handle(arg); 1270*f9cc9f20SBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use) 1271*f9cc9f20SBram Moolenaar { 1272*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_sp = i; 1273*f9cc9f20SBram Moolenaar # endif 1274*f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0) 1275*f9cc9f20SBram Moolenaar { 1276*f9cc9f20SBram Moolenaar vim_free(*namep); 1277*f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0) 1278*f9cc9f20SBram Moolenaar *namep = vim_strsave(arg); 1279*f9cc9f20SBram Moolenaar else 1280*f9cc9f20SBram Moolenaar *namep = NULL; 1281*f9cc9f20SBram Moolenaar did_change = TRUE; 1282*f9cc9f20SBram Moolenaar } 1283*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 1284*f9cc9f20SBram Moolenaar } 1285*f9cc9f20SBram Moolenaar # endif 1286*f9cc9f20SBram Moolenaar } 1287*f9cc9f20SBram Moolenaar #endif 1288*f9cc9f20SBram Moolenaar } 1289*f9cc9f20SBram Moolenaar else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0) 1290*f9cc9f20SBram Moolenaar { 1291*f9cc9f20SBram Moolenaar char_u buf[100]; 1292*f9cc9f20SBram Moolenaar char_u *tname; 1293*f9cc9f20SBram Moolenaar 1294*f9cc9f20SBram Moolenaar if (!init) 1295*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_TERM; 1296*f9cc9f20SBram Moolenaar 1297*f9cc9f20SBram Moolenaar /* 1298*f9cc9f20SBram Moolenaar * The "start" and "stop" arguments can be a literal escape 1299*f9cc9f20SBram Moolenaar * sequence, or a comma separated list of terminal codes. 1300*f9cc9f20SBram Moolenaar */ 1301*f9cc9f20SBram Moolenaar if (STRNCMP(arg, "t_", 2) == 0) 1302*f9cc9f20SBram Moolenaar { 1303*f9cc9f20SBram Moolenaar off = 0; 1304*f9cc9f20SBram Moolenaar buf[0] = 0; 1305*f9cc9f20SBram Moolenaar while (arg[off] != NUL) 1306*f9cc9f20SBram Moolenaar { 1307*f9cc9f20SBram Moolenaar // Isolate one termcap name 1308*f9cc9f20SBram Moolenaar for (len = 0; arg[off + len] && 1309*f9cc9f20SBram Moolenaar arg[off + len] != ','; ++len) 1310*f9cc9f20SBram Moolenaar ; 1311*f9cc9f20SBram Moolenaar tname = vim_strnsave(arg + off, len); 1312*f9cc9f20SBram Moolenaar if (tname == NULL) // out of memory 1313*f9cc9f20SBram Moolenaar { 1314*f9cc9f20SBram Moolenaar error = TRUE; 1315*f9cc9f20SBram Moolenaar break; 1316*f9cc9f20SBram Moolenaar } 1317*f9cc9f20SBram Moolenaar // lookup the escape sequence for the item 1318*f9cc9f20SBram Moolenaar p = get_term_code(tname); 1319*f9cc9f20SBram Moolenaar vim_free(tname); 1320*f9cc9f20SBram Moolenaar if (p == NULL) // ignore non-existing things 1321*f9cc9f20SBram Moolenaar p = (char_u *)""; 1322*f9cc9f20SBram Moolenaar 1323*f9cc9f20SBram Moolenaar // Append it to the already found stuff 1324*f9cc9f20SBram Moolenaar if ((int)(STRLEN(buf) + STRLEN(p)) >= 99) 1325*f9cc9f20SBram Moolenaar { 1326*f9cc9f20SBram Moolenaar semsg(_("E422: terminal code too long: %s"), arg); 1327*f9cc9f20SBram Moolenaar error = TRUE; 1328*f9cc9f20SBram Moolenaar break; 1329*f9cc9f20SBram Moolenaar } 1330*f9cc9f20SBram Moolenaar STRCAT(buf, p); 1331*f9cc9f20SBram Moolenaar 1332*f9cc9f20SBram Moolenaar // Advance to the next item 1333*f9cc9f20SBram Moolenaar off += len; 1334*f9cc9f20SBram Moolenaar if (arg[off] == ',') // another one follows 1335*f9cc9f20SBram Moolenaar ++off; 1336*f9cc9f20SBram Moolenaar } 1337*f9cc9f20SBram Moolenaar } 1338*f9cc9f20SBram Moolenaar else 1339*f9cc9f20SBram Moolenaar { 1340*f9cc9f20SBram Moolenaar /* 1341*f9cc9f20SBram Moolenaar * Copy characters from arg[] to buf[], translating <> codes. 1342*f9cc9f20SBram Moolenaar */ 1343*f9cc9f20SBram Moolenaar for (p = arg, off = 0; off < 100 - 6 && *p; ) 1344*f9cc9f20SBram Moolenaar { 1345*f9cc9f20SBram Moolenaar len = trans_special(&p, buf + off, FALSE, FALSE); 1346*f9cc9f20SBram Moolenaar if (len > 0) // recognized special char 1347*f9cc9f20SBram Moolenaar off += len; 1348*f9cc9f20SBram Moolenaar else // copy as normal char 1349*f9cc9f20SBram Moolenaar buf[off++] = *p++; 1350*f9cc9f20SBram Moolenaar } 1351*f9cc9f20SBram Moolenaar buf[off] = NUL; 1352*f9cc9f20SBram Moolenaar } 1353*f9cc9f20SBram Moolenaar if (error) 1354*f9cc9f20SBram Moolenaar break; 1355*f9cc9f20SBram Moolenaar 1356*f9cc9f20SBram Moolenaar if (STRCMP(buf, "NONE") == 0) // resetting the value 1357*f9cc9f20SBram Moolenaar p = NULL; 1358*f9cc9f20SBram Moolenaar else 1359*f9cc9f20SBram Moolenaar p = vim_strsave(buf); 1360*f9cc9f20SBram Moolenaar if (key[2] == 'A') 1361*f9cc9f20SBram Moolenaar { 1362*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_start); 1363*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_start = p; 1364*f9cc9f20SBram Moolenaar } 1365*f9cc9f20SBram Moolenaar else 1366*f9cc9f20SBram Moolenaar { 1367*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_stop); 1368*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_stop = p; 1369*f9cc9f20SBram Moolenaar } 1370*f9cc9f20SBram Moolenaar } 1371*f9cc9f20SBram Moolenaar else 1372*f9cc9f20SBram Moolenaar { 1373*f9cc9f20SBram Moolenaar semsg(_("E423: Illegal argument: %s"), key_start); 1374*f9cc9f20SBram Moolenaar error = TRUE; 1375*f9cc9f20SBram Moolenaar break; 1376*f9cc9f20SBram Moolenaar } 1377*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cleared = FALSE; 1378*f9cc9f20SBram Moolenaar 1379*f9cc9f20SBram Moolenaar /* 1380*f9cc9f20SBram Moolenaar * When highlighting has been given for a group, don't link it. 1381*f9cc9f20SBram Moolenaar */ 1382*f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) 1383*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_link = 0; 1384*f9cc9f20SBram Moolenaar 1385*f9cc9f20SBram Moolenaar /* 1386*f9cc9f20SBram Moolenaar * Continue with next argument. 1387*f9cc9f20SBram Moolenaar */ 1388*f9cc9f20SBram Moolenaar linep = skipwhite(linep); 1389*f9cc9f20SBram Moolenaar } 1390*f9cc9f20SBram Moolenaar 1391*f9cc9f20SBram Moolenaar /* 1392*f9cc9f20SBram Moolenaar * If there is an error, and it's a new entry, remove it from the table. 1393*f9cc9f20SBram Moolenaar */ 1394*f9cc9f20SBram Moolenaar if (error && idx == highlight_ga.ga_len) 1395*f9cc9f20SBram Moolenaar syn_unadd_group(); 1396*f9cc9f20SBram Moolenaar else 1397*f9cc9f20SBram Moolenaar { 1398*f9cc9f20SBram Moolenaar if (is_normal_group) 1399*f9cc9f20SBram Moolenaar { 1400*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term_attr = 0; 1401*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_attr = 0; 1402*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1403*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_attr = 0; 1404*f9cc9f20SBram Moolenaar /* 1405*f9cc9f20SBram Moolenaar * Need to update all groups, because they might be using "bg" 1406*f9cc9f20SBram Moolenaar * and/or "fg", which have been changed now. 1407*f9cc9f20SBram Moolenaar */ 1408*f9cc9f20SBram Moolenaar #endif 1409*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1410*f9cc9f20SBram Moolenaar if (USE_24BIT) 1411*f9cc9f20SBram Moolenaar { 1412*f9cc9f20SBram Moolenaar highlight_gui_started(); 1413*f9cc9f20SBram Moolenaar did_highlight_changed = TRUE; 1414*f9cc9f20SBram Moolenaar redraw_all_later(NOT_VALID); 1415*f9cc9f20SBram Moolenaar } 1416*f9cc9f20SBram Moolenaar #endif 1417*f9cc9f20SBram Moolenaar } 1418*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 1419*f9cc9f20SBram Moolenaar else if (is_terminal_group) 1420*f9cc9f20SBram Moolenaar set_terminal_default_colors( 1421*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_fg, HL_TABLE()[idx].sg_cterm_bg); 1422*f9cc9f20SBram Moolenaar #endif 1423*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI_X11 1424*f9cc9f20SBram Moolenaar # ifdef FEAT_MENU 1425*f9cc9f20SBram Moolenaar else if (is_menu_group) 1426*f9cc9f20SBram Moolenaar { 1427*f9cc9f20SBram Moolenaar if (gui.in_use && do_colors) 1428*f9cc9f20SBram Moolenaar gui_mch_new_menu_colors(); 1429*f9cc9f20SBram Moolenaar } 1430*f9cc9f20SBram Moolenaar # endif 1431*f9cc9f20SBram Moolenaar else if (is_scrollbar_group) 1432*f9cc9f20SBram Moolenaar { 1433*f9cc9f20SBram Moolenaar if (gui.in_use && do_colors) 1434*f9cc9f20SBram Moolenaar gui_new_scrollbar_colors(); 1435*f9cc9f20SBram Moolenaar else 1436*f9cc9f20SBram Moolenaar set_hl_attr(idx); 1437*f9cc9f20SBram Moolenaar } 1438*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1439*f9cc9f20SBram Moolenaar else if (is_tooltip_group) 1440*f9cc9f20SBram Moolenaar { 1441*f9cc9f20SBram Moolenaar if (gui.in_use && do_colors) 1442*f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors(); 1443*f9cc9f20SBram Moolenaar } 1444*f9cc9f20SBram Moolenaar # endif 1445*f9cc9f20SBram Moolenaar #endif 1446*f9cc9f20SBram Moolenaar else 1447*f9cc9f20SBram Moolenaar set_hl_attr(idx); 1448*f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 1449*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_script_ctx = current_sctx; 1450*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_script_ctx.sc_lnum += sourcing_lnum; 1451*f9cc9f20SBram Moolenaar #endif 1452*f9cc9f20SBram Moolenaar } 1453*f9cc9f20SBram Moolenaar 1454*f9cc9f20SBram Moolenaar vim_free(key); 1455*f9cc9f20SBram Moolenaar vim_free(arg); 1456*f9cc9f20SBram Moolenaar 1457*f9cc9f20SBram Moolenaar // Only call highlight_changed() once, after a sequence of highlight 1458*f9cc9f20SBram Moolenaar // commands, and only if an attribute actually changed. 1459*f9cc9f20SBram Moolenaar if ((did_change 1460*f9cc9f20SBram Moolenaar || memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0) 1461*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1462*f9cc9f20SBram Moolenaar && !did_highlight_changed 1463*f9cc9f20SBram Moolenaar #endif 1464*f9cc9f20SBram Moolenaar ) 1465*f9cc9f20SBram Moolenaar { 1466*f9cc9f20SBram Moolenaar // Do not trigger a redraw when highlighting is changed while 1467*f9cc9f20SBram Moolenaar // redrawing. This may happen when evaluating 'statusline' changes the 1468*f9cc9f20SBram Moolenaar // StatusLine group. 1469*f9cc9f20SBram Moolenaar if (!updating_screen) 1470*f9cc9f20SBram Moolenaar redraw_all_later(NOT_VALID); 1471*f9cc9f20SBram Moolenaar need_highlight_changed = TRUE; 1472*f9cc9f20SBram Moolenaar } 1473*f9cc9f20SBram Moolenaar } 1474*f9cc9f20SBram Moolenaar 1475*f9cc9f20SBram Moolenaar #if defined(EXITFREE) || defined(PROTO) 1476*f9cc9f20SBram Moolenaar void 1477*f9cc9f20SBram Moolenaar free_highlight(void) 1478*f9cc9f20SBram Moolenaar { 1479*f9cc9f20SBram Moolenaar int i; 1480*f9cc9f20SBram Moolenaar 1481*f9cc9f20SBram Moolenaar for (i = 0; i < highlight_ga.ga_len; ++i) 1482*f9cc9f20SBram Moolenaar { 1483*f9cc9f20SBram Moolenaar highlight_clear(i); 1484*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[i].sg_name); 1485*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[i].sg_name_u); 1486*f9cc9f20SBram Moolenaar } 1487*f9cc9f20SBram Moolenaar ga_clear(&highlight_ga); 1488*f9cc9f20SBram Moolenaar } 1489*f9cc9f20SBram Moolenaar #endif 1490*f9cc9f20SBram Moolenaar 1491*f9cc9f20SBram Moolenaar /* 1492*f9cc9f20SBram Moolenaar * Reset the cterm colors to what they were before Vim was started, if 1493*f9cc9f20SBram Moolenaar * possible. Otherwise reset them to zero. 1494*f9cc9f20SBram Moolenaar */ 1495*f9cc9f20SBram Moolenaar void 1496*f9cc9f20SBram Moolenaar restore_cterm_colors(void) 1497*f9cc9f20SBram Moolenaar { 1498*f9cc9f20SBram Moolenaar #if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) 1499*f9cc9f20SBram Moolenaar // Since t_me has been set, this probably means that the user 1500*f9cc9f20SBram Moolenaar // wants to use this as default colors. Need to reset default 1501*f9cc9f20SBram Moolenaar // background/foreground colors. 1502*f9cc9f20SBram Moolenaar mch_set_normal_colors(); 1503*f9cc9f20SBram Moolenaar #else 1504*f9cc9f20SBram Moolenaar # ifdef VIMDLL 1505*f9cc9f20SBram Moolenaar if (!gui.in_use) 1506*f9cc9f20SBram Moolenaar { 1507*f9cc9f20SBram Moolenaar mch_set_normal_colors(); 1508*f9cc9f20SBram Moolenaar return; 1509*f9cc9f20SBram Moolenaar } 1510*f9cc9f20SBram Moolenaar # endif 1511*f9cc9f20SBram Moolenaar cterm_normal_fg_color = 0; 1512*f9cc9f20SBram Moolenaar cterm_normal_fg_bold = 0; 1513*f9cc9f20SBram Moolenaar cterm_normal_bg_color = 0; 1514*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 1515*f9cc9f20SBram Moolenaar cterm_normal_fg_gui_color = INVALCOLOR; 1516*f9cc9f20SBram Moolenaar cterm_normal_bg_gui_color = INVALCOLOR; 1517*f9cc9f20SBram Moolenaar # endif 1518*f9cc9f20SBram Moolenaar #endif 1519*f9cc9f20SBram Moolenaar } 1520*f9cc9f20SBram Moolenaar 1521*f9cc9f20SBram Moolenaar /* 1522*f9cc9f20SBram Moolenaar * Return TRUE if highlight group "idx" has any settings. 1523*f9cc9f20SBram Moolenaar * When "check_link" is TRUE also check for an existing link. 1524*f9cc9f20SBram Moolenaar */ 1525*f9cc9f20SBram Moolenaar static int 1526*f9cc9f20SBram Moolenaar hl_has_settings(int idx, int check_link) 1527*f9cc9f20SBram Moolenaar { 1528*f9cc9f20SBram Moolenaar return ( HL_TABLE()[idx].sg_term_attr != 0 1529*f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_attr != 0 1530*f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_fg != 0 1531*f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_bg != 0 1532*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1533*f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_attr != 0 1534*f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_fg_name != NULL 1535*f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_bg_name != NULL 1536*f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_sp_name != NULL 1537*f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_font_name != NULL 1538*f9cc9f20SBram Moolenaar #endif 1539*f9cc9f20SBram Moolenaar || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK))); 1540*f9cc9f20SBram Moolenaar } 1541*f9cc9f20SBram Moolenaar 1542*f9cc9f20SBram Moolenaar /* 1543*f9cc9f20SBram Moolenaar * Clear highlighting for one group. 1544*f9cc9f20SBram Moolenaar */ 1545*f9cc9f20SBram Moolenaar static void 1546*f9cc9f20SBram Moolenaar highlight_clear(int idx) 1547*f9cc9f20SBram Moolenaar { 1548*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cleared = TRUE; 1549*f9cc9f20SBram Moolenaar 1550*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term = 0; 1551*f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_start); 1552*f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_stop); 1553*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term_attr = 0; 1554*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm = 0; 1555*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = FALSE; 1556*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_fg = 0; 1557*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bg = 0; 1558*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_attr = 0; 1559*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1560*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui = 0; 1561*f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_fg_name); 1562*f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_bg_name); 1563*f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_sp_name); 1564*f9cc9f20SBram Moolenaar #endif 1565*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1566*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg = INVALCOLOR; 1567*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg = INVALCOLOR; 1568*f9cc9f20SBram Moolenaar #endif 1569*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1570*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_sp = INVALCOLOR; 1571*f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font); 1572*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT; 1573*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1574*f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); 1575*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET; 1576*f9cc9f20SBram Moolenaar # endif 1577*f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_font_name); 1578*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_attr = 0; 1579*f9cc9f20SBram Moolenaar #endif 1580*f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 1581*f9cc9f20SBram Moolenaar // Clear the script ID only when there is no link, since that is not 1582*f9cc9f20SBram Moolenaar // cleared. 1583*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_link == 0) 1584*f9cc9f20SBram Moolenaar { 1585*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_script_ctx.sc_sid = 0; 1586*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_script_ctx.sc_lnum = 0; 1587*f9cc9f20SBram Moolenaar } 1588*f9cc9f20SBram Moolenaar #endif 1589*f9cc9f20SBram Moolenaar } 1590*f9cc9f20SBram Moolenaar 1591*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) 1592*f9cc9f20SBram Moolenaar /* 1593*f9cc9f20SBram Moolenaar * Set the normal foreground and background colors according to the "Normal" 1594*f9cc9f20SBram Moolenaar * highlighting group. For X11 also set "Menu", "Scrollbar", and 1595*f9cc9f20SBram Moolenaar * "Tooltip" colors. 1596*f9cc9f20SBram Moolenaar */ 1597*f9cc9f20SBram Moolenaar void 1598*f9cc9f20SBram Moolenaar set_normal_colors(void) 1599*f9cc9f20SBram Moolenaar { 1600*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 1601*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 1602*f9cc9f20SBram Moolenaar if (gui.in_use) 1603*f9cc9f20SBram Moolenaar # endif 1604*f9cc9f20SBram Moolenaar { 1605*f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Normal", 1606*f9cc9f20SBram Moolenaar &gui.norm_pixel, &gui.back_pixel, 1607*f9cc9f20SBram Moolenaar FALSE, TRUE, FALSE)) 1608*f9cc9f20SBram Moolenaar { 1609*f9cc9f20SBram Moolenaar gui_mch_new_colors(); 1610*f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1611*f9cc9f20SBram Moolenaar } 1612*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11 1613*f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Menu", 1614*f9cc9f20SBram Moolenaar &gui.menu_fg_pixel, &gui.menu_bg_pixel, 1615*f9cc9f20SBram Moolenaar TRUE, FALSE, FALSE)) 1616*f9cc9f20SBram Moolenaar { 1617*f9cc9f20SBram Moolenaar # ifdef FEAT_MENU 1618*f9cc9f20SBram Moolenaar gui_mch_new_menu_colors(); 1619*f9cc9f20SBram Moolenaar # endif 1620*f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1621*f9cc9f20SBram Moolenaar } 1622*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1623*f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Tooltip", 1624*f9cc9f20SBram Moolenaar &gui.tooltip_fg_pixel, &gui.tooltip_bg_pixel, 1625*f9cc9f20SBram Moolenaar FALSE, FALSE, TRUE)) 1626*f9cc9f20SBram Moolenaar { 1627*f9cc9f20SBram Moolenaar # ifdef FEAT_TOOLBAR 1628*f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors(); 1629*f9cc9f20SBram Moolenaar # endif 1630*f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1631*f9cc9f20SBram Moolenaar } 1632*f9cc9f20SBram Moolenaar # endif 1633*f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Scrollbar", 1634*f9cc9f20SBram Moolenaar &gui.scroll_fg_pixel, &gui.scroll_bg_pixel, 1635*f9cc9f20SBram Moolenaar FALSE, FALSE, FALSE)) 1636*f9cc9f20SBram Moolenaar { 1637*f9cc9f20SBram Moolenaar gui_new_scrollbar_colors(); 1638*f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1639*f9cc9f20SBram Moolenaar } 1640*f9cc9f20SBram Moolenaar # endif 1641*f9cc9f20SBram Moolenaar } 1642*f9cc9f20SBram Moolenaar # endif 1643*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 1644*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 1645*f9cc9f20SBram Moolenaar else 1646*f9cc9f20SBram Moolenaar # endif 1647*f9cc9f20SBram Moolenaar { 1648*f9cc9f20SBram Moolenaar int idx; 1649*f9cc9f20SBram Moolenaar 1650*f9cc9f20SBram Moolenaar idx = syn_name2id((char_u *)"Normal") - 1; 1651*f9cc9f20SBram Moolenaar if (idx >= 0) 1652*f9cc9f20SBram Moolenaar { 1653*f9cc9f20SBram Moolenaar gui_do_one_color(idx, FALSE, FALSE); 1654*f9cc9f20SBram Moolenaar 1655*f9cc9f20SBram Moolenaar // If the normal fg or bg color changed a complete redraw is 1656*f9cc9f20SBram Moolenaar // required. 1657*f9cc9f20SBram Moolenaar if (cterm_normal_fg_gui_color != HL_TABLE()[idx].sg_gui_fg 1658*f9cc9f20SBram Moolenaar || cterm_normal_bg_gui_color != HL_TABLE()[idx].sg_gui_bg) 1659*f9cc9f20SBram Moolenaar { 1660*f9cc9f20SBram Moolenaar // if the GUI color is INVALCOLOR then we use the default cterm 1661*f9cc9f20SBram Moolenaar // color 1662*f9cc9f20SBram Moolenaar cterm_normal_fg_gui_color = HL_TABLE()[idx].sg_gui_fg; 1663*f9cc9f20SBram Moolenaar cterm_normal_bg_gui_color = HL_TABLE()[idx].sg_gui_bg; 1664*f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1665*f9cc9f20SBram Moolenaar } 1666*f9cc9f20SBram Moolenaar } 1667*f9cc9f20SBram Moolenaar } 1668*f9cc9f20SBram Moolenaar # endif 1669*f9cc9f20SBram Moolenaar } 1670*f9cc9f20SBram Moolenaar #endif 1671*f9cc9f20SBram Moolenaar 1672*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(PROTO) 1673*f9cc9f20SBram Moolenaar /* 1674*f9cc9f20SBram Moolenaar * Set the colors for "Normal", "Menu", "Tooltip" or "Scrollbar". 1675*f9cc9f20SBram Moolenaar */ 1676*f9cc9f20SBram Moolenaar static int 1677*f9cc9f20SBram Moolenaar set_group_colors( 1678*f9cc9f20SBram Moolenaar char_u *name, 1679*f9cc9f20SBram Moolenaar guicolor_T *fgp, 1680*f9cc9f20SBram Moolenaar guicolor_T *bgp, 1681*f9cc9f20SBram Moolenaar int do_menu, 1682*f9cc9f20SBram Moolenaar int use_norm, 1683*f9cc9f20SBram Moolenaar int do_tooltip) 1684*f9cc9f20SBram Moolenaar { 1685*f9cc9f20SBram Moolenaar int idx; 1686*f9cc9f20SBram Moolenaar 1687*f9cc9f20SBram Moolenaar idx = syn_name2id(name) - 1; 1688*f9cc9f20SBram Moolenaar if (idx >= 0) 1689*f9cc9f20SBram Moolenaar { 1690*f9cc9f20SBram Moolenaar gui_do_one_color(idx, do_menu, do_tooltip); 1691*f9cc9f20SBram Moolenaar 1692*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_fg != INVALCOLOR) 1693*f9cc9f20SBram Moolenaar *fgp = HL_TABLE()[idx].sg_gui_fg; 1694*f9cc9f20SBram Moolenaar else if (use_norm) 1695*f9cc9f20SBram Moolenaar *fgp = gui.def_norm_pixel; 1696*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_bg != INVALCOLOR) 1697*f9cc9f20SBram Moolenaar *bgp = HL_TABLE()[idx].sg_gui_bg; 1698*f9cc9f20SBram Moolenaar else if (use_norm) 1699*f9cc9f20SBram Moolenaar *bgp = gui.def_back_pixel; 1700*f9cc9f20SBram Moolenaar return TRUE; 1701*f9cc9f20SBram Moolenaar } 1702*f9cc9f20SBram Moolenaar return FALSE; 1703*f9cc9f20SBram Moolenaar } 1704*f9cc9f20SBram Moolenaar 1705*f9cc9f20SBram Moolenaar /* 1706*f9cc9f20SBram Moolenaar * Get the font of the "Normal" group. 1707*f9cc9f20SBram Moolenaar * Returns "" when it's not found or not set. 1708*f9cc9f20SBram Moolenaar */ 1709*f9cc9f20SBram Moolenaar char_u * 1710*f9cc9f20SBram Moolenaar hl_get_font_name(void) 1711*f9cc9f20SBram Moolenaar { 1712*f9cc9f20SBram Moolenaar int id; 1713*f9cc9f20SBram Moolenaar char_u *s; 1714*f9cc9f20SBram Moolenaar 1715*f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 1716*f9cc9f20SBram Moolenaar if (id > 0) 1717*f9cc9f20SBram Moolenaar { 1718*f9cc9f20SBram Moolenaar s = HL_TABLE()[id - 1].sg_font_name; 1719*f9cc9f20SBram Moolenaar if (s != NULL) 1720*f9cc9f20SBram Moolenaar return s; 1721*f9cc9f20SBram Moolenaar } 1722*f9cc9f20SBram Moolenaar return (char_u *)""; 1723*f9cc9f20SBram Moolenaar } 1724*f9cc9f20SBram Moolenaar 1725*f9cc9f20SBram Moolenaar /* 1726*f9cc9f20SBram Moolenaar * Set font for "Normal" group. Called by gui_mch_init_font() when a font has 1727*f9cc9f20SBram Moolenaar * actually chosen to be used. 1728*f9cc9f20SBram Moolenaar */ 1729*f9cc9f20SBram Moolenaar void 1730*f9cc9f20SBram Moolenaar hl_set_font_name(char_u *font_name) 1731*f9cc9f20SBram Moolenaar { 1732*f9cc9f20SBram Moolenaar int id; 1733*f9cc9f20SBram Moolenaar 1734*f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 1735*f9cc9f20SBram Moolenaar if (id > 0) 1736*f9cc9f20SBram Moolenaar { 1737*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_font_name); 1738*f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_font_name = vim_strsave(font_name); 1739*f9cc9f20SBram Moolenaar } 1740*f9cc9f20SBram Moolenaar } 1741*f9cc9f20SBram Moolenaar 1742*f9cc9f20SBram Moolenaar /* 1743*f9cc9f20SBram Moolenaar * Set background color for "Normal" group. Called by gui_set_bg_color() 1744*f9cc9f20SBram Moolenaar * when the color is known. 1745*f9cc9f20SBram Moolenaar */ 1746*f9cc9f20SBram Moolenaar void 1747*f9cc9f20SBram Moolenaar hl_set_bg_color_name( 1748*f9cc9f20SBram Moolenaar char_u *name) // must have been allocated 1749*f9cc9f20SBram Moolenaar { 1750*f9cc9f20SBram Moolenaar int id; 1751*f9cc9f20SBram Moolenaar 1752*f9cc9f20SBram Moolenaar if (name != NULL) 1753*f9cc9f20SBram Moolenaar { 1754*f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 1755*f9cc9f20SBram Moolenaar if (id > 0) 1756*f9cc9f20SBram Moolenaar { 1757*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_gui_bg_name); 1758*f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_gui_bg_name = name; 1759*f9cc9f20SBram Moolenaar } 1760*f9cc9f20SBram Moolenaar } 1761*f9cc9f20SBram Moolenaar } 1762*f9cc9f20SBram Moolenaar 1763*f9cc9f20SBram Moolenaar /* 1764*f9cc9f20SBram Moolenaar * Set foreground color for "Normal" group. Called by gui_set_fg_color() 1765*f9cc9f20SBram Moolenaar * when the color is known. 1766*f9cc9f20SBram Moolenaar */ 1767*f9cc9f20SBram Moolenaar void 1768*f9cc9f20SBram Moolenaar hl_set_fg_color_name( 1769*f9cc9f20SBram Moolenaar char_u *name) // must have been allocated 1770*f9cc9f20SBram Moolenaar { 1771*f9cc9f20SBram Moolenaar int id; 1772*f9cc9f20SBram Moolenaar 1773*f9cc9f20SBram Moolenaar if (name != NULL) 1774*f9cc9f20SBram Moolenaar { 1775*f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 1776*f9cc9f20SBram Moolenaar if (id > 0) 1777*f9cc9f20SBram Moolenaar { 1778*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_gui_fg_name); 1779*f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_gui_fg_name = name; 1780*f9cc9f20SBram Moolenaar } 1781*f9cc9f20SBram Moolenaar } 1782*f9cc9f20SBram Moolenaar } 1783*f9cc9f20SBram Moolenaar 1784*f9cc9f20SBram Moolenaar /* 1785*f9cc9f20SBram Moolenaar * Return the handle for a font name. 1786*f9cc9f20SBram Moolenaar * Returns NOFONT when failed. 1787*f9cc9f20SBram Moolenaar */ 1788*f9cc9f20SBram Moolenaar static GuiFont 1789*f9cc9f20SBram Moolenaar font_name2handle(char_u *name) 1790*f9cc9f20SBram Moolenaar { 1791*f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0) 1792*f9cc9f20SBram Moolenaar return NOFONT; 1793*f9cc9f20SBram Moolenaar 1794*f9cc9f20SBram Moolenaar return gui_mch_get_font(name, TRUE); 1795*f9cc9f20SBram Moolenaar } 1796*f9cc9f20SBram Moolenaar 1797*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1798*f9cc9f20SBram Moolenaar /* 1799*f9cc9f20SBram Moolenaar * Return the handle for a fontset name. 1800*f9cc9f20SBram Moolenaar * Returns NOFONTSET when failed. 1801*f9cc9f20SBram Moolenaar */ 1802*f9cc9f20SBram Moolenaar static GuiFontset 1803*f9cc9f20SBram Moolenaar fontset_name2handle(char_u *name, int fixed_width) 1804*f9cc9f20SBram Moolenaar { 1805*f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0) 1806*f9cc9f20SBram Moolenaar return NOFONTSET; 1807*f9cc9f20SBram Moolenaar 1808*f9cc9f20SBram Moolenaar return gui_mch_get_fontset(name, TRUE, fixed_width); 1809*f9cc9f20SBram Moolenaar } 1810*f9cc9f20SBram Moolenaar # endif 1811*f9cc9f20SBram Moolenaar 1812*f9cc9f20SBram Moolenaar /* 1813*f9cc9f20SBram Moolenaar * Get the font or fontset for one highlight group. 1814*f9cc9f20SBram Moolenaar */ 1815*f9cc9f20SBram Moolenaar static void 1816*f9cc9f20SBram Moolenaar hl_do_font( 1817*f9cc9f20SBram Moolenaar int idx, 1818*f9cc9f20SBram Moolenaar char_u *arg, 1819*f9cc9f20SBram Moolenaar int do_normal, // set normal font 1820*f9cc9f20SBram Moolenaar int do_menu UNUSED, // set menu font 1821*f9cc9f20SBram Moolenaar int do_tooltip UNUSED, // set tooltip font 1822*f9cc9f20SBram Moolenaar int free_font) // free current font/fontset 1823*f9cc9f20SBram Moolenaar { 1824*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1825*f9cc9f20SBram Moolenaar // If 'guifontset' is not empty, first try using the name as a 1826*f9cc9f20SBram Moolenaar // fontset. If that doesn't work, use it as a font name. 1827*f9cc9f20SBram Moolenaar if (*p_guifontset != NUL 1828*f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS 1829*f9cc9f20SBram Moolenaar || do_menu 1830*f9cc9f20SBram Moolenaar # endif 1831*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP 1832*f9cc9f20SBram Moolenaar // In Athena & Motif, the Tooltip highlight group is always a fontset 1833*f9cc9f20SBram Moolenaar || do_tooltip 1834*f9cc9f20SBram Moolenaar # endif 1835*f9cc9f20SBram Moolenaar ) 1836*f9cc9f20SBram Moolenaar { 1837*f9cc9f20SBram Moolenaar if (free_font) 1838*f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); 1839*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = fontset_name2handle(arg, 0 1840*f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS 1841*f9cc9f20SBram Moolenaar || do_menu 1842*f9cc9f20SBram Moolenaar # endif 1843*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP 1844*f9cc9f20SBram Moolenaar || do_tooltip 1845*f9cc9f20SBram Moolenaar # endif 1846*f9cc9f20SBram Moolenaar ); 1847*f9cc9f20SBram Moolenaar } 1848*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_fontset != NOFONTSET) 1849*f9cc9f20SBram Moolenaar { 1850*f9cc9f20SBram Moolenaar // If it worked and it's the Normal group, use it as the normal 1851*f9cc9f20SBram Moolenaar // fontset. Same for the Menu group. 1852*f9cc9f20SBram Moolenaar if (do_normal) 1853*f9cc9f20SBram Moolenaar gui_init_font(arg, TRUE); 1854*f9cc9f20SBram Moolenaar # if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU) 1855*f9cc9f20SBram Moolenaar if (do_menu) 1856*f9cc9f20SBram Moolenaar { 1857*f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS 1858*f9cc9f20SBram Moolenaar gui.menu_fontset = HL_TABLE()[idx].sg_fontset; 1859*f9cc9f20SBram Moolenaar # else 1860*f9cc9f20SBram Moolenaar // YIKES! This is a bug waiting to crash the program 1861*f9cc9f20SBram Moolenaar gui.menu_font = HL_TABLE()[idx].sg_fontset; 1862*f9cc9f20SBram Moolenaar # endif 1863*f9cc9f20SBram Moolenaar gui_mch_new_menu_font(); 1864*f9cc9f20SBram Moolenaar } 1865*f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1866*f9cc9f20SBram Moolenaar if (do_tooltip) 1867*f9cc9f20SBram Moolenaar { 1868*f9cc9f20SBram Moolenaar // The Athena widget set cannot currently handle switching between 1869*f9cc9f20SBram Moolenaar // displaying a single font and a fontset. 1870*f9cc9f20SBram Moolenaar // If the XtNinternational resource is set to True at widget 1871*f9cc9f20SBram Moolenaar // creation, then a fontset is always used, otherwise an 1872*f9cc9f20SBram Moolenaar // XFontStruct is used. 1873*f9cc9f20SBram Moolenaar gui.tooltip_fontset = (XFontSet)HL_TABLE()[idx].sg_fontset; 1874*f9cc9f20SBram Moolenaar gui_mch_new_tooltip_font(); 1875*f9cc9f20SBram Moolenaar } 1876*f9cc9f20SBram Moolenaar # endif 1877*f9cc9f20SBram Moolenaar # endif 1878*f9cc9f20SBram Moolenaar } 1879*f9cc9f20SBram Moolenaar else 1880*f9cc9f20SBram Moolenaar # endif 1881*f9cc9f20SBram Moolenaar { 1882*f9cc9f20SBram Moolenaar if (free_font) 1883*f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font); 1884*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = font_name2handle(arg); 1885*f9cc9f20SBram Moolenaar // If it worked and it's the Normal group, use it as the 1886*f9cc9f20SBram Moolenaar // normal font. Same for the Menu group. 1887*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font != NOFONT) 1888*f9cc9f20SBram Moolenaar { 1889*f9cc9f20SBram Moolenaar if (do_normal) 1890*f9cc9f20SBram Moolenaar gui_init_font(arg, FALSE); 1891*f9cc9f20SBram Moolenaar #ifndef FONTSET_ALWAYS 1892*f9cc9f20SBram Moolenaar # if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU) 1893*f9cc9f20SBram Moolenaar if (do_menu) 1894*f9cc9f20SBram Moolenaar { 1895*f9cc9f20SBram Moolenaar gui.menu_font = HL_TABLE()[idx].sg_font; 1896*f9cc9f20SBram Moolenaar gui_mch_new_menu_font(); 1897*f9cc9f20SBram Moolenaar } 1898*f9cc9f20SBram Moolenaar # endif 1899*f9cc9f20SBram Moolenaar #endif 1900*f9cc9f20SBram Moolenaar } 1901*f9cc9f20SBram Moolenaar } 1902*f9cc9f20SBram Moolenaar } 1903*f9cc9f20SBram Moolenaar 1904*f9cc9f20SBram Moolenaar #endif // FEAT_GUI 1905*f9cc9f20SBram Moolenaar 1906*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) 1907*f9cc9f20SBram Moolenaar /* 1908*f9cc9f20SBram Moolenaar * Return the handle for a color name. 1909*f9cc9f20SBram Moolenaar * Returns INVALCOLOR when failed. 1910*f9cc9f20SBram Moolenaar */ 1911*f9cc9f20SBram Moolenaar guicolor_T 1912*f9cc9f20SBram Moolenaar color_name2handle(char_u *name) 1913*f9cc9f20SBram Moolenaar { 1914*f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0) 1915*f9cc9f20SBram Moolenaar return INVALCOLOR; 1916*f9cc9f20SBram Moolenaar 1917*f9cc9f20SBram Moolenaar if (STRICMP(name, "fg") == 0 || STRICMP(name, "foreground") == 0) 1918*f9cc9f20SBram Moolenaar { 1919*f9cc9f20SBram Moolenaar #if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) 1920*f9cc9f20SBram Moolenaar if (gui.in_use) 1921*f9cc9f20SBram Moolenaar #endif 1922*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1923*f9cc9f20SBram Moolenaar return gui.norm_pixel; 1924*f9cc9f20SBram Moolenaar #endif 1925*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 1926*f9cc9f20SBram Moolenaar if (cterm_normal_fg_gui_color != INVALCOLOR) 1927*f9cc9f20SBram Moolenaar return cterm_normal_fg_gui_color; 1928*f9cc9f20SBram Moolenaar // Guess that the foreground is black or white. 1929*f9cc9f20SBram Moolenaar return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "black" : "white")); 1930*f9cc9f20SBram Moolenaar #endif 1931*f9cc9f20SBram Moolenaar } 1932*f9cc9f20SBram Moolenaar if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0) 1933*f9cc9f20SBram Moolenaar { 1934*f9cc9f20SBram Moolenaar #if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) 1935*f9cc9f20SBram Moolenaar if (gui.in_use) 1936*f9cc9f20SBram Moolenaar #endif 1937*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1938*f9cc9f20SBram Moolenaar return gui.back_pixel; 1939*f9cc9f20SBram Moolenaar #endif 1940*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 1941*f9cc9f20SBram Moolenaar if (cterm_normal_bg_gui_color != INVALCOLOR) 1942*f9cc9f20SBram Moolenaar return cterm_normal_bg_gui_color; 1943*f9cc9f20SBram Moolenaar // Guess that the background is white or black. 1944*f9cc9f20SBram Moolenaar return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "white" : "black")); 1945*f9cc9f20SBram Moolenaar #endif 1946*f9cc9f20SBram Moolenaar } 1947*f9cc9f20SBram Moolenaar 1948*f9cc9f20SBram Moolenaar return GUI_GET_COLOR(name); 1949*f9cc9f20SBram Moolenaar } 1950*f9cc9f20SBram Moolenaar #endif 1951*f9cc9f20SBram Moolenaar 1952*f9cc9f20SBram Moolenaar /* 1953*f9cc9f20SBram Moolenaar * Table with the specifications for an attribute number. 1954*f9cc9f20SBram Moolenaar * Note that this table is used by ALL buffers. This is required because the 1955*f9cc9f20SBram Moolenaar * GUI can redraw at any time for any buffer. 1956*f9cc9f20SBram Moolenaar */ 1957*f9cc9f20SBram Moolenaar static garray_T term_attr_table = {0, 0, 0, 0, NULL}; 1958*f9cc9f20SBram Moolenaar 1959*f9cc9f20SBram Moolenaar #define TERM_ATTR_ENTRY(idx) ((attrentry_T *)term_attr_table.ga_data)[idx] 1960*f9cc9f20SBram Moolenaar 1961*f9cc9f20SBram Moolenaar static garray_T cterm_attr_table = {0, 0, 0, 0, NULL}; 1962*f9cc9f20SBram Moolenaar 1963*f9cc9f20SBram Moolenaar #define CTERM_ATTR_ENTRY(idx) ((attrentry_T *)cterm_attr_table.ga_data)[idx] 1964*f9cc9f20SBram Moolenaar 1965*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1966*f9cc9f20SBram Moolenaar static garray_T gui_attr_table = {0, 0, 0, 0, NULL}; 1967*f9cc9f20SBram Moolenaar 1968*f9cc9f20SBram Moolenaar #define GUI_ATTR_ENTRY(idx) ((attrentry_T *)gui_attr_table.ga_data)[idx] 1969*f9cc9f20SBram Moolenaar #endif 1970*f9cc9f20SBram Moolenaar 1971*f9cc9f20SBram Moolenaar /* 1972*f9cc9f20SBram Moolenaar * Return the attr number for a set of colors and font. 1973*f9cc9f20SBram Moolenaar * Add a new entry to the term_attr_table, cterm_attr_table or gui_attr_table 1974*f9cc9f20SBram Moolenaar * if the combination is new. 1975*f9cc9f20SBram Moolenaar * Return 0 for error (no more room). 1976*f9cc9f20SBram Moolenaar */ 1977*f9cc9f20SBram Moolenaar static int 1978*f9cc9f20SBram Moolenaar get_attr_entry(garray_T *table, attrentry_T *aep) 1979*f9cc9f20SBram Moolenaar { 1980*f9cc9f20SBram Moolenaar int i; 1981*f9cc9f20SBram Moolenaar attrentry_T *taep; 1982*f9cc9f20SBram Moolenaar static int recursive = FALSE; 1983*f9cc9f20SBram Moolenaar 1984*f9cc9f20SBram Moolenaar /* 1985*f9cc9f20SBram Moolenaar * Init the table, in case it wasn't done yet. 1986*f9cc9f20SBram Moolenaar */ 1987*f9cc9f20SBram Moolenaar table->ga_itemsize = sizeof(attrentry_T); 1988*f9cc9f20SBram Moolenaar table->ga_growsize = 7; 1989*f9cc9f20SBram Moolenaar 1990*f9cc9f20SBram Moolenaar /* 1991*f9cc9f20SBram Moolenaar * Try to find an entry with the same specifications. 1992*f9cc9f20SBram Moolenaar */ 1993*f9cc9f20SBram Moolenaar for (i = 0; i < table->ga_len; ++i) 1994*f9cc9f20SBram Moolenaar { 1995*f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)table->ga_data)[i]); 1996*f9cc9f20SBram Moolenaar if ( aep->ae_attr == taep->ae_attr 1997*f9cc9f20SBram Moolenaar && ( 1998*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1999*f9cc9f20SBram Moolenaar (table == &gui_attr_table 2000*f9cc9f20SBram Moolenaar && (aep->ae_u.gui.fg_color == taep->ae_u.gui.fg_color 2001*f9cc9f20SBram Moolenaar && aep->ae_u.gui.bg_color 2002*f9cc9f20SBram Moolenaar == taep->ae_u.gui.bg_color 2003*f9cc9f20SBram Moolenaar && aep->ae_u.gui.sp_color 2004*f9cc9f20SBram Moolenaar == taep->ae_u.gui.sp_color 2005*f9cc9f20SBram Moolenaar && aep->ae_u.gui.font == taep->ae_u.gui.font 2006*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2007*f9cc9f20SBram Moolenaar && aep->ae_u.gui.fontset == taep->ae_u.gui.fontset 2008*f9cc9f20SBram Moolenaar # endif 2009*f9cc9f20SBram Moolenaar )) 2010*f9cc9f20SBram Moolenaar || 2011*f9cc9f20SBram Moolenaar #endif 2012*f9cc9f20SBram Moolenaar (table == &term_attr_table 2013*f9cc9f20SBram Moolenaar && (aep->ae_u.term.start == NULL) 2014*f9cc9f20SBram Moolenaar == (taep->ae_u.term.start == NULL) 2015*f9cc9f20SBram Moolenaar && (aep->ae_u.term.start == NULL 2016*f9cc9f20SBram Moolenaar || STRCMP(aep->ae_u.term.start, 2017*f9cc9f20SBram Moolenaar taep->ae_u.term.start) == 0) 2018*f9cc9f20SBram Moolenaar && (aep->ae_u.term.stop == NULL) 2019*f9cc9f20SBram Moolenaar == (taep->ae_u.term.stop == NULL) 2020*f9cc9f20SBram Moolenaar && (aep->ae_u.term.stop == NULL 2021*f9cc9f20SBram Moolenaar || STRCMP(aep->ae_u.term.stop, 2022*f9cc9f20SBram Moolenaar taep->ae_u.term.stop) == 0)) 2023*f9cc9f20SBram Moolenaar || (table == &cterm_attr_table 2024*f9cc9f20SBram Moolenaar && aep->ae_u.cterm.fg_color 2025*f9cc9f20SBram Moolenaar == taep->ae_u.cterm.fg_color 2026*f9cc9f20SBram Moolenaar && aep->ae_u.cterm.bg_color 2027*f9cc9f20SBram Moolenaar == taep->ae_u.cterm.bg_color 2028*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2029*f9cc9f20SBram Moolenaar && aep->ae_u.cterm.fg_rgb 2030*f9cc9f20SBram Moolenaar == taep->ae_u.cterm.fg_rgb 2031*f9cc9f20SBram Moolenaar && aep->ae_u.cterm.bg_rgb 2032*f9cc9f20SBram Moolenaar == taep->ae_u.cterm.bg_rgb 2033*f9cc9f20SBram Moolenaar #endif 2034*f9cc9f20SBram Moolenaar ))) 2035*f9cc9f20SBram Moolenaar 2036*f9cc9f20SBram Moolenaar return i + ATTR_OFF; 2037*f9cc9f20SBram Moolenaar } 2038*f9cc9f20SBram Moolenaar 2039*f9cc9f20SBram Moolenaar if (table->ga_len + ATTR_OFF > MAX_TYPENR) 2040*f9cc9f20SBram Moolenaar { 2041*f9cc9f20SBram Moolenaar /* 2042*f9cc9f20SBram Moolenaar * Running out of attribute entries! remove all attributes, and 2043*f9cc9f20SBram Moolenaar * compute new ones for all groups. 2044*f9cc9f20SBram Moolenaar * When called recursively, we are really out of numbers. 2045*f9cc9f20SBram Moolenaar */ 2046*f9cc9f20SBram Moolenaar if (recursive) 2047*f9cc9f20SBram Moolenaar { 2048*f9cc9f20SBram Moolenaar emsg(_("E424: Too many different highlighting attributes in use")); 2049*f9cc9f20SBram Moolenaar return 0; 2050*f9cc9f20SBram Moolenaar } 2051*f9cc9f20SBram Moolenaar recursive = TRUE; 2052*f9cc9f20SBram Moolenaar 2053*f9cc9f20SBram Moolenaar clear_hl_tables(); 2054*f9cc9f20SBram Moolenaar 2055*f9cc9f20SBram Moolenaar must_redraw = CLEAR; 2056*f9cc9f20SBram Moolenaar 2057*f9cc9f20SBram Moolenaar for (i = 0; i < highlight_ga.ga_len; ++i) 2058*f9cc9f20SBram Moolenaar set_hl_attr(i); 2059*f9cc9f20SBram Moolenaar 2060*f9cc9f20SBram Moolenaar recursive = FALSE; 2061*f9cc9f20SBram Moolenaar } 2062*f9cc9f20SBram Moolenaar 2063*f9cc9f20SBram Moolenaar /* 2064*f9cc9f20SBram Moolenaar * This is a new combination of colors and font, add an entry. 2065*f9cc9f20SBram Moolenaar */ 2066*f9cc9f20SBram Moolenaar if (ga_grow(table, 1) == FAIL) 2067*f9cc9f20SBram Moolenaar return 0; 2068*f9cc9f20SBram Moolenaar 2069*f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)table->ga_data)[table->ga_len]); 2070*f9cc9f20SBram Moolenaar vim_memset(taep, 0, sizeof(attrentry_T)); 2071*f9cc9f20SBram Moolenaar taep->ae_attr = aep->ae_attr; 2072*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2073*f9cc9f20SBram Moolenaar if (table == &gui_attr_table) 2074*f9cc9f20SBram Moolenaar { 2075*f9cc9f20SBram Moolenaar taep->ae_u.gui.fg_color = aep->ae_u.gui.fg_color; 2076*f9cc9f20SBram Moolenaar taep->ae_u.gui.bg_color = aep->ae_u.gui.bg_color; 2077*f9cc9f20SBram Moolenaar taep->ae_u.gui.sp_color = aep->ae_u.gui.sp_color; 2078*f9cc9f20SBram Moolenaar taep->ae_u.gui.font = aep->ae_u.gui.font; 2079*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2080*f9cc9f20SBram Moolenaar taep->ae_u.gui.fontset = aep->ae_u.gui.fontset; 2081*f9cc9f20SBram Moolenaar # endif 2082*f9cc9f20SBram Moolenaar } 2083*f9cc9f20SBram Moolenaar #endif 2084*f9cc9f20SBram Moolenaar if (table == &term_attr_table) 2085*f9cc9f20SBram Moolenaar { 2086*f9cc9f20SBram Moolenaar if (aep->ae_u.term.start == NULL) 2087*f9cc9f20SBram Moolenaar taep->ae_u.term.start = NULL; 2088*f9cc9f20SBram Moolenaar else 2089*f9cc9f20SBram Moolenaar taep->ae_u.term.start = vim_strsave(aep->ae_u.term.start); 2090*f9cc9f20SBram Moolenaar if (aep->ae_u.term.stop == NULL) 2091*f9cc9f20SBram Moolenaar taep->ae_u.term.stop = NULL; 2092*f9cc9f20SBram Moolenaar else 2093*f9cc9f20SBram Moolenaar taep->ae_u.term.stop = vim_strsave(aep->ae_u.term.stop); 2094*f9cc9f20SBram Moolenaar } 2095*f9cc9f20SBram Moolenaar else if (table == &cterm_attr_table) 2096*f9cc9f20SBram Moolenaar { 2097*f9cc9f20SBram Moolenaar taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color; 2098*f9cc9f20SBram Moolenaar taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color; 2099*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2100*f9cc9f20SBram Moolenaar taep->ae_u.cterm.fg_rgb = aep->ae_u.cterm.fg_rgb; 2101*f9cc9f20SBram Moolenaar taep->ae_u.cterm.bg_rgb = aep->ae_u.cterm.bg_rgb; 2102*f9cc9f20SBram Moolenaar #endif 2103*f9cc9f20SBram Moolenaar } 2104*f9cc9f20SBram Moolenaar ++table->ga_len; 2105*f9cc9f20SBram Moolenaar return (table->ga_len - 1 + ATTR_OFF); 2106*f9cc9f20SBram Moolenaar } 2107*f9cc9f20SBram Moolenaar 2108*f9cc9f20SBram Moolenaar #if defined(FEAT_TERMINAL) || defined(PROTO) 2109*f9cc9f20SBram Moolenaar /* 2110*f9cc9f20SBram Moolenaar * Get an attribute index for a cterm entry. 2111*f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed. 2112*f9cc9f20SBram Moolenaar */ 2113*f9cc9f20SBram Moolenaar int 2114*f9cc9f20SBram Moolenaar get_cterm_attr_idx(int attr, int fg, int bg) 2115*f9cc9f20SBram Moolenaar { 2116*f9cc9f20SBram Moolenaar attrentry_T at_en; 2117*f9cc9f20SBram Moolenaar 2118*f9cc9f20SBram Moolenaar vim_memset(&at_en, 0, sizeof(attrentry_T)); 2119*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2120*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = INVALCOLOR; 2121*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = INVALCOLOR; 2122*f9cc9f20SBram Moolenaar #endif 2123*f9cc9f20SBram Moolenaar at_en.ae_attr = attr; 2124*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_color = fg; 2125*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_color = bg; 2126*f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &at_en); 2127*f9cc9f20SBram Moolenaar } 2128*f9cc9f20SBram Moolenaar #endif 2129*f9cc9f20SBram Moolenaar 2130*f9cc9f20SBram Moolenaar #if (defined(FEAT_TERMINAL) && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) 2131*f9cc9f20SBram Moolenaar /* 2132*f9cc9f20SBram Moolenaar * Get an attribute index for a 'termguicolors' entry. 2133*f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed. 2134*f9cc9f20SBram Moolenaar */ 2135*f9cc9f20SBram Moolenaar int 2136*f9cc9f20SBram Moolenaar get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg) 2137*f9cc9f20SBram Moolenaar { 2138*f9cc9f20SBram Moolenaar attrentry_T at_en; 2139*f9cc9f20SBram Moolenaar 2140*f9cc9f20SBram Moolenaar vim_memset(&at_en, 0, sizeof(attrentry_T)); 2141*f9cc9f20SBram Moolenaar at_en.ae_attr = attr; 2142*f9cc9f20SBram Moolenaar if (fg == INVALCOLOR && bg == INVALCOLOR) 2143*f9cc9f20SBram Moolenaar { 2144*f9cc9f20SBram Moolenaar // If both GUI colors are not set fall back to the cterm colors. Helps 2145*f9cc9f20SBram Moolenaar // if the GUI only has an attribute, such as undercurl. 2146*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = CTERMCOLOR; 2147*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = CTERMCOLOR; 2148*f9cc9f20SBram Moolenaar } 2149*f9cc9f20SBram Moolenaar else 2150*f9cc9f20SBram Moolenaar { 2151*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = fg; 2152*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = bg; 2153*f9cc9f20SBram Moolenaar } 2154*f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &at_en); 2155*f9cc9f20SBram Moolenaar } 2156*f9cc9f20SBram Moolenaar #endif 2157*f9cc9f20SBram Moolenaar 2158*f9cc9f20SBram Moolenaar #if (defined(FEAT_TERMINAL) && defined(FEAT_GUI)) || defined(PROTO) 2159*f9cc9f20SBram Moolenaar /* 2160*f9cc9f20SBram Moolenaar * Get an attribute index for a cterm entry. 2161*f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed. 2162*f9cc9f20SBram Moolenaar */ 2163*f9cc9f20SBram Moolenaar int 2164*f9cc9f20SBram Moolenaar get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg) 2165*f9cc9f20SBram Moolenaar { 2166*f9cc9f20SBram Moolenaar attrentry_T at_en; 2167*f9cc9f20SBram Moolenaar 2168*f9cc9f20SBram Moolenaar vim_memset(&at_en, 0, sizeof(attrentry_T)); 2169*f9cc9f20SBram Moolenaar at_en.ae_attr = attr; 2170*f9cc9f20SBram Moolenaar at_en.ae_u.gui.fg_color = fg; 2171*f9cc9f20SBram Moolenaar at_en.ae_u.gui.bg_color = bg; 2172*f9cc9f20SBram Moolenaar return get_attr_entry(&gui_attr_table, &at_en); 2173*f9cc9f20SBram Moolenaar } 2174*f9cc9f20SBram Moolenaar #endif 2175*f9cc9f20SBram Moolenaar 2176*f9cc9f20SBram Moolenaar /* 2177*f9cc9f20SBram Moolenaar * Clear all highlight tables. 2178*f9cc9f20SBram Moolenaar */ 2179*f9cc9f20SBram Moolenaar void 2180*f9cc9f20SBram Moolenaar clear_hl_tables(void) 2181*f9cc9f20SBram Moolenaar { 2182*f9cc9f20SBram Moolenaar int i; 2183*f9cc9f20SBram Moolenaar attrentry_T *taep; 2184*f9cc9f20SBram Moolenaar 2185*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2186*f9cc9f20SBram Moolenaar ga_clear(&gui_attr_table); 2187*f9cc9f20SBram Moolenaar #endif 2188*f9cc9f20SBram Moolenaar for (i = 0; i < term_attr_table.ga_len; ++i) 2189*f9cc9f20SBram Moolenaar { 2190*f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)term_attr_table.ga_data)[i]); 2191*f9cc9f20SBram Moolenaar vim_free(taep->ae_u.term.start); 2192*f9cc9f20SBram Moolenaar vim_free(taep->ae_u.term.stop); 2193*f9cc9f20SBram Moolenaar } 2194*f9cc9f20SBram Moolenaar ga_clear(&term_attr_table); 2195*f9cc9f20SBram Moolenaar ga_clear(&cterm_attr_table); 2196*f9cc9f20SBram Moolenaar } 2197*f9cc9f20SBram Moolenaar 2198*f9cc9f20SBram Moolenaar /* 2199*f9cc9f20SBram Moolenaar * Combine special attributes (e.g., for spelling) with other attributes 2200*f9cc9f20SBram Moolenaar * (e.g., for syntax highlighting). 2201*f9cc9f20SBram Moolenaar * "prim_attr" overrules "char_attr". 2202*f9cc9f20SBram Moolenaar * This creates a new group when required. 2203*f9cc9f20SBram Moolenaar * Since we expect there to be few spelling mistakes we don't cache the 2204*f9cc9f20SBram Moolenaar * result. 2205*f9cc9f20SBram Moolenaar * Return the resulting attributes. 2206*f9cc9f20SBram Moolenaar */ 2207*f9cc9f20SBram Moolenaar int 2208*f9cc9f20SBram Moolenaar hl_combine_attr(int char_attr, int prim_attr) 2209*f9cc9f20SBram Moolenaar { 2210*f9cc9f20SBram Moolenaar attrentry_T *char_aep = NULL; 2211*f9cc9f20SBram Moolenaar attrentry_T *spell_aep; 2212*f9cc9f20SBram Moolenaar attrentry_T new_en; 2213*f9cc9f20SBram Moolenaar 2214*f9cc9f20SBram Moolenaar if (char_attr == 0) 2215*f9cc9f20SBram Moolenaar return prim_attr; 2216*f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL && prim_attr <= HL_ALL) 2217*f9cc9f20SBram Moolenaar return ATTR_COMBINE(char_attr, prim_attr); 2218*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2219*f9cc9f20SBram Moolenaar if (gui.in_use) 2220*f9cc9f20SBram Moolenaar { 2221*f9cc9f20SBram Moolenaar if (char_attr > HL_ALL) 2222*f9cc9f20SBram Moolenaar char_aep = syn_gui_attr2entry(char_attr); 2223*f9cc9f20SBram Moolenaar if (char_aep != NULL) 2224*f9cc9f20SBram Moolenaar new_en = *char_aep; 2225*f9cc9f20SBram Moolenaar else 2226*f9cc9f20SBram Moolenaar { 2227*f9cc9f20SBram Moolenaar vim_memset(&new_en, 0, sizeof(new_en)); 2228*f9cc9f20SBram Moolenaar new_en.ae_u.gui.fg_color = INVALCOLOR; 2229*f9cc9f20SBram Moolenaar new_en.ae_u.gui.bg_color = INVALCOLOR; 2230*f9cc9f20SBram Moolenaar new_en.ae_u.gui.sp_color = INVALCOLOR; 2231*f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL) 2232*f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr; 2233*f9cc9f20SBram Moolenaar } 2234*f9cc9f20SBram Moolenaar 2235*f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL) 2236*f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); 2237*f9cc9f20SBram Moolenaar else 2238*f9cc9f20SBram Moolenaar { 2239*f9cc9f20SBram Moolenaar spell_aep = syn_gui_attr2entry(prim_attr); 2240*f9cc9f20SBram Moolenaar if (spell_aep != NULL) 2241*f9cc9f20SBram Moolenaar { 2242*f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, 2243*f9cc9f20SBram Moolenaar spell_aep->ae_attr); 2244*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.fg_color != INVALCOLOR) 2245*f9cc9f20SBram Moolenaar new_en.ae_u.gui.fg_color = spell_aep->ae_u.gui.fg_color; 2246*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.bg_color != INVALCOLOR) 2247*f9cc9f20SBram Moolenaar new_en.ae_u.gui.bg_color = spell_aep->ae_u.gui.bg_color; 2248*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.sp_color != INVALCOLOR) 2249*f9cc9f20SBram Moolenaar new_en.ae_u.gui.sp_color = spell_aep->ae_u.gui.sp_color; 2250*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.font != NOFONT) 2251*f9cc9f20SBram Moolenaar new_en.ae_u.gui.font = spell_aep->ae_u.gui.font; 2252*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2253*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.fontset != NOFONTSET) 2254*f9cc9f20SBram Moolenaar new_en.ae_u.gui.fontset = spell_aep->ae_u.gui.fontset; 2255*f9cc9f20SBram Moolenaar # endif 2256*f9cc9f20SBram Moolenaar } 2257*f9cc9f20SBram Moolenaar } 2258*f9cc9f20SBram Moolenaar return get_attr_entry(&gui_attr_table, &new_en); 2259*f9cc9f20SBram Moolenaar } 2260*f9cc9f20SBram Moolenaar #endif 2261*f9cc9f20SBram Moolenaar 2262*f9cc9f20SBram Moolenaar if (IS_CTERM) 2263*f9cc9f20SBram Moolenaar { 2264*f9cc9f20SBram Moolenaar if (char_attr > HL_ALL) 2265*f9cc9f20SBram Moolenaar char_aep = syn_cterm_attr2entry(char_attr); 2266*f9cc9f20SBram Moolenaar if (char_aep != NULL) 2267*f9cc9f20SBram Moolenaar new_en = *char_aep; 2268*f9cc9f20SBram Moolenaar else 2269*f9cc9f20SBram Moolenaar { 2270*f9cc9f20SBram Moolenaar vim_memset(&new_en, 0, sizeof(new_en)); 2271*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2272*f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = INVALCOLOR; 2273*f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = INVALCOLOR; 2274*f9cc9f20SBram Moolenaar #endif 2275*f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL) 2276*f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr; 2277*f9cc9f20SBram Moolenaar } 2278*f9cc9f20SBram Moolenaar 2279*f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL) 2280*f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); 2281*f9cc9f20SBram Moolenaar else 2282*f9cc9f20SBram Moolenaar { 2283*f9cc9f20SBram Moolenaar spell_aep = syn_cterm_attr2entry(prim_attr); 2284*f9cc9f20SBram Moolenaar if (spell_aep != NULL) 2285*f9cc9f20SBram Moolenaar { 2286*f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, 2287*f9cc9f20SBram Moolenaar spell_aep->ae_attr); 2288*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_color > 0) 2289*f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color; 2290*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_color > 0) 2291*f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color; 2292*f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2293*f9cc9f20SBram Moolenaar // If both fg and bg are not set fall back to cterm colors. 2294*f9cc9f20SBram Moolenaar // Helps for SpellBad which uses undercurl in the GUI. 2295*f9cc9f20SBram Moolenaar if (COLOR_INVALID(spell_aep->ae_u.cterm.fg_rgb) 2296*f9cc9f20SBram Moolenaar && COLOR_INVALID(spell_aep->ae_u.cterm.bg_rgb)) 2297*f9cc9f20SBram Moolenaar { 2298*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_color > 0) 2299*f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = CTERMCOLOR; 2300*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_color > 0) 2301*f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = CTERMCOLOR; 2302*f9cc9f20SBram Moolenaar } 2303*f9cc9f20SBram Moolenaar else 2304*f9cc9f20SBram Moolenaar { 2305*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_rgb != INVALCOLOR) 2306*f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = spell_aep->ae_u.cterm.fg_rgb; 2307*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_rgb != INVALCOLOR) 2308*f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = spell_aep->ae_u.cterm.bg_rgb; 2309*f9cc9f20SBram Moolenaar } 2310*f9cc9f20SBram Moolenaar #endif 2311*f9cc9f20SBram Moolenaar } 2312*f9cc9f20SBram Moolenaar } 2313*f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &new_en); 2314*f9cc9f20SBram Moolenaar } 2315*f9cc9f20SBram Moolenaar 2316*f9cc9f20SBram Moolenaar if (char_attr > HL_ALL) 2317*f9cc9f20SBram Moolenaar char_aep = syn_term_attr2entry(char_attr); 2318*f9cc9f20SBram Moolenaar if (char_aep != NULL) 2319*f9cc9f20SBram Moolenaar new_en = *char_aep; 2320*f9cc9f20SBram Moolenaar else 2321*f9cc9f20SBram Moolenaar { 2322*f9cc9f20SBram Moolenaar vim_memset(&new_en, 0, sizeof(new_en)); 2323*f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL) 2324*f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr; 2325*f9cc9f20SBram Moolenaar } 2326*f9cc9f20SBram Moolenaar 2327*f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL) 2328*f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); 2329*f9cc9f20SBram Moolenaar else 2330*f9cc9f20SBram Moolenaar { 2331*f9cc9f20SBram Moolenaar spell_aep = syn_term_attr2entry(prim_attr); 2332*f9cc9f20SBram Moolenaar if (spell_aep != NULL) 2333*f9cc9f20SBram Moolenaar { 2334*f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, spell_aep->ae_attr); 2335*f9cc9f20SBram Moolenaar if (spell_aep->ae_u.term.start != NULL) 2336*f9cc9f20SBram Moolenaar { 2337*f9cc9f20SBram Moolenaar new_en.ae_u.term.start = spell_aep->ae_u.term.start; 2338*f9cc9f20SBram Moolenaar new_en.ae_u.term.stop = spell_aep->ae_u.term.stop; 2339*f9cc9f20SBram Moolenaar } 2340*f9cc9f20SBram Moolenaar } 2341*f9cc9f20SBram Moolenaar } 2342*f9cc9f20SBram Moolenaar return get_attr_entry(&term_attr_table, &new_en); 2343*f9cc9f20SBram Moolenaar } 2344*f9cc9f20SBram Moolenaar 2345*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2346*f9cc9f20SBram Moolenaar attrentry_T * 2347*f9cc9f20SBram Moolenaar syn_gui_attr2entry(int attr) 2348*f9cc9f20SBram Moolenaar { 2349*f9cc9f20SBram Moolenaar attr -= ATTR_OFF; 2350*f9cc9f20SBram Moolenaar if (attr >= gui_attr_table.ga_len) // did ":syntax clear" 2351*f9cc9f20SBram Moolenaar return NULL; 2352*f9cc9f20SBram Moolenaar return &(GUI_ATTR_ENTRY(attr)); 2353*f9cc9f20SBram Moolenaar } 2354*f9cc9f20SBram Moolenaar #endif 2355*f9cc9f20SBram Moolenaar 2356*f9cc9f20SBram Moolenaar /* 2357*f9cc9f20SBram Moolenaar * Get the highlight attributes (HL_BOLD etc.) from an attribute nr. 2358*f9cc9f20SBram Moolenaar * Only to be used when "attr" > HL_ALL. 2359*f9cc9f20SBram Moolenaar */ 2360*f9cc9f20SBram Moolenaar int 2361*f9cc9f20SBram Moolenaar syn_attr2attr(int attr) 2362*f9cc9f20SBram Moolenaar { 2363*f9cc9f20SBram Moolenaar attrentry_T *aep; 2364*f9cc9f20SBram Moolenaar 2365*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2366*f9cc9f20SBram Moolenaar if (gui.in_use) 2367*f9cc9f20SBram Moolenaar aep = syn_gui_attr2entry(attr); 2368*f9cc9f20SBram Moolenaar else 2369*f9cc9f20SBram Moolenaar #endif 2370*f9cc9f20SBram Moolenaar if (IS_CTERM) 2371*f9cc9f20SBram Moolenaar aep = syn_cterm_attr2entry(attr); 2372*f9cc9f20SBram Moolenaar else 2373*f9cc9f20SBram Moolenaar aep = syn_term_attr2entry(attr); 2374*f9cc9f20SBram Moolenaar 2375*f9cc9f20SBram Moolenaar if (aep == NULL) // highlighting not set 2376*f9cc9f20SBram Moolenaar return 0; 2377*f9cc9f20SBram Moolenaar return aep->ae_attr; 2378*f9cc9f20SBram Moolenaar } 2379*f9cc9f20SBram Moolenaar 2380*f9cc9f20SBram Moolenaar 2381*f9cc9f20SBram Moolenaar attrentry_T * 2382*f9cc9f20SBram Moolenaar syn_term_attr2entry(int attr) 2383*f9cc9f20SBram Moolenaar { 2384*f9cc9f20SBram Moolenaar attr -= ATTR_OFF; 2385*f9cc9f20SBram Moolenaar if (attr >= term_attr_table.ga_len) // did ":syntax clear" 2386*f9cc9f20SBram Moolenaar return NULL; 2387*f9cc9f20SBram Moolenaar return &(TERM_ATTR_ENTRY(attr)); 2388*f9cc9f20SBram Moolenaar } 2389*f9cc9f20SBram Moolenaar 2390*f9cc9f20SBram Moolenaar attrentry_T * 2391*f9cc9f20SBram Moolenaar syn_cterm_attr2entry(int attr) 2392*f9cc9f20SBram Moolenaar { 2393*f9cc9f20SBram Moolenaar attr -= ATTR_OFF; 2394*f9cc9f20SBram Moolenaar if (attr >= cterm_attr_table.ga_len) // did ":syntax clear" 2395*f9cc9f20SBram Moolenaar return NULL; 2396*f9cc9f20SBram Moolenaar return &(CTERM_ATTR_ENTRY(attr)); 2397*f9cc9f20SBram Moolenaar } 2398*f9cc9f20SBram Moolenaar 2399*f9cc9f20SBram Moolenaar #define LIST_ATTR 1 2400*f9cc9f20SBram Moolenaar #define LIST_STRING 2 2401*f9cc9f20SBram Moolenaar #define LIST_INT 3 2402*f9cc9f20SBram Moolenaar 2403*f9cc9f20SBram Moolenaar static void 2404*f9cc9f20SBram Moolenaar highlight_list_one(int id) 2405*f9cc9f20SBram Moolenaar { 2406*f9cc9f20SBram Moolenaar hl_group_T *sgp; 2407*f9cc9f20SBram Moolenaar int didh = FALSE; 2408*f9cc9f20SBram Moolenaar 2409*f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[id - 1]; // index is ID minus one 2410*f9cc9f20SBram Moolenaar 2411*f9cc9f20SBram Moolenaar if (message_filtered(sgp->sg_name)) 2412*f9cc9f20SBram Moolenaar return; 2413*f9cc9f20SBram Moolenaar 2414*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR, 2415*f9cc9f20SBram Moolenaar sgp->sg_term, NULL, "term"); 2416*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2417*f9cc9f20SBram Moolenaar 0, sgp->sg_start, "start"); 2418*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2419*f9cc9f20SBram Moolenaar 0, sgp->sg_stop, "stop"); 2420*f9cc9f20SBram Moolenaar 2421*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR, 2422*f9cc9f20SBram Moolenaar sgp->sg_cterm, NULL, "cterm"); 2423*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_INT, 2424*f9cc9f20SBram Moolenaar sgp->sg_cterm_fg, NULL, "ctermfg"); 2425*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_INT, 2426*f9cc9f20SBram Moolenaar sgp->sg_cterm_bg, NULL, "ctermbg"); 2427*f9cc9f20SBram Moolenaar 2428*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 2429*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR, 2430*f9cc9f20SBram Moolenaar sgp->sg_gui, NULL, "gui"); 2431*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2432*f9cc9f20SBram Moolenaar 0, sgp->sg_gui_fg_name, "guifg"); 2433*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2434*f9cc9f20SBram Moolenaar 0, sgp->sg_gui_bg_name, "guibg"); 2435*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2436*f9cc9f20SBram Moolenaar 0, sgp->sg_gui_sp_name, "guisp"); 2437*f9cc9f20SBram Moolenaar #endif 2438*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2439*f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2440*f9cc9f20SBram Moolenaar 0, sgp->sg_font_name, "font"); 2441*f9cc9f20SBram Moolenaar #endif 2442*f9cc9f20SBram Moolenaar 2443*f9cc9f20SBram Moolenaar if (sgp->sg_link && !got_int) 2444*f9cc9f20SBram Moolenaar { 2445*f9cc9f20SBram Moolenaar (void)syn_list_header(didh, 9999, id); 2446*f9cc9f20SBram Moolenaar didh = TRUE; 2447*f9cc9f20SBram Moolenaar msg_puts_attr("links to", HL_ATTR(HLF_D)); 2448*f9cc9f20SBram Moolenaar msg_putchar(' '); 2449*f9cc9f20SBram Moolenaar msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name); 2450*f9cc9f20SBram Moolenaar } 2451*f9cc9f20SBram Moolenaar 2452*f9cc9f20SBram Moolenaar if (!didh) 2453*f9cc9f20SBram Moolenaar highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", ""); 2454*f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 2455*f9cc9f20SBram Moolenaar if (p_verbose > 0) 2456*f9cc9f20SBram Moolenaar last_set_msg(sgp->sg_script_ctx); 2457*f9cc9f20SBram Moolenaar #endif 2458*f9cc9f20SBram Moolenaar } 2459*f9cc9f20SBram Moolenaar 2460*f9cc9f20SBram Moolenaar static int 2461*f9cc9f20SBram Moolenaar highlight_list_arg( 2462*f9cc9f20SBram Moolenaar int id, 2463*f9cc9f20SBram Moolenaar int didh, 2464*f9cc9f20SBram Moolenaar int type, 2465*f9cc9f20SBram Moolenaar int iarg, 2466*f9cc9f20SBram Moolenaar char_u *sarg, 2467*f9cc9f20SBram Moolenaar char *name) 2468*f9cc9f20SBram Moolenaar { 2469*f9cc9f20SBram Moolenaar char_u buf[100]; 2470*f9cc9f20SBram Moolenaar char_u *ts; 2471*f9cc9f20SBram Moolenaar int i; 2472*f9cc9f20SBram Moolenaar 2473*f9cc9f20SBram Moolenaar if (got_int) 2474*f9cc9f20SBram Moolenaar return FALSE; 2475*f9cc9f20SBram Moolenaar if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0)) 2476*f9cc9f20SBram Moolenaar { 2477*f9cc9f20SBram Moolenaar ts = buf; 2478*f9cc9f20SBram Moolenaar if (type == LIST_INT) 2479*f9cc9f20SBram Moolenaar sprintf((char *)buf, "%d", iarg - 1); 2480*f9cc9f20SBram Moolenaar else if (type == LIST_STRING) 2481*f9cc9f20SBram Moolenaar ts = sarg; 2482*f9cc9f20SBram Moolenaar else // type == LIST_ATTR 2483*f9cc9f20SBram Moolenaar { 2484*f9cc9f20SBram Moolenaar buf[0] = NUL; 2485*f9cc9f20SBram Moolenaar for (i = 0; hl_attr_table[i] != 0; ++i) 2486*f9cc9f20SBram Moolenaar { 2487*f9cc9f20SBram Moolenaar if (iarg & hl_attr_table[i]) 2488*f9cc9f20SBram Moolenaar { 2489*f9cc9f20SBram Moolenaar if (buf[0] != NUL) 2490*f9cc9f20SBram Moolenaar vim_strcat(buf, (char_u *)",", 100); 2491*f9cc9f20SBram Moolenaar vim_strcat(buf, (char_u *)hl_name_table[i], 100); 2492*f9cc9f20SBram Moolenaar iarg &= ~hl_attr_table[i]; // don't want "inverse" 2493*f9cc9f20SBram Moolenaar } 2494*f9cc9f20SBram Moolenaar } 2495*f9cc9f20SBram Moolenaar } 2496*f9cc9f20SBram Moolenaar 2497*f9cc9f20SBram Moolenaar (void)syn_list_header(didh, 2498*f9cc9f20SBram Moolenaar (int)(vim_strsize(ts) + STRLEN(name) + 1), id); 2499*f9cc9f20SBram Moolenaar didh = TRUE; 2500*f9cc9f20SBram Moolenaar if (!got_int) 2501*f9cc9f20SBram Moolenaar { 2502*f9cc9f20SBram Moolenaar if (*name != NUL) 2503*f9cc9f20SBram Moolenaar { 2504*f9cc9f20SBram Moolenaar msg_puts_attr(name, HL_ATTR(HLF_D)); 2505*f9cc9f20SBram Moolenaar msg_puts_attr("=", HL_ATTR(HLF_D)); 2506*f9cc9f20SBram Moolenaar } 2507*f9cc9f20SBram Moolenaar msg_outtrans(ts); 2508*f9cc9f20SBram Moolenaar } 2509*f9cc9f20SBram Moolenaar } 2510*f9cc9f20SBram Moolenaar return didh; 2511*f9cc9f20SBram Moolenaar } 2512*f9cc9f20SBram Moolenaar 2513*f9cc9f20SBram Moolenaar #if (((defined(FEAT_EVAL) || defined(FEAT_PRINTER))) && defined(FEAT_SYN_HL)) || defined(PROTO) 2514*f9cc9f20SBram Moolenaar /* 2515*f9cc9f20SBram Moolenaar * Return "1" if highlight group "id" has attribute "flag". 2516*f9cc9f20SBram Moolenaar * Return NULL otherwise. 2517*f9cc9f20SBram Moolenaar */ 2518*f9cc9f20SBram Moolenaar char_u * 2519*f9cc9f20SBram Moolenaar highlight_has_attr( 2520*f9cc9f20SBram Moolenaar int id, 2521*f9cc9f20SBram Moolenaar int flag, 2522*f9cc9f20SBram Moolenaar int modec) // 'g' for GUI, 'c' for cterm, 't' for term 2523*f9cc9f20SBram Moolenaar { 2524*f9cc9f20SBram Moolenaar int attr; 2525*f9cc9f20SBram Moolenaar 2526*f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len) 2527*f9cc9f20SBram Moolenaar return NULL; 2528*f9cc9f20SBram Moolenaar 2529*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 2530*f9cc9f20SBram Moolenaar if (modec == 'g') 2531*f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_gui; 2532*f9cc9f20SBram Moolenaar else 2533*f9cc9f20SBram Moolenaar #endif 2534*f9cc9f20SBram Moolenaar if (modec == 'c') 2535*f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_cterm; 2536*f9cc9f20SBram Moolenaar else 2537*f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_term; 2538*f9cc9f20SBram Moolenaar 2539*f9cc9f20SBram Moolenaar if (attr & flag) 2540*f9cc9f20SBram Moolenaar return (char_u *)"1"; 2541*f9cc9f20SBram Moolenaar return NULL; 2542*f9cc9f20SBram Moolenaar } 2543*f9cc9f20SBram Moolenaar #endif 2544*f9cc9f20SBram Moolenaar 2545*f9cc9f20SBram Moolenaar #if (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) || defined(PROTO) 2546*f9cc9f20SBram Moolenaar /* 2547*f9cc9f20SBram Moolenaar * Return color name of highlight group "id". 2548*f9cc9f20SBram Moolenaar */ 2549*f9cc9f20SBram Moolenaar char_u * 2550*f9cc9f20SBram Moolenaar highlight_color( 2551*f9cc9f20SBram Moolenaar int id, 2552*f9cc9f20SBram Moolenaar char_u *what, // "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" 2553*f9cc9f20SBram Moolenaar int modec) // 'g' for GUI, 'c' for cterm, 't' for term 2554*f9cc9f20SBram Moolenaar { 2555*f9cc9f20SBram Moolenaar static char_u name[20]; 2556*f9cc9f20SBram Moolenaar int n; 2557*f9cc9f20SBram Moolenaar int fg = FALSE; 2558*f9cc9f20SBram Moolenaar int sp = FALSE; 2559*f9cc9f20SBram Moolenaar int font = FALSE; 2560*f9cc9f20SBram Moolenaar 2561*f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len) 2562*f9cc9f20SBram Moolenaar return NULL; 2563*f9cc9f20SBram Moolenaar 2564*f9cc9f20SBram Moolenaar if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g') 2565*f9cc9f20SBram Moolenaar fg = TRUE; 2566*f9cc9f20SBram Moolenaar else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o' 2567*f9cc9f20SBram Moolenaar && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') 2568*f9cc9f20SBram Moolenaar font = TRUE; 2569*f9cc9f20SBram Moolenaar else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p') 2570*f9cc9f20SBram Moolenaar sp = TRUE; 2571*f9cc9f20SBram Moolenaar else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g')) 2572*f9cc9f20SBram Moolenaar return NULL; 2573*f9cc9f20SBram Moolenaar if (modec == 'g') 2574*f9cc9f20SBram Moolenaar { 2575*f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 2576*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 2577*f9cc9f20SBram Moolenaar // return font name 2578*f9cc9f20SBram Moolenaar if (font) 2579*f9cc9f20SBram Moolenaar return HL_TABLE()[id - 1].sg_font_name; 2580*f9cc9f20SBram Moolenaar # endif 2581*f9cc9f20SBram Moolenaar 2582*f9cc9f20SBram Moolenaar // return #RRGGBB form (only possible when GUI is running) 2583*f9cc9f20SBram Moolenaar if ((USE_24BIT) && what[2] == '#') 2584*f9cc9f20SBram Moolenaar { 2585*f9cc9f20SBram Moolenaar guicolor_T color; 2586*f9cc9f20SBram Moolenaar long_u rgb; 2587*f9cc9f20SBram Moolenaar static char_u buf[10]; 2588*f9cc9f20SBram Moolenaar 2589*f9cc9f20SBram Moolenaar if (fg) 2590*f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_fg; 2591*f9cc9f20SBram Moolenaar else if (sp) 2592*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 2593*f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_sp; 2594*f9cc9f20SBram Moolenaar # else 2595*f9cc9f20SBram Moolenaar color = INVALCOLOR; 2596*f9cc9f20SBram Moolenaar # endif 2597*f9cc9f20SBram Moolenaar else 2598*f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_bg; 2599*f9cc9f20SBram Moolenaar if (color == INVALCOLOR) 2600*f9cc9f20SBram Moolenaar return NULL; 2601*f9cc9f20SBram Moolenaar rgb = (long_u)GUI_MCH_GET_RGB(color); 2602*f9cc9f20SBram Moolenaar sprintf((char *)buf, "#%02x%02x%02x", 2603*f9cc9f20SBram Moolenaar (unsigned)(rgb >> 16), 2604*f9cc9f20SBram Moolenaar (unsigned)(rgb >> 8) & 255, 2605*f9cc9f20SBram Moolenaar (unsigned)rgb & 255); 2606*f9cc9f20SBram Moolenaar return buf; 2607*f9cc9f20SBram Moolenaar } 2608*f9cc9f20SBram Moolenaar # endif 2609*f9cc9f20SBram Moolenaar if (fg) 2610*f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_fg_name); 2611*f9cc9f20SBram Moolenaar if (sp) 2612*f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_sp_name); 2613*f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_bg_name); 2614*f9cc9f20SBram Moolenaar } 2615*f9cc9f20SBram Moolenaar if (font || sp) 2616*f9cc9f20SBram Moolenaar return NULL; 2617*f9cc9f20SBram Moolenaar if (modec == 'c') 2618*f9cc9f20SBram Moolenaar { 2619*f9cc9f20SBram Moolenaar if (fg) 2620*f9cc9f20SBram Moolenaar n = HL_TABLE()[id - 1].sg_cterm_fg - 1; 2621*f9cc9f20SBram Moolenaar else 2622*f9cc9f20SBram Moolenaar n = HL_TABLE()[id - 1].sg_cterm_bg - 1; 2623*f9cc9f20SBram Moolenaar if (n < 0) 2624*f9cc9f20SBram Moolenaar return NULL; 2625*f9cc9f20SBram Moolenaar sprintf((char *)name, "%d", n); 2626*f9cc9f20SBram Moolenaar return name; 2627*f9cc9f20SBram Moolenaar } 2628*f9cc9f20SBram Moolenaar // term doesn't have color 2629*f9cc9f20SBram Moolenaar return NULL; 2630*f9cc9f20SBram Moolenaar } 2631*f9cc9f20SBram Moolenaar #endif 2632*f9cc9f20SBram Moolenaar 2633*f9cc9f20SBram Moolenaar #if (defined(FEAT_SYN_HL) \ 2634*f9cc9f20SBram Moolenaar && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) \ 2635*f9cc9f20SBram Moolenaar && defined(FEAT_PRINTER)) || defined(PROTO) 2636*f9cc9f20SBram Moolenaar /* 2637*f9cc9f20SBram Moolenaar * Return color name of highlight group "id" as RGB value. 2638*f9cc9f20SBram Moolenaar */ 2639*f9cc9f20SBram Moolenaar long_u 2640*f9cc9f20SBram Moolenaar highlight_gui_color_rgb( 2641*f9cc9f20SBram Moolenaar int id, 2642*f9cc9f20SBram Moolenaar int fg) // TRUE = fg, FALSE = bg 2643*f9cc9f20SBram Moolenaar { 2644*f9cc9f20SBram Moolenaar guicolor_T color; 2645*f9cc9f20SBram Moolenaar 2646*f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len) 2647*f9cc9f20SBram Moolenaar return 0L; 2648*f9cc9f20SBram Moolenaar 2649*f9cc9f20SBram Moolenaar if (fg) 2650*f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_fg; 2651*f9cc9f20SBram Moolenaar else 2652*f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_bg; 2653*f9cc9f20SBram Moolenaar 2654*f9cc9f20SBram Moolenaar if (color == INVALCOLOR) 2655*f9cc9f20SBram Moolenaar return 0L; 2656*f9cc9f20SBram Moolenaar 2657*f9cc9f20SBram Moolenaar return GUI_MCH_GET_RGB(color); 2658*f9cc9f20SBram Moolenaar } 2659*f9cc9f20SBram Moolenaar #endif 2660*f9cc9f20SBram Moolenaar 2661*f9cc9f20SBram Moolenaar /* 2662*f9cc9f20SBram Moolenaar * Output the syntax list header. 2663*f9cc9f20SBram Moolenaar * Return TRUE when started a new line. 2664*f9cc9f20SBram Moolenaar */ 2665*f9cc9f20SBram Moolenaar int 2666*f9cc9f20SBram Moolenaar syn_list_header( 2667*f9cc9f20SBram Moolenaar int did_header, // did header already 2668*f9cc9f20SBram Moolenaar int outlen, // length of string that comes 2669*f9cc9f20SBram Moolenaar int id) // highlight group id 2670*f9cc9f20SBram Moolenaar { 2671*f9cc9f20SBram Moolenaar int endcol = 19; 2672*f9cc9f20SBram Moolenaar int newline = TRUE; 2673*f9cc9f20SBram Moolenaar int name_col = 0; 2674*f9cc9f20SBram Moolenaar 2675*f9cc9f20SBram Moolenaar if (!did_header) 2676*f9cc9f20SBram Moolenaar { 2677*f9cc9f20SBram Moolenaar msg_putchar('\n'); 2678*f9cc9f20SBram Moolenaar if (got_int) 2679*f9cc9f20SBram Moolenaar return TRUE; 2680*f9cc9f20SBram Moolenaar msg_outtrans(HL_TABLE()[id - 1].sg_name); 2681*f9cc9f20SBram Moolenaar name_col = msg_col; 2682*f9cc9f20SBram Moolenaar endcol = 15; 2683*f9cc9f20SBram Moolenaar } 2684*f9cc9f20SBram Moolenaar else if (msg_col + outlen + 1 >= Columns) 2685*f9cc9f20SBram Moolenaar { 2686*f9cc9f20SBram Moolenaar msg_putchar('\n'); 2687*f9cc9f20SBram Moolenaar if (got_int) 2688*f9cc9f20SBram Moolenaar return TRUE; 2689*f9cc9f20SBram Moolenaar } 2690*f9cc9f20SBram Moolenaar else 2691*f9cc9f20SBram Moolenaar { 2692*f9cc9f20SBram Moolenaar if (msg_col >= endcol) // wrap around is like starting a new line 2693*f9cc9f20SBram Moolenaar newline = FALSE; 2694*f9cc9f20SBram Moolenaar } 2695*f9cc9f20SBram Moolenaar 2696*f9cc9f20SBram Moolenaar if (msg_col >= endcol) // output at least one space 2697*f9cc9f20SBram Moolenaar endcol = msg_col + 1; 2698*f9cc9f20SBram Moolenaar if (Columns <= endcol) // avoid hang for tiny window 2699*f9cc9f20SBram Moolenaar endcol = Columns - 1; 2700*f9cc9f20SBram Moolenaar 2701*f9cc9f20SBram Moolenaar msg_advance(endcol); 2702*f9cc9f20SBram Moolenaar 2703*f9cc9f20SBram Moolenaar // Show "xxx" with the attributes. 2704*f9cc9f20SBram Moolenaar if (!did_header) 2705*f9cc9f20SBram Moolenaar { 2706*f9cc9f20SBram Moolenaar if (endcol == Columns - 1 && endcol <= name_col) 2707*f9cc9f20SBram Moolenaar msg_putchar(' '); 2708*f9cc9f20SBram Moolenaar msg_puts_attr("xxx", syn_id2attr(id)); 2709*f9cc9f20SBram Moolenaar msg_putchar(' '); 2710*f9cc9f20SBram Moolenaar } 2711*f9cc9f20SBram Moolenaar 2712*f9cc9f20SBram Moolenaar return newline; 2713*f9cc9f20SBram Moolenaar } 2714*f9cc9f20SBram Moolenaar 2715*f9cc9f20SBram Moolenaar /* 2716*f9cc9f20SBram Moolenaar * Set the attribute numbers for a highlight group. 2717*f9cc9f20SBram Moolenaar * Called after one of the attributes has changed. 2718*f9cc9f20SBram Moolenaar */ 2719*f9cc9f20SBram Moolenaar static void 2720*f9cc9f20SBram Moolenaar set_hl_attr( 2721*f9cc9f20SBram Moolenaar int idx) // index in array 2722*f9cc9f20SBram Moolenaar { 2723*f9cc9f20SBram Moolenaar attrentry_T at_en; 2724*f9cc9f20SBram Moolenaar hl_group_T *sgp = HL_TABLE() + idx; 2725*f9cc9f20SBram Moolenaar 2726*f9cc9f20SBram Moolenaar // The "Normal" group doesn't need an attribute number 2727*f9cc9f20SBram Moolenaar if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) 2728*f9cc9f20SBram Moolenaar return; 2729*f9cc9f20SBram Moolenaar 2730*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2731*f9cc9f20SBram Moolenaar /* 2732*f9cc9f20SBram Moolenaar * For the GUI mode: If there are other than "normal" highlighting 2733*f9cc9f20SBram Moolenaar * attributes, need to allocate an attr number. 2734*f9cc9f20SBram Moolenaar */ 2735*f9cc9f20SBram Moolenaar if (sgp->sg_gui_fg == INVALCOLOR 2736*f9cc9f20SBram Moolenaar && sgp->sg_gui_bg == INVALCOLOR 2737*f9cc9f20SBram Moolenaar && sgp->sg_gui_sp == INVALCOLOR 2738*f9cc9f20SBram Moolenaar && sgp->sg_font == NOFONT 2739*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2740*f9cc9f20SBram Moolenaar && sgp->sg_fontset == NOFONTSET 2741*f9cc9f20SBram Moolenaar # endif 2742*f9cc9f20SBram Moolenaar ) 2743*f9cc9f20SBram Moolenaar { 2744*f9cc9f20SBram Moolenaar sgp->sg_gui_attr = sgp->sg_gui; 2745*f9cc9f20SBram Moolenaar } 2746*f9cc9f20SBram Moolenaar else 2747*f9cc9f20SBram Moolenaar { 2748*f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_gui; 2749*f9cc9f20SBram Moolenaar at_en.ae_u.gui.fg_color = sgp->sg_gui_fg; 2750*f9cc9f20SBram Moolenaar at_en.ae_u.gui.bg_color = sgp->sg_gui_bg; 2751*f9cc9f20SBram Moolenaar at_en.ae_u.gui.sp_color = sgp->sg_gui_sp; 2752*f9cc9f20SBram Moolenaar at_en.ae_u.gui.font = sgp->sg_font; 2753*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2754*f9cc9f20SBram Moolenaar at_en.ae_u.gui.fontset = sgp->sg_fontset; 2755*f9cc9f20SBram Moolenaar # endif 2756*f9cc9f20SBram Moolenaar sgp->sg_gui_attr = get_attr_entry(&gui_attr_table, &at_en); 2757*f9cc9f20SBram Moolenaar } 2758*f9cc9f20SBram Moolenaar #endif 2759*f9cc9f20SBram Moolenaar /* 2760*f9cc9f20SBram Moolenaar * For the term mode: If there are other than "normal" highlighting 2761*f9cc9f20SBram Moolenaar * attributes, need to allocate an attr number. 2762*f9cc9f20SBram Moolenaar */ 2763*f9cc9f20SBram Moolenaar if (sgp->sg_start == NULL && sgp->sg_stop == NULL) 2764*f9cc9f20SBram Moolenaar sgp->sg_term_attr = sgp->sg_term; 2765*f9cc9f20SBram Moolenaar else 2766*f9cc9f20SBram Moolenaar { 2767*f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_term; 2768*f9cc9f20SBram Moolenaar at_en.ae_u.term.start = sgp->sg_start; 2769*f9cc9f20SBram Moolenaar at_en.ae_u.term.stop = sgp->sg_stop; 2770*f9cc9f20SBram Moolenaar sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en); 2771*f9cc9f20SBram Moolenaar } 2772*f9cc9f20SBram Moolenaar 2773*f9cc9f20SBram Moolenaar /* 2774*f9cc9f20SBram Moolenaar * For the color term mode: If there are other than "normal" 2775*f9cc9f20SBram Moolenaar * highlighting attributes, need to allocate an attr number. 2776*f9cc9f20SBram Moolenaar */ 2777*f9cc9f20SBram Moolenaar if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 2778*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 2779*f9cc9f20SBram Moolenaar && sgp->sg_gui_fg == INVALCOLOR 2780*f9cc9f20SBram Moolenaar && sgp->sg_gui_bg == INVALCOLOR 2781*f9cc9f20SBram Moolenaar # endif 2782*f9cc9f20SBram Moolenaar ) 2783*f9cc9f20SBram Moolenaar sgp->sg_cterm_attr = sgp->sg_cterm; 2784*f9cc9f20SBram Moolenaar else 2785*f9cc9f20SBram Moolenaar { 2786*f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_cterm; 2787*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg; 2788*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg; 2789*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 2790*f9cc9f20SBram Moolenaar # ifdef MSWIN 2791*f9cc9f20SBram Moolenaar # ifdef VIMDLL 2792*f9cc9f20SBram Moolenaar // Only when not using the GUI. 2793*f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting) 2794*f9cc9f20SBram Moolenaar # endif 2795*f9cc9f20SBram Moolenaar { 2796*f9cc9f20SBram Moolenaar int id; 2797*f9cc9f20SBram Moolenaar guicolor_T fg, bg; 2798*f9cc9f20SBram Moolenaar 2799*f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 2800*f9cc9f20SBram Moolenaar if (id > 0) 2801*f9cc9f20SBram Moolenaar { 2802*f9cc9f20SBram Moolenaar syn_id2colors(id, &fg, &bg); 2803*f9cc9f20SBram Moolenaar if (sgp->sg_gui_fg == INVALCOLOR) 2804*f9cc9f20SBram Moolenaar sgp->sg_gui_fg = fg; 2805*f9cc9f20SBram Moolenaar if (sgp->sg_gui_bg == INVALCOLOR) 2806*f9cc9f20SBram Moolenaar sgp->sg_gui_bg = bg; 2807*f9cc9f20SBram Moolenaar } 2808*f9cc9f20SBram Moolenaar 2809*f9cc9f20SBram Moolenaar } 2810*f9cc9f20SBram Moolenaar # endif 2811*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_fg); 2812*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_bg); 2813*f9cc9f20SBram Moolenaar if (at_en.ae_u.cterm.fg_rgb == INVALCOLOR 2814*f9cc9f20SBram Moolenaar && at_en.ae_u.cterm.bg_rgb == INVALCOLOR) 2815*f9cc9f20SBram Moolenaar { 2816*f9cc9f20SBram Moolenaar // If both fg and bg are invalid fall back to the cterm colors. 2817*f9cc9f20SBram Moolenaar // Helps when the GUI only uses an attribute, e.g. undercurl. 2818*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = CTERMCOLOR; 2819*f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = CTERMCOLOR; 2820*f9cc9f20SBram Moolenaar } 2821*f9cc9f20SBram Moolenaar # endif 2822*f9cc9f20SBram Moolenaar sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en); 2823*f9cc9f20SBram Moolenaar } 2824*f9cc9f20SBram Moolenaar } 2825*f9cc9f20SBram Moolenaar 2826*f9cc9f20SBram Moolenaar /* 2827*f9cc9f20SBram Moolenaar * Lookup a highlight group name and return its ID. 2828*f9cc9f20SBram Moolenaar * If it is not found, 0 is returned. 2829*f9cc9f20SBram Moolenaar */ 2830*f9cc9f20SBram Moolenaar int 2831*f9cc9f20SBram Moolenaar syn_name2id(char_u *name) 2832*f9cc9f20SBram Moolenaar { 2833*f9cc9f20SBram Moolenaar int i; 2834*f9cc9f20SBram Moolenaar char_u name_u[200]; 2835*f9cc9f20SBram Moolenaar 2836*f9cc9f20SBram Moolenaar // Avoid using stricmp() too much, it's slow on some systems 2837*f9cc9f20SBram Moolenaar // Avoid alloc()/free(), these are slow too. ID names over 200 chars 2838*f9cc9f20SBram Moolenaar // don't deserve to be found! 2839*f9cc9f20SBram Moolenaar vim_strncpy(name_u, name, 199); 2840*f9cc9f20SBram Moolenaar vim_strup(name_u); 2841*f9cc9f20SBram Moolenaar for (i = highlight_ga.ga_len; --i >= 0; ) 2842*f9cc9f20SBram Moolenaar if (HL_TABLE()[i].sg_name_u != NULL 2843*f9cc9f20SBram Moolenaar && STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0) 2844*f9cc9f20SBram Moolenaar break; 2845*f9cc9f20SBram Moolenaar return i + 1; 2846*f9cc9f20SBram Moolenaar } 2847*f9cc9f20SBram Moolenaar 2848*f9cc9f20SBram Moolenaar /* 2849*f9cc9f20SBram Moolenaar * Lookup a highlight group name and return its attributes. 2850*f9cc9f20SBram Moolenaar * Return zero if not found. 2851*f9cc9f20SBram Moolenaar */ 2852*f9cc9f20SBram Moolenaar int 2853*f9cc9f20SBram Moolenaar syn_name2attr(char_u *name) 2854*f9cc9f20SBram Moolenaar { 2855*f9cc9f20SBram Moolenaar int id = syn_name2id(name); 2856*f9cc9f20SBram Moolenaar 2857*f9cc9f20SBram Moolenaar if (id != 0) 2858*f9cc9f20SBram Moolenaar return syn_id2attr(id); 2859*f9cc9f20SBram Moolenaar return 0; 2860*f9cc9f20SBram Moolenaar } 2861*f9cc9f20SBram Moolenaar 2862*f9cc9f20SBram Moolenaar #if defined(FEAT_EVAL) || defined(PROTO) 2863*f9cc9f20SBram Moolenaar /* 2864*f9cc9f20SBram Moolenaar * Return TRUE if highlight group "name" exists. 2865*f9cc9f20SBram Moolenaar */ 2866*f9cc9f20SBram Moolenaar int 2867*f9cc9f20SBram Moolenaar highlight_exists(char_u *name) 2868*f9cc9f20SBram Moolenaar { 2869*f9cc9f20SBram Moolenaar return (syn_name2id(name) > 0); 2870*f9cc9f20SBram Moolenaar } 2871*f9cc9f20SBram Moolenaar 2872*f9cc9f20SBram Moolenaar # if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) 2873*f9cc9f20SBram Moolenaar /* 2874*f9cc9f20SBram Moolenaar * Return the name of highlight group "id". 2875*f9cc9f20SBram Moolenaar * When not a valid ID return an empty string. 2876*f9cc9f20SBram Moolenaar */ 2877*f9cc9f20SBram Moolenaar char_u * 2878*f9cc9f20SBram Moolenaar syn_id2name(int id) 2879*f9cc9f20SBram Moolenaar { 2880*f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len) 2881*f9cc9f20SBram Moolenaar return (char_u *)""; 2882*f9cc9f20SBram Moolenaar return HL_TABLE()[id - 1].sg_name; 2883*f9cc9f20SBram Moolenaar } 2884*f9cc9f20SBram Moolenaar # endif 2885*f9cc9f20SBram Moolenaar #endif 2886*f9cc9f20SBram Moolenaar 2887*f9cc9f20SBram Moolenaar /* 2888*f9cc9f20SBram Moolenaar * Like syn_name2id(), but take a pointer + length argument. 2889*f9cc9f20SBram Moolenaar */ 2890*f9cc9f20SBram Moolenaar int 2891*f9cc9f20SBram Moolenaar syn_namen2id(char_u *linep, int len) 2892*f9cc9f20SBram Moolenaar { 2893*f9cc9f20SBram Moolenaar char_u *name; 2894*f9cc9f20SBram Moolenaar int id = 0; 2895*f9cc9f20SBram Moolenaar 2896*f9cc9f20SBram Moolenaar name = vim_strnsave(linep, len); 2897*f9cc9f20SBram Moolenaar if (name != NULL) 2898*f9cc9f20SBram Moolenaar { 2899*f9cc9f20SBram Moolenaar id = syn_name2id(name); 2900*f9cc9f20SBram Moolenaar vim_free(name); 2901*f9cc9f20SBram Moolenaar } 2902*f9cc9f20SBram Moolenaar return id; 2903*f9cc9f20SBram Moolenaar } 2904*f9cc9f20SBram Moolenaar 2905*f9cc9f20SBram Moolenaar /* 2906*f9cc9f20SBram Moolenaar * Find highlight group name in the table and return its ID. 2907*f9cc9f20SBram Moolenaar * The argument is a pointer to the name and the length of the name. 2908*f9cc9f20SBram Moolenaar * If it doesn't exist yet, a new entry is created. 2909*f9cc9f20SBram Moolenaar * Return 0 for failure. 2910*f9cc9f20SBram Moolenaar */ 2911*f9cc9f20SBram Moolenaar int 2912*f9cc9f20SBram Moolenaar syn_check_group(char_u *pp, int len) 2913*f9cc9f20SBram Moolenaar { 2914*f9cc9f20SBram Moolenaar int id; 2915*f9cc9f20SBram Moolenaar char_u *name; 2916*f9cc9f20SBram Moolenaar 2917*f9cc9f20SBram Moolenaar name = vim_strnsave(pp, len); 2918*f9cc9f20SBram Moolenaar if (name == NULL) 2919*f9cc9f20SBram Moolenaar return 0; 2920*f9cc9f20SBram Moolenaar 2921*f9cc9f20SBram Moolenaar id = syn_name2id(name); 2922*f9cc9f20SBram Moolenaar if (id == 0) // doesn't exist yet 2923*f9cc9f20SBram Moolenaar id = syn_add_group(name); 2924*f9cc9f20SBram Moolenaar else 2925*f9cc9f20SBram Moolenaar vim_free(name); 2926*f9cc9f20SBram Moolenaar return id; 2927*f9cc9f20SBram Moolenaar } 2928*f9cc9f20SBram Moolenaar 2929*f9cc9f20SBram Moolenaar /* 2930*f9cc9f20SBram Moolenaar * Add new highlight group and return its ID. 2931*f9cc9f20SBram Moolenaar * "name" must be an allocated string, it will be consumed. 2932*f9cc9f20SBram Moolenaar * Return 0 for failure. 2933*f9cc9f20SBram Moolenaar */ 2934*f9cc9f20SBram Moolenaar static int 2935*f9cc9f20SBram Moolenaar syn_add_group(char_u *name) 2936*f9cc9f20SBram Moolenaar { 2937*f9cc9f20SBram Moolenaar char_u *p; 2938*f9cc9f20SBram Moolenaar 2939*f9cc9f20SBram Moolenaar // Check that the name is ASCII letters, digits and underscore. 2940*f9cc9f20SBram Moolenaar for (p = name; *p != NUL; ++p) 2941*f9cc9f20SBram Moolenaar { 2942*f9cc9f20SBram Moolenaar if (!vim_isprintc(*p)) 2943*f9cc9f20SBram Moolenaar { 2944*f9cc9f20SBram Moolenaar emsg(_("E669: Unprintable character in group name")); 2945*f9cc9f20SBram Moolenaar vim_free(name); 2946*f9cc9f20SBram Moolenaar return 0; 2947*f9cc9f20SBram Moolenaar } 2948*f9cc9f20SBram Moolenaar else if (!ASCII_ISALNUM(*p) && *p != '_') 2949*f9cc9f20SBram Moolenaar { 2950*f9cc9f20SBram Moolenaar // This is an error, but since there previously was no check only 2951*f9cc9f20SBram Moolenaar // give a warning. 2952*f9cc9f20SBram Moolenaar msg_source(HL_ATTR(HLF_W)); 2953*f9cc9f20SBram Moolenaar msg(_("W18: Invalid character in group name")); 2954*f9cc9f20SBram Moolenaar break; 2955*f9cc9f20SBram Moolenaar } 2956*f9cc9f20SBram Moolenaar } 2957*f9cc9f20SBram Moolenaar 2958*f9cc9f20SBram Moolenaar /* 2959*f9cc9f20SBram Moolenaar * First call for this growarray: init growing array. 2960*f9cc9f20SBram Moolenaar */ 2961*f9cc9f20SBram Moolenaar if (highlight_ga.ga_data == NULL) 2962*f9cc9f20SBram Moolenaar { 2963*f9cc9f20SBram Moolenaar highlight_ga.ga_itemsize = sizeof(hl_group_T); 2964*f9cc9f20SBram Moolenaar highlight_ga.ga_growsize = 10; 2965*f9cc9f20SBram Moolenaar } 2966*f9cc9f20SBram Moolenaar 2967*f9cc9f20SBram Moolenaar if (highlight_ga.ga_len >= MAX_HL_ID) 2968*f9cc9f20SBram Moolenaar { 2969*f9cc9f20SBram Moolenaar emsg(_("E849: Too many highlight and syntax groups")); 2970*f9cc9f20SBram Moolenaar vim_free(name); 2971*f9cc9f20SBram Moolenaar return 0; 2972*f9cc9f20SBram Moolenaar } 2973*f9cc9f20SBram Moolenaar 2974*f9cc9f20SBram Moolenaar /* 2975*f9cc9f20SBram Moolenaar * Make room for at least one other syntax_highlight entry. 2976*f9cc9f20SBram Moolenaar */ 2977*f9cc9f20SBram Moolenaar if (ga_grow(&highlight_ga, 1) == FAIL) 2978*f9cc9f20SBram Moolenaar { 2979*f9cc9f20SBram Moolenaar vim_free(name); 2980*f9cc9f20SBram Moolenaar return 0; 2981*f9cc9f20SBram Moolenaar } 2982*f9cc9f20SBram Moolenaar 2983*f9cc9f20SBram Moolenaar vim_memset(&(HL_TABLE()[highlight_ga.ga_len]), 0, sizeof(hl_group_T)); 2984*f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_name = name; 2985*f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_name_u = vim_strsave_up(name); 2986*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 2987*f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_bg = INVALCOLOR; 2988*f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR; 2989*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 2990*f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_sp = INVALCOLOR; 2991*f9cc9f20SBram Moolenaar # endif 2992*f9cc9f20SBram Moolenaar #endif 2993*f9cc9f20SBram Moolenaar ++highlight_ga.ga_len; 2994*f9cc9f20SBram Moolenaar 2995*f9cc9f20SBram Moolenaar return highlight_ga.ga_len; // ID is index plus one 2996*f9cc9f20SBram Moolenaar } 2997*f9cc9f20SBram Moolenaar 2998*f9cc9f20SBram Moolenaar /* 2999*f9cc9f20SBram Moolenaar * When, just after calling syn_add_group(), an error is discovered, this 3000*f9cc9f20SBram Moolenaar * function deletes the new name. 3001*f9cc9f20SBram Moolenaar */ 3002*f9cc9f20SBram Moolenaar static void 3003*f9cc9f20SBram Moolenaar syn_unadd_group(void) 3004*f9cc9f20SBram Moolenaar { 3005*f9cc9f20SBram Moolenaar --highlight_ga.ga_len; 3006*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name); 3007*f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u); 3008*f9cc9f20SBram Moolenaar } 3009*f9cc9f20SBram Moolenaar 3010*f9cc9f20SBram Moolenaar /* 3011*f9cc9f20SBram Moolenaar * Translate a group ID to highlight attributes. 3012*f9cc9f20SBram Moolenaar */ 3013*f9cc9f20SBram Moolenaar int 3014*f9cc9f20SBram Moolenaar syn_id2attr(int hl_id) 3015*f9cc9f20SBram Moolenaar { 3016*f9cc9f20SBram Moolenaar int attr; 3017*f9cc9f20SBram Moolenaar hl_group_T *sgp; 3018*f9cc9f20SBram Moolenaar 3019*f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id); 3020*f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one 3021*f9cc9f20SBram Moolenaar 3022*f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 3023*f9cc9f20SBram Moolenaar /* 3024*f9cc9f20SBram Moolenaar * Only use GUI attr when the GUI is being used. 3025*f9cc9f20SBram Moolenaar */ 3026*f9cc9f20SBram Moolenaar if (gui.in_use) 3027*f9cc9f20SBram Moolenaar attr = sgp->sg_gui_attr; 3028*f9cc9f20SBram Moolenaar else 3029*f9cc9f20SBram Moolenaar #endif 3030*f9cc9f20SBram Moolenaar if (IS_CTERM) 3031*f9cc9f20SBram Moolenaar attr = sgp->sg_cterm_attr; 3032*f9cc9f20SBram Moolenaar else 3033*f9cc9f20SBram Moolenaar attr = sgp->sg_term_attr; 3034*f9cc9f20SBram Moolenaar 3035*f9cc9f20SBram Moolenaar return attr; 3036*f9cc9f20SBram Moolenaar } 3037*f9cc9f20SBram Moolenaar 3038*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) 3039*f9cc9f20SBram Moolenaar /* 3040*f9cc9f20SBram Moolenaar * Get the GUI colors and attributes for a group ID. 3041*f9cc9f20SBram Moolenaar * NOTE: the colors will be INVALCOLOR when not set, the color otherwise. 3042*f9cc9f20SBram Moolenaar */ 3043*f9cc9f20SBram Moolenaar int 3044*f9cc9f20SBram Moolenaar syn_id2colors(int hl_id, guicolor_T *fgp, guicolor_T *bgp) 3045*f9cc9f20SBram Moolenaar { 3046*f9cc9f20SBram Moolenaar hl_group_T *sgp; 3047*f9cc9f20SBram Moolenaar 3048*f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id); 3049*f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one 3050*f9cc9f20SBram Moolenaar 3051*f9cc9f20SBram Moolenaar *fgp = sgp->sg_gui_fg; 3052*f9cc9f20SBram Moolenaar *bgp = sgp->sg_gui_bg; 3053*f9cc9f20SBram Moolenaar return sgp->sg_gui; 3054*f9cc9f20SBram Moolenaar } 3055*f9cc9f20SBram Moolenaar #endif 3056*f9cc9f20SBram Moolenaar 3057*f9cc9f20SBram Moolenaar #if (defined(MSWIN) \ 3058*f9cc9f20SBram Moolenaar && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \ 3059*f9cc9f20SBram Moolenaar && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) 3060*f9cc9f20SBram Moolenaar void 3061*f9cc9f20SBram Moolenaar syn_id2cterm_bg(int hl_id, int *fgp, int *bgp) 3062*f9cc9f20SBram Moolenaar { 3063*f9cc9f20SBram Moolenaar hl_group_T *sgp; 3064*f9cc9f20SBram Moolenaar 3065*f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id); 3066*f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one 3067*f9cc9f20SBram Moolenaar *fgp = sgp->sg_cterm_fg - 1; 3068*f9cc9f20SBram Moolenaar *bgp = sgp->sg_cterm_bg - 1; 3069*f9cc9f20SBram Moolenaar } 3070*f9cc9f20SBram Moolenaar #endif 3071*f9cc9f20SBram Moolenaar 3072*f9cc9f20SBram Moolenaar /* 3073*f9cc9f20SBram Moolenaar * Translate a group ID to the final group ID (following links). 3074*f9cc9f20SBram Moolenaar */ 3075*f9cc9f20SBram Moolenaar int 3076*f9cc9f20SBram Moolenaar syn_get_final_id(int hl_id) 3077*f9cc9f20SBram Moolenaar { 3078*f9cc9f20SBram Moolenaar int count; 3079*f9cc9f20SBram Moolenaar hl_group_T *sgp; 3080*f9cc9f20SBram Moolenaar 3081*f9cc9f20SBram Moolenaar if (hl_id > highlight_ga.ga_len || hl_id < 1) 3082*f9cc9f20SBram Moolenaar return 0; // Can be called from eval!! 3083*f9cc9f20SBram Moolenaar 3084*f9cc9f20SBram Moolenaar /* 3085*f9cc9f20SBram Moolenaar * Follow links until there is no more. 3086*f9cc9f20SBram Moolenaar * Look out for loops! Break after 100 links. 3087*f9cc9f20SBram Moolenaar */ 3088*f9cc9f20SBram Moolenaar for (count = 100; --count >= 0; ) 3089*f9cc9f20SBram Moolenaar { 3090*f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one 3091*f9cc9f20SBram Moolenaar if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len) 3092*f9cc9f20SBram Moolenaar break; 3093*f9cc9f20SBram Moolenaar hl_id = sgp->sg_link; 3094*f9cc9f20SBram Moolenaar } 3095*f9cc9f20SBram Moolenaar 3096*f9cc9f20SBram Moolenaar return hl_id; 3097*f9cc9f20SBram Moolenaar } 3098*f9cc9f20SBram Moolenaar 3099*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) 3100*f9cc9f20SBram Moolenaar /* 3101*f9cc9f20SBram Moolenaar * Call this function just after the GUI has started. 3102*f9cc9f20SBram Moolenaar * Also called when 'termguicolors' was set, gui.in_use will be FALSE then. 3103*f9cc9f20SBram Moolenaar * It finds the font and color handles for the highlighting groups. 3104*f9cc9f20SBram Moolenaar */ 3105*f9cc9f20SBram Moolenaar void 3106*f9cc9f20SBram Moolenaar highlight_gui_started(void) 3107*f9cc9f20SBram Moolenaar { 3108*f9cc9f20SBram Moolenaar int idx; 3109*f9cc9f20SBram Moolenaar 3110*f9cc9f20SBram Moolenaar // First get the colors from the "Normal" and "Menu" group, if set 3111*f9cc9f20SBram Moolenaar if (USE_24BIT) 3112*f9cc9f20SBram Moolenaar set_normal_colors(); 3113*f9cc9f20SBram Moolenaar 3114*f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx) 3115*f9cc9f20SBram Moolenaar gui_do_one_color(idx, FALSE, FALSE); 3116*f9cc9f20SBram Moolenaar 3117*f9cc9f20SBram Moolenaar highlight_changed(); 3118*f9cc9f20SBram Moolenaar } 3119*f9cc9f20SBram Moolenaar 3120*f9cc9f20SBram Moolenaar static void 3121*f9cc9f20SBram Moolenaar gui_do_one_color( 3122*f9cc9f20SBram Moolenaar int idx, 3123*f9cc9f20SBram Moolenaar int do_menu UNUSED, // TRUE: might set the menu font 3124*f9cc9f20SBram Moolenaar int do_tooltip UNUSED) // TRUE: might set the tooltip font 3125*f9cc9f20SBram Moolenaar { 3126*f9cc9f20SBram Moolenaar int didit = FALSE; 3127*f9cc9f20SBram Moolenaar 3128*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 3129*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 3130*f9cc9f20SBram Moolenaar if (gui.in_use) 3131*f9cc9f20SBram Moolenaar # endif 3132*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font_name != NULL) 3133*f9cc9f20SBram Moolenaar { 3134*f9cc9f20SBram Moolenaar hl_do_font(idx, HL_TABLE()[idx].sg_font_name, FALSE, do_menu, 3135*f9cc9f20SBram Moolenaar do_tooltip, TRUE); 3136*f9cc9f20SBram Moolenaar didit = TRUE; 3137*f9cc9f20SBram Moolenaar } 3138*f9cc9f20SBram Moolenaar # endif 3139*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_fg_name != NULL) 3140*f9cc9f20SBram Moolenaar { 3141*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg = 3142*f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_fg_name); 3143*f9cc9f20SBram Moolenaar didit = TRUE; 3144*f9cc9f20SBram Moolenaar } 3145*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_bg_name != NULL) 3146*f9cc9f20SBram Moolenaar { 3147*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg = 3148*f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_bg_name); 3149*f9cc9f20SBram Moolenaar didit = TRUE; 3150*f9cc9f20SBram Moolenaar } 3151*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 3152*f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_sp_name != NULL) 3153*f9cc9f20SBram Moolenaar { 3154*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_sp = 3155*f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_sp_name); 3156*f9cc9f20SBram Moolenaar didit = TRUE; 3157*f9cc9f20SBram Moolenaar } 3158*f9cc9f20SBram Moolenaar # endif 3159*f9cc9f20SBram Moolenaar if (didit) // need to get a new attr number 3160*f9cc9f20SBram Moolenaar set_hl_attr(idx); 3161*f9cc9f20SBram Moolenaar } 3162*f9cc9f20SBram Moolenaar #endif 3163*f9cc9f20SBram Moolenaar 3164*f9cc9f20SBram Moolenaar #if defined(USER_HIGHLIGHT) && defined(FEAT_STL_OPT) 3165*f9cc9f20SBram Moolenaar /* 3166*f9cc9f20SBram Moolenaar * Apply difference between User[1-9] and HLF_S to HLF_SNC, HLF_ST or HLF_STNC. 3167*f9cc9f20SBram Moolenaar */ 3168*f9cc9f20SBram Moolenaar static void 3169*f9cc9f20SBram Moolenaar combine_stl_hlt( 3170*f9cc9f20SBram Moolenaar int id, 3171*f9cc9f20SBram Moolenaar int id_S, 3172*f9cc9f20SBram Moolenaar int id_alt, 3173*f9cc9f20SBram Moolenaar int hlcnt, 3174*f9cc9f20SBram Moolenaar int i, 3175*f9cc9f20SBram Moolenaar int hlf, 3176*f9cc9f20SBram Moolenaar int *table) 3177*f9cc9f20SBram Moolenaar { 3178*f9cc9f20SBram Moolenaar hl_group_T *hlt = HL_TABLE(); 3179*f9cc9f20SBram Moolenaar 3180*f9cc9f20SBram Moolenaar if (id_alt == 0) 3181*f9cc9f20SBram Moolenaar { 3182*f9cc9f20SBram Moolenaar vim_memset(&hlt[hlcnt + i], 0, sizeof(hl_group_T)); 3183*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_term = highlight_attr[hlf]; 3184*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm = highlight_attr[hlf]; 3185*f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_EVAL) 3186*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui = highlight_attr[hlf]; 3187*f9cc9f20SBram Moolenaar # endif 3188*f9cc9f20SBram Moolenaar } 3189*f9cc9f20SBram Moolenaar else 3190*f9cc9f20SBram Moolenaar mch_memmove(&hlt[hlcnt + i], 3191*f9cc9f20SBram Moolenaar &hlt[id_alt - 1], 3192*f9cc9f20SBram Moolenaar sizeof(hl_group_T)); 3193*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_link = 0; 3194*f9cc9f20SBram Moolenaar 3195*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_term ^= 3196*f9cc9f20SBram Moolenaar hlt[id - 1].sg_term ^ hlt[id_S - 1].sg_term; 3197*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_start != hlt[id_S - 1].sg_start) 3198*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_start = hlt[id - 1].sg_start; 3199*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_stop != hlt[id_S - 1].sg_stop) 3200*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_stop = hlt[id - 1].sg_stop; 3201*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm ^= 3202*f9cc9f20SBram Moolenaar hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm; 3203*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg) 3204*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg; 3205*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg) 3206*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg; 3207*f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_EVAL) 3208*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui ^= 3209*f9cc9f20SBram Moolenaar hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui; 3210*f9cc9f20SBram Moolenaar # endif 3211*f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 3212*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_fg != hlt[id_S - 1].sg_gui_fg) 3213*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_fg = hlt[id - 1].sg_gui_fg; 3214*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_bg != hlt[id_S - 1].sg_gui_bg) 3215*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_bg = hlt[id - 1].sg_gui_bg; 3216*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_sp != hlt[id_S - 1].sg_gui_sp) 3217*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_sp = hlt[id - 1].sg_gui_sp; 3218*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_font != hlt[id_S - 1].sg_font) 3219*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_font = hlt[id - 1].sg_font; 3220*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 3221*f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_fontset != hlt[id_S - 1].sg_fontset) 3222*f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_fontset = hlt[id - 1].sg_fontset; 3223*f9cc9f20SBram Moolenaar # endif 3224*f9cc9f20SBram Moolenaar # endif 3225*f9cc9f20SBram Moolenaar highlight_ga.ga_len = hlcnt + i + 1; 3226*f9cc9f20SBram Moolenaar set_hl_attr(hlcnt + i); // At long last we can apply 3227*f9cc9f20SBram Moolenaar table[i] = syn_id2attr(hlcnt + i + 1); 3228*f9cc9f20SBram Moolenaar } 3229*f9cc9f20SBram Moolenaar #endif 3230*f9cc9f20SBram Moolenaar 3231*f9cc9f20SBram Moolenaar /* 3232*f9cc9f20SBram Moolenaar * Translate the 'highlight' option into attributes in highlight_attr[] and 3233*f9cc9f20SBram Moolenaar * set up the user highlights User1..9. If FEAT_STL_OPT is in use, a set of 3234*f9cc9f20SBram Moolenaar * corresponding highlights to use on top of HLF_SNC is computed. 3235*f9cc9f20SBram Moolenaar * Called only when the 'highlight' option has been changed and upon first 3236*f9cc9f20SBram Moolenaar * screen redraw after any :highlight command. 3237*f9cc9f20SBram Moolenaar * Return FAIL when an invalid flag is found in 'highlight'. OK otherwise. 3238*f9cc9f20SBram Moolenaar */ 3239*f9cc9f20SBram Moolenaar int 3240*f9cc9f20SBram Moolenaar highlight_changed(void) 3241*f9cc9f20SBram Moolenaar { 3242*f9cc9f20SBram Moolenaar int hlf; 3243*f9cc9f20SBram Moolenaar int i; 3244*f9cc9f20SBram Moolenaar char_u *p; 3245*f9cc9f20SBram Moolenaar int attr; 3246*f9cc9f20SBram Moolenaar char_u *end; 3247*f9cc9f20SBram Moolenaar int id; 3248*f9cc9f20SBram Moolenaar #ifdef USER_HIGHLIGHT 3249*f9cc9f20SBram Moolenaar char_u userhl[30]; // use 30 to avoid compiler warning 3250*f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3251*f9cc9f20SBram Moolenaar int id_S = -1; 3252*f9cc9f20SBram Moolenaar int id_SNC = 0; 3253*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL 3254*f9cc9f20SBram Moolenaar int id_ST = 0; 3255*f9cc9f20SBram Moolenaar int id_STNC = 0; 3256*f9cc9f20SBram Moolenaar # endif 3257*f9cc9f20SBram Moolenaar int hlcnt; 3258*f9cc9f20SBram Moolenaar # endif 3259*f9cc9f20SBram Moolenaar #endif 3260*f9cc9f20SBram Moolenaar static int hl_flags[HLF_COUNT] = HL_FLAGS; 3261*f9cc9f20SBram Moolenaar 3262*f9cc9f20SBram Moolenaar need_highlight_changed = FALSE; 3263*f9cc9f20SBram Moolenaar 3264*f9cc9f20SBram Moolenaar /* 3265*f9cc9f20SBram Moolenaar * Clear all attributes. 3266*f9cc9f20SBram Moolenaar */ 3267*f9cc9f20SBram Moolenaar for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf) 3268*f9cc9f20SBram Moolenaar highlight_attr[hlf] = 0; 3269*f9cc9f20SBram Moolenaar 3270*f9cc9f20SBram Moolenaar /* 3271*f9cc9f20SBram Moolenaar * First set all attributes to their default value. 3272*f9cc9f20SBram Moolenaar * Then use the attributes from the 'highlight' option. 3273*f9cc9f20SBram Moolenaar */ 3274*f9cc9f20SBram Moolenaar for (i = 0; i < 2; ++i) 3275*f9cc9f20SBram Moolenaar { 3276*f9cc9f20SBram Moolenaar if (i) 3277*f9cc9f20SBram Moolenaar p = p_hl; 3278*f9cc9f20SBram Moolenaar else 3279*f9cc9f20SBram Moolenaar p = get_highlight_default(); 3280*f9cc9f20SBram Moolenaar if (p == NULL) // just in case 3281*f9cc9f20SBram Moolenaar continue; 3282*f9cc9f20SBram Moolenaar 3283*f9cc9f20SBram Moolenaar while (*p) 3284*f9cc9f20SBram Moolenaar { 3285*f9cc9f20SBram Moolenaar for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf) 3286*f9cc9f20SBram Moolenaar if (hl_flags[hlf] == *p) 3287*f9cc9f20SBram Moolenaar break; 3288*f9cc9f20SBram Moolenaar ++p; 3289*f9cc9f20SBram Moolenaar if (hlf == (int)HLF_COUNT || *p == NUL) 3290*f9cc9f20SBram Moolenaar return FAIL; 3291*f9cc9f20SBram Moolenaar 3292*f9cc9f20SBram Moolenaar /* 3293*f9cc9f20SBram Moolenaar * Allow several hl_flags to be combined, like "bu" for 3294*f9cc9f20SBram Moolenaar * bold-underlined. 3295*f9cc9f20SBram Moolenaar */ 3296*f9cc9f20SBram Moolenaar attr = 0; 3297*f9cc9f20SBram Moolenaar for ( ; *p && *p != ','; ++p) // parse upto comma 3298*f9cc9f20SBram Moolenaar { 3299*f9cc9f20SBram Moolenaar if (VIM_ISWHITE(*p)) // ignore white space 3300*f9cc9f20SBram Moolenaar continue; 3301*f9cc9f20SBram Moolenaar 3302*f9cc9f20SBram Moolenaar if (attr > HL_ALL) // Combination with ':' is not allowed. 3303*f9cc9f20SBram Moolenaar return FAIL; 3304*f9cc9f20SBram Moolenaar 3305*f9cc9f20SBram Moolenaar switch (*p) 3306*f9cc9f20SBram Moolenaar { 3307*f9cc9f20SBram Moolenaar case 'b': attr |= HL_BOLD; 3308*f9cc9f20SBram Moolenaar break; 3309*f9cc9f20SBram Moolenaar case 'i': attr |= HL_ITALIC; 3310*f9cc9f20SBram Moolenaar break; 3311*f9cc9f20SBram Moolenaar case '-': 3312*f9cc9f20SBram Moolenaar case 'n': // no highlighting 3313*f9cc9f20SBram Moolenaar break; 3314*f9cc9f20SBram Moolenaar case 'r': attr |= HL_INVERSE; 3315*f9cc9f20SBram Moolenaar break; 3316*f9cc9f20SBram Moolenaar case 's': attr |= HL_STANDOUT; 3317*f9cc9f20SBram Moolenaar break; 3318*f9cc9f20SBram Moolenaar case 'u': attr |= HL_UNDERLINE; 3319*f9cc9f20SBram Moolenaar break; 3320*f9cc9f20SBram Moolenaar case 'c': attr |= HL_UNDERCURL; 3321*f9cc9f20SBram Moolenaar break; 3322*f9cc9f20SBram Moolenaar case 't': attr |= HL_STRIKETHROUGH; 3323*f9cc9f20SBram Moolenaar break; 3324*f9cc9f20SBram Moolenaar case ':': ++p; // highlight group name 3325*f9cc9f20SBram Moolenaar if (attr || *p == NUL) // no combinations 3326*f9cc9f20SBram Moolenaar return FAIL; 3327*f9cc9f20SBram Moolenaar end = vim_strchr(p, ','); 3328*f9cc9f20SBram Moolenaar if (end == NULL) 3329*f9cc9f20SBram Moolenaar end = p + STRLEN(p); 3330*f9cc9f20SBram Moolenaar id = syn_check_group(p, (int)(end - p)); 3331*f9cc9f20SBram Moolenaar if (id == 0) 3332*f9cc9f20SBram Moolenaar return FAIL; 3333*f9cc9f20SBram Moolenaar attr = syn_id2attr(id); 3334*f9cc9f20SBram Moolenaar p = end - 1; 3335*f9cc9f20SBram Moolenaar #if defined(FEAT_STL_OPT) && defined(USER_HIGHLIGHT) 3336*f9cc9f20SBram Moolenaar if (hlf == (int)HLF_SNC) 3337*f9cc9f20SBram Moolenaar id_SNC = syn_get_final_id(id); 3338*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL 3339*f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_ST) 3340*f9cc9f20SBram Moolenaar id_ST = syn_get_final_id(id); 3341*f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_STNC) 3342*f9cc9f20SBram Moolenaar id_STNC = syn_get_final_id(id); 3343*f9cc9f20SBram Moolenaar # endif 3344*f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_S) 3345*f9cc9f20SBram Moolenaar id_S = syn_get_final_id(id); 3346*f9cc9f20SBram Moolenaar #endif 3347*f9cc9f20SBram Moolenaar break; 3348*f9cc9f20SBram Moolenaar default: return FAIL; 3349*f9cc9f20SBram Moolenaar } 3350*f9cc9f20SBram Moolenaar } 3351*f9cc9f20SBram Moolenaar highlight_attr[hlf] = attr; 3352*f9cc9f20SBram Moolenaar 3353*f9cc9f20SBram Moolenaar p = skip_to_option_part(p); // skip comma and spaces 3354*f9cc9f20SBram Moolenaar } 3355*f9cc9f20SBram Moolenaar } 3356*f9cc9f20SBram Moolenaar 3357*f9cc9f20SBram Moolenaar #ifdef USER_HIGHLIGHT 3358*f9cc9f20SBram Moolenaar /* 3359*f9cc9f20SBram Moolenaar * Setup the user highlights 3360*f9cc9f20SBram Moolenaar * 3361*f9cc9f20SBram Moolenaar * Temporarily utilize 28 more hl entries: 3362*f9cc9f20SBram Moolenaar * 9 for User1-User9 combined with StatusLineNC 3363*f9cc9f20SBram Moolenaar * 9 for User1-User9 combined with StatusLineTerm 3364*f9cc9f20SBram Moolenaar * 9 for User1-User9 combined with StatusLineTermNC 3365*f9cc9f20SBram Moolenaar * 1 for StatusLine default 3366*f9cc9f20SBram Moolenaar * Have to be in there simultaneously in case of table overflows in 3367*f9cc9f20SBram Moolenaar * get_attr_entry() 3368*f9cc9f20SBram Moolenaar */ 3369*f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3370*f9cc9f20SBram Moolenaar if (ga_grow(&highlight_ga, 28) == FAIL) 3371*f9cc9f20SBram Moolenaar return FAIL; 3372*f9cc9f20SBram Moolenaar hlcnt = highlight_ga.ga_len; 3373*f9cc9f20SBram Moolenaar if (id_S == -1) 3374*f9cc9f20SBram Moolenaar { 3375*f9cc9f20SBram Moolenaar // Make sure id_S is always valid to simplify code below. Use the last 3376*f9cc9f20SBram Moolenaar // entry. 3377*f9cc9f20SBram Moolenaar vim_memset(&HL_TABLE()[hlcnt + 27], 0, sizeof(hl_group_T)); 3378*f9cc9f20SBram Moolenaar HL_TABLE()[hlcnt + 18].sg_term = highlight_attr[HLF_S]; 3379*f9cc9f20SBram Moolenaar id_S = hlcnt + 19; 3380*f9cc9f20SBram Moolenaar } 3381*f9cc9f20SBram Moolenaar # endif 3382*f9cc9f20SBram Moolenaar for (i = 0; i < 9; i++) 3383*f9cc9f20SBram Moolenaar { 3384*f9cc9f20SBram Moolenaar sprintf((char *)userhl, "User%d", i + 1); 3385*f9cc9f20SBram Moolenaar id = syn_name2id(userhl); 3386*f9cc9f20SBram Moolenaar if (id == 0) 3387*f9cc9f20SBram Moolenaar { 3388*f9cc9f20SBram Moolenaar highlight_user[i] = 0; 3389*f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3390*f9cc9f20SBram Moolenaar highlight_stlnc[i] = 0; 3391*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL 3392*f9cc9f20SBram Moolenaar highlight_stlterm[i] = 0; 3393*f9cc9f20SBram Moolenaar highlight_stltermnc[i] = 0; 3394*f9cc9f20SBram Moolenaar # endif 3395*f9cc9f20SBram Moolenaar # endif 3396*f9cc9f20SBram Moolenaar } 3397*f9cc9f20SBram Moolenaar else 3398*f9cc9f20SBram Moolenaar { 3399*f9cc9f20SBram Moolenaar highlight_user[i] = syn_id2attr(id); 3400*f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3401*f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_SNC, hlcnt, i, 3402*f9cc9f20SBram Moolenaar HLF_SNC, highlight_stlnc); 3403*f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL 3404*f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_ST, hlcnt + 9, i, 3405*f9cc9f20SBram Moolenaar HLF_ST, highlight_stlterm); 3406*f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_STNC, hlcnt + 18, i, 3407*f9cc9f20SBram Moolenaar HLF_STNC, highlight_stltermnc); 3408*f9cc9f20SBram Moolenaar # endif 3409*f9cc9f20SBram Moolenaar # endif 3410*f9cc9f20SBram Moolenaar } 3411*f9cc9f20SBram Moolenaar } 3412*f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3413*f9cc9f20SBram Moolenaar highlight_ga.ga_len = hlcnt; 3414*f9cc9f20SBram Moolenaar # endif 3415*f9cc9f20SBram Moolenaar 3416*f9cc9f20SBram Moolenaar #endif // USER_HIGHLIGHT 3417*f9cc9f20SBram Moolenaar 3418*f9cc9f20SBram Moolenaar return OK; 3419*f9cc9f20SBram Moolenaar } 3420*f9cc9f20SBram Moolenaar 3421*f9cc9f20SBram Moolenaar #if defined(FEAT_CMDL_COMPL) || defined(PROTO) 3422*f9cc9f20SBram Moolenaar 3423*f9cc9f20SBram Moolenaar static void highlight_list(void); 3424*f9cc9f20SBram Moolenaar static void highlight_list_two(int cnt, int attr); 3425*f9cc9f20SBram Moolenaar 3426*f9cc9f20SBram Moolenaar /* 3427*f9cc9f20SBram Moolenaar * Handle command line completion for :highlight command. 3428*f9cc9f20SBram Moolenaar */ 3429*f9cc9f20SBram Moolenaar void 3430*f9cc9f20SBram Moolenaar set_context_in_highlight_cmd(expand_T *xp, char_u *arg) 3431*f9cc9f20SBram Moolenaar { 3432*f9cc9f20SBram Moolenaar char_u *p; 3433*f9cc9f20SBram Moolenaar 3434*f9cc9f20SBram Moolenaar // Default: expand group names 3435*f9cc9f20SBram Moolenaar xp->xp_context = EXPAND_HIGHLIGHT; 3436*f9cc9f20SBram Moolenaar xp->xp_pattern = arg; 3437*f9cc9f20SBram Moolenaar include_link = 2; 3438*f9cc9f20SBram Moolenaar include_default = 1; 3439*f9cc9f20SBram Moolenaar 3440*f9cc9f20SBram Moolenaar // (part of) subcommand already typed 3441*f9cc9f20SBram Moolenaar if (*arg != NUL) 3442*f9cc9f20SBram Moolenaar { 3443*f9cc9f20SBram Moolenaar p = skiptowhite(arg); 3444*f9cc9f20SBram Moolenaar if (*p != NUL) // past "default" or group name 3445*f9cc9f20SBram Moolenaar { 3446*f9cc9f20SBram Moolenaar include_default = 0; 3447*f9cc9f20SBram Moolenaar if (STRNCMP("default", arg, p - arg) == 0) 3448*f9cc9f20SBram Moolenaar { 3449*f9cc9f20SBram Moolenaar arg = skipwhite(p); 3450*f9cc9f20SBram Moolenaar xp->xp_pattern = arg; 3451*f9cc9f20SBram Moolenaar p = skiptowhite(arg); 3452*f9cc9f20SBram Moolenaar } 3453*f9cc9f20SBram Moolenaar if (*p != NUL) // past group name 3454*f9cc9f20SBram Moolenaar { 3455*f9cc9f20SBram Moolenaar include_link = 0; 3456*f9cc9f20SBram Moolenaar if (arg[1] == 'i' && arg[0] == 'N') 3457*f9cc9f20SBram Moolenaar highlight_list(); 3458*f9cc9f20SBram Moolenaar if (STRNCMP("link", arg, p - arg) == 0 3459*f9cc9f20SBram Moolenaar || STRNCMP("clear", arg, p - arg) == 0) 3460*f9cc9f20SBram Moolenaar { 3461*f9cc9f20SBram Moolenaar xp->xp_pattern = skipwhite(p); 3462*f9cc9f20SBram Moolenaar p = skiptowhite(xp->xp_pattern); 3463*f9cc9f20SBram Moolenaar if (*p != NUL) // past first group name 3464*f9cc9f20SBram Moolenaar { 3465*f9cc9f20SBram Moolenaar xp->xp_pattern = skipwhite(p); 3466*f9cc9f20SBram Moolenaar p = skiptowhite(xp->xp_pattern); 3467*f9cc9f20SBram Moolenaar } 3468*f9cc9f20SBram Moolenaar } 3469*f9cc9f20SBram Moolenaar if (*p != NUL) // past group name(s) 3470*f9cc9f20SBram Moolenaar xp->xp_context = EXPAND_NOTHING; 3471*f9cc9f20SBram Moolenaar } 3472*f9cc9f20SBram Moolenaar } 3473*f9cc9f20SBram Moolenaar } 3474*f9cc9f20SBram Moolenaar } 3475*f9cc9f20SBram Moolenaar 3476*f9cc9f20SBram Moolenaar /* 3477*f9cc9f20SBram Moolenaar * List highlighting matches in a nice way. 3478*f9cc9f20SBram Moolenaar */ 3479*f9cc9f20SBram Moolenaar static void 3480*f9cc9f20SBram Moolenaar highlight_list(void) 3481*f9cc9f20SBram Moolenaar { 3482*f9cc9f20SBram Moolenaar int i; 3483*f9cc9f20SBram Moolenaar 3484*f9cc9f20SBram Moolenaar for (i = 10; --i >= 0; ) 3485*f9cc9f20SBram Moolenaar highlight_list_two(i, HL_ATTR(HLF_D)); 3486*f9cc9f20SBram Moolenaar for (i = 40; --i >= 0; ) 3487*f9cc9f20SBram Moolenaar highlight_list_two(99, 0); 3488*f9cc9f20SBram Moolenaar } 3489*f9cc9f20SBram Moolenaar 3490*f9cc9f20SBram Moolenaar static void 3491*f9cc9f20SBram Moolenaar highlight_list_two(int cnt, int attr) 3492*f9cc9f20SBram Moolenaar { 3493*f9cc9f20SBram Moolenaar msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr); 3494*f9cc9f20SBram Moolenaar msg_clr_eos(); 3495*f9cc9f20SBram Moolenaar out_flush(); 3496*f9cc9f20SBram Moolenaar ui_delay(cnt == 99 ? 40L : (long)cnt * 50L, FALSE); 3497*f9cc9f20SBram Moolenaar } 3498*f9cc9f20SBram Moolenaar 3499*f9cc9f20SBram Moolenaar #endif // FEAT_CMDL_COMPL 3500*f9cc9f20SBram Moolenaar 3501*f9cc9f20SBram Moolenaar #if defined(FEAT_CMDL_COMPL) || (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) \ 3502*f9cc9f20SBram Moolenaar || defined(FEAT_SIGNS) || defined(PROTO) 3503*f9cc9f20SBram Moolenaar /* 3504*f9cc9f20SBram Moolenaar * Function given to ExpandGeneric() to obtain the list of group names. 3505*f9cc9f20SBram Moolenaar */ 3506*f9cc9f20SBram Moolenaar char_u * 3507*f9cc9f20SBram Moolenaar get_highlight_name(expand_T *xp UNUSED, int idx) 3508*f9cc9f20SBram Moolenaar { 3509*f9cc9f20SBram Moolenaar return get_highlight_name_ext(xp, idx, TRUE); 3510*f9cc9f20SBram Moolenaar } 3511*f9cc9f20SBram Moolenaar 3512*f9cc9f20SBram Moolenaar /* 3513*f9cc9f20SBram Moolenaar * Obtain a highlight group name. 3514*f9cc9f20SBram Moolenaar * When "skip_cleared" is TRUE don't return a cleared entry. 3515*f9cc9f20SBram Moolenaar */ 3516*f9cc9f20SBram Moolenaar char_u * 3517*f9cc9f20SBram Moolenaar get_highlight_name_ext(expand_T *xp UNUSED, int idx, int skip_cleared) 3518*f9cc9f20SBram Moolenaar { 3519*f9cc9f20SBram Moolenaar if (idx < 0) 3520*f9cc9f20SBram Moolenaar return NULL; 3521*f9cc9f20SBram Moolenaar 3522*f9cc9f20SBram Moolenaar // Items are never removed from the table, skip the ones that were 3523*f9cc9f20SBram Moolenaar // cleared. 3524*f9cc9f20SBram Moolenaar if (skip_cleared && idx < highlight_ga.ga_len && HL_TABLE()[idx].sg_cleared) 3525*f9cc9f20SBram Moolenaar return (char_u *)""; 3526*f9cc9f20SBram Moolenaar 3527*f9cc9f20SBram Moolenaar #ifdef FEAT_CMDL_COMPL 3528*f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len && include_none != 0) 3529*f9cc9f20SBram Moolenaar return (char_u *)"none"; 3530*f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none && include_default != 0) 3531*f9cc9f20SBram Moolenaar return (char_u *)"default"; 3532*f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none + include_default 3533*f9cc9f20SBram Moolenaar && include_link != 0) 3534*f9cc9f20SBram Moolenaar return (char_u *)"link"; 3535*f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none + include_default + 1 3536*f9cc9f20SBram Moolenaar && include_link != 0) 3537*f9cc9f20SBram Moolenaar return (char_u *)"clear"; 3538*f9cc9f20SBram Moolenaar #endif 3539*f9cc9f20SBram Moolenaar if (idx >= highlight_ga.ga_len) 3540*f9cc9f20SBram Moolenaar return NULL; 3541*f9cc9f20SBram Moolenaar return HL_TABLE()[idx].sg_name; 3542*f9cc9f20SBram Moolenaar } 3543*f9cc9f20SBram Moolenaar #endif 3544*f9cc9f20SBram Moolenaar 3545*f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(PROTO) 3546*f9cc9f20SBram Moolenaar /* 3547*f9cc9f20SBram Moolenaar * Free all the highlight group fonts. 3548*f9cc9f20SBram Moolenaar * Used when quitting for systems which need it. 3549*f9cc9f20SBram Moolenaar */ 3550*f9cc9f20SBram Moolenaar void 3551*f9cc9f20SBram Moolenaar free_highlight_fonts(void) 3552*f9cc9f20SBram Moolenaar { 3553*f9cc9f20SBram Moolenaar int idx; 3554*f9cc9f20SBram Moolenaar 3555*f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx) 3556*f9cc9f20SBram Moolenaar { 3557*f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font); 3558*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT; 3559*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 3560*f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); 3561*f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET; 3562*f9cc9f20SBram Moolenaar # endif 3563*f9cc9f20SBram Moolenaar } 3564*f9cc9f20SBram Moolenaar 3565*f9cc9f20SBram Moolenaar gui_mch_free_font(gui.norm_font); 3566*f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 3567*f9cc9f20SBram Moolenaar gui_mch_free_fontset(gui.fontset); 3568*f9cc9f20SBram Moolenaar # endif 3569*f9cc9f20SBram Moolenaar # ifndef FEAT_GUI_GTK 3570*f9cc9f20SBram Moolenaar gui_mch_free_font(gui.bold_font); 3571*f9cc9f20SBram Moolenaar gui_mch_free_font(gui.ital_font); 3572*f9cc9f20SBram Moolenaar gui_mch_free_font(gui.boldital_font); 3573*f9cc9f20SBram Moolenaar # endif 3574*f9cc9f20SBram Moolenaar } 3575*f9cc9f20SBram Moolenaar #endif 3576