1f9cc9f20SBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet:
2f9cc9f20SBram Moolenaar *
3f9cc9f20SBram Moolenaar * VIM - Vi IMproved by Bram Moolenaar
4f9cc9f20SBram Moolenaar *
5f9cc9f20SBram Moolenaar * Do ":help uganda" in Vim to read copying and usage conditions.
6f9cc9f20SBram Moolenaar * Do ":help credits" in Vim to see a list of people who contributed.
7f9cc9f20SBram Moolenaar * See README.txt for an overview of the Vim source code.
8f9cc9f20SBram Moolenaar */
9f9cc9f20SBram Moolenaar
10f9cc9f20SBram Moolenaar /*
1129b7d7a9SBram Moolenaar * Highlighting stuff.
12f9cc9f20SBram Moolenaar */
13f9cc9f20SBram Moolenaar
14f9cc9f20SBram Moolenaar #include "vim.h"
15f9cc9f20SBram Moolenaar
16f9cc9f20SBram Moolenaar #define SG_TERM 1 // term has been set
17f9cc9f20SBram Moolenaar #define SG_CTERM 2 // cterm has been set
18f9cc9f20SBram Moolenaar #define SG_GUI 4 // gui has been set
19f9cc9f20SBram Moolenaar #define SG_LINK 8 // link has been set
20f9cc9f20SBram Moolenaar
21f9cc9f20SBram Moolenaar /*
22f9cc9f20SBram Moolenaar * The "term", "cterm" and "gui" arguments can be any combination of the
23f9cc9f20SBram Moolenaar * following names, separated by commas (but no spaces!).
24f9cc9f20SBram Moolenaar */
25f9cc9f20SBram Moolenaar static char *(hl_name_table[]) =
26f9cc9f20SBram Moolenaar {"bold", "standout", "underline", "undercurl",
27f9cc9f20SBram Moolenaar "italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"};
28f9cc9f20SBram Moolenaar static int hl_attr_table[] =
29f9cc9f20SBram Moolenaar {HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0};
30f9cc9f20SBram Moolenaar #define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? attr_b : (attr_a)) | (attr_b))
31f9cc9f20SBram Moolenaar
322ac6e82aSBram Moolenaar /*
332ac6e82aSBram Moolenaar * Structure that stores information about a highlight group.
342ac6e82aSBram Moolenaar * The ID of a highlight group is also called group ID. It is the index in
352ac6e82aSBram Moolenaar * the highlight_ga array PLUS ONE.
362ac6e82aSBram Moolenaar */
372ac6e82aSBram Moolenaar typedef struct
382ac6e82aSBram Moolenaar {
392ac6e82aSBram Moolenaar char_u *sg_name; // highlight group name
402ac6e82aSBram Moolenaar char_u *sg_name_u; // uppercase of sg_name
412ac6e82aSBram Moolenaar int sg_cleared; // "hi clear" was used
422ac6e82aSBram Moolenaar // for normal terminals
432ac6e82aSBram Moolenaar int sg_term; // "term=" highlighting attributes
442ac6e82aSBram Moolenaar char_u *sg_start; // terminal string for start highl
452ac6e82aSBram Moolenaar char_u *sg_stop; // terminal string for stop highl
462ac6e82aSBram Moolenaar int sg_term_attr; // Screen attr for term mode
472ac6e82aSBram Moolenaar // for color terminals
482ac6e82aSBram Moolenaar int sg_cterm; // "cterm=" highlighting attr
492ac6e82aSBram Moolenaar int sg_cterm_bold; // bold attr was set for light color
502ac6e82aSBram Moolenaar int sg_cterm_fg; // terminal fg color number + 1
512ac6e82aSBram Moolenaar int sg_cterm_bg; // terminal bg color number + 1
52e023e88bSBram Moolenaar int sg_cterm_ul; // terminal ul color number + 1
532ac6e82aSBram Moolenaar int sg_cterm_attr; // Screen attr for color term mode
542ac6e82aSBram Moolenaar // for when using the GUI
552ac6e82aSBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
562ac6e82aSBram Moolenaar guicolor_T sg_gui_fg; // GUI foreground color handle
572ac6e82aSBram Moolenaar guicolor_T sg_gui_bg; // GUI background color handle
58e023e88bSBram Moolenaar guicolor_T sg_gui_sp; // GUI special color handle
592ac6e82aSBram Moolenaar #endif
602ac6e82aSBram Moolenaar #ifdef FEAT_GUI
612ac6e82aSBram Moolenaar GuiFont sg_font; // GUI font handle
622ac6e82aSBram Moolenaar #ifdef FEAT_XFONTSET
632ac6e82aSBram Moolenaar GuiFontset sg_fontset; // GUI fontset handle
642ac6e82aSBram Moolenaar #endif
652ac6e82aSBram Moolenaar char_u *sg_font_name; // GUI font or fontset name
662ac6e82aSBram Moolenaar int sg_gui_attr; // Screen attr for GUI mode
672ac6e82aSBram Moolenaar #endif
682ac6e82aSBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL)
692ac6e82aSBram Moolenaar // Store the sp color name for the GUI or synIDattr()
702ac6e82aSBram Moolenaar int sg_gui; // "gui=" highlighting attributes
712ac6e82aSBram Moolenaar char_u *sg_gui_fg_name;// GUI foreground color name
722ac6e82aSBram Moolenaar char_u *sg_gui_bg_name;// GUI background color name
732ac6e82aSBram Moolenaar char_u *sg_gui_sp_name;// GUI special color name
742ac6e82aSBram Moolenaar #endif
752ac6e82aSBram Moolenaar int sg_link; // link to this highlight group ID
76213da551SBram Moolenaar int sg_deflink; // default link; restored in highlight_clear()
772ac6e82aSBram Moolenaar int sg_set; // combination of SG_* flags
782ac6e82aSBram Moolenaar #ifdef FEAT_EVAL
79e8df0104SBram Moolenaar sctx_T sg_deflink_sctx; // script where the default link was set
802ac6e82aSBram Moolenaar sctx_T sg_script_ctx; // script in which the group was last set
812ac6e82aSBram Moolenaar #endif
822ac6e82aSBram Moolenaar } hl_group_T;
832ac6e82aSBram Moolenaar
842ac6e82aSBram Moolenaar // highlight groups for 'highlight' option
852ac6e82aSBram Moolenaar static garray_T highlight_ga;
862ac6e82aSBram Moolenaar #define HL_TABLE() ((hl_group_T *)((highlight_ga.ga_data)))
872ac6e82aSBram Moolenaar
882ac6e82aSBram Moolenaar /*
892ac6e82aSBram Moolenaar * An attribute number is the index in attr_table plus ATTR_OFF.
902ac6e82aSBram Moolenaar */
912ac6e82aSBram Moolenaar #define ATTR_OFF (HL_ALL + 1)
922ac6e82aSBram Moolenaar
93f9cc9f20SBram Moolenaar static void syn_unadd_group(void);
94f9cc9f20SBram Moolenaar static void set_hl_attr(int idx);
95f9cc9f20SBram Moolenaar static void highlight_list_one(int id);
96f9cc9f20SBram Moolenaar static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name);
97f9cc9f20SBram Moolenaar static int syn_add_group(char_u *name);
98f9cc9f20SBram Moolenaar static int hl_has_settings(int idx, int check_link);
99f9cc9f20SBram Moolenaar static void highlight_clear(int idx);
100f9cc9f20SBram Moolenaar
101f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
102f9cc9f20SBram Moolenaar static void gui_do_one_color(int idx, int do_menu, int do_tooltip);
103f9cc9f20SBram Moolenaar #endif
104f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
105f9cc9f20SBram Moolenaar static int set_group_colors(char_u *name, guicolor_T *fgp, guicolor_T *bgp, int do_menu, int use_norm, int do_tooltip);
106f9cc9f20SBram Moolenaar static void hl_do_font(int idx, char_u *arg, int do_normal, int do_menu, int do_tooltip, int free_font);
107f9cc9f20SBram Moolenaar #endif
108f9cc9f20SBram Moolenaar
109f9cc9f20SBram Moolenaar /*
110f9cc9f20SBram Moolenaar * The default highlight groups. These are compiled-in for fast startup and
111f9cc9f20SBram Moolenaar * they still work when the runtime files can't be found.
112f9cc9f20SBram Moolenaar * When making changes here, also change runtime/colors/default.vim!
113f9cc9f20SBram Moolenaar * The #ifdefs are needed to reduce the amount of static data. Helps to make
114f9cc9f20SBram Moolenaar * the 16 bit DOS (museum) version compile.
115f9cc9f20SBram Moolenaar */
116f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL)
117f9cc9f20SBram Moolenaar # define CENT(a, b) b
118f9cc9f20SBram Moolenaar #else
119f9cc9f20SBram Moolenaar # define CENT(a, b) a
120f9cc9f20SBram Moolenaar #endif
121f9cc9f20SBram Moolenaar static char *(highlight_init_both[]) = {
122f9cc9f20SBram Moolenaar CENT("ErrorMsg term=standout ctermbg=DarkRed ctermfg=White",
123f9cc9f20SBram Moolenaar "ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White"),
124f9cc9f20SBram Moolenaar CENT("IncSearch term=reverse cterm=reverse",
125f9cc9f20SBram Moolenaar "IncSearch term=reverse cterm=reverse gui=reverse"),
126f9cc9f20SBram Moolenaar CENT("ModeMsg term=bold cterm=bold",
127f9cc9f20SBram Moolenaar "ModeMsg term=bold cterm=bold gui=bold"),
128f9cc9f20SBram Moolenaar CENT("NonText term=bold ctermfg=Blue",
129f9cc9f20SBram Moolenaar "NonText term=bold ctermfg=Blue gui=bold guifg=Blue"),
130f9cc9f20SBram Moolenaar CENT("StatusLine term=reverse,bold cterm=reverse,bold",
131f9cc9f20SBram Moolenaar "StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold"),
132f9cc9f20SBram Moolenaar CENT("StatusLineNC term=reverse cterm=reverse",
133f9cc9f20SBram Moolenaar "StatusLineNC term=reverse cterm=reverse gui=reverse"),
134f9cc9f20SBram Moolenaar "default link EndOfBuffer NonText",
135f9cc9f20SBram Moolenaar CENT("VertSplit term=reverse cterm=reverse",
136f9cc9f20SBram Moolenaar "VertSplit term=reverse cterm=reverse gui=reverse"),
137f9cc9f20SBram Moolenaar #ifdef FEAT_CLIPBOARD
138f9cc9f20SBram Moolenaar CENT("VisualNOS term=underline,bold cterm=underline,bold",
139f9cc9f20SBram Moolenaar "VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold"),
140f9cc9f20SBram Moolenaar #endif
141f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF
142f9cc9f20SBram Moolenaar CENT("DiffText term=reverse cterm=bold ctermbg=Red",
143f9cc9f20SBram Moolenaar "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red"),
144f9cc9f20SBram Moolenaar #endif
145f9cc9f20SBram Moolenaar CENT("PmenuSbar ctermbg=Grey",
146f9cc9f20SBram Moolenaar "PmenuSbar ctermbg=Grey guibg=Grey"),
147f9cc9f20SBram Moolenaar CENT("TabLineSel term=bold cterm=bold",
148f9cc9f20SBram Moolenaar "TabLineSel term=bold cterm=bold gui=bold"),
149f9cc9f20SBram Moolenaar CENT("TabLineFill term=reverse cterm=reverse",
150f9cc9f20SBram Moolenaar "TabLineFill term=reverse cterm=reverse gui=reverse"),
151f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
152f9cc9f20SBram Moolenaar "Cursor guibg=fg guifg=bg",
153f9cc9f20SBram Moolenaar "lCursor guibg=fg guifg=bg", // should be different, but what?
154f9cc9f20SBram Moolenaar #endif
155f9cc9f20SBram Moolenaar "default link QuickFixLine Search",
156f9cc9f20SBram Moolenaar CENT("Normal cterm=NONE", "Normal gui=NONE"),
157f9cc9f20SBram Moolenaar NULL
158f9cc9f20SBram Moolenaar };
159f9cc9f20SBram Moolenaar
1601f164b19SBram Moolenaar // Default colors only used with a light background.
161f9cc9f20SBram Moolenaar static char *(highlight_init_light[]) = {
162f9cc9f20SBram Moolenaar CENT("Directory term=bold ctermfg=DarkBlue",
163f9cc9f20SBram Moolenaar "Directory term=bold ctermfg=DarkBlue guifg=Blue"),
164f9cc9f20SBram Moolenaar CENT("LineNr term=underline ctermfg=Brown",
165f9cc9f20SBram Moolenaar "LineNr term=underline ctermfg=Brown guifg=Brown"),
166017ba07fSBram Moolenaar CENT("CursorLineNr term=bold cterm=underline ctermfg=Brown",
167017ba07fSBram Moolenaar "CursorLineNr term=bold cterm=underline ctermfg=Brown gui=bold guifg=Brown"),
168f9cc9f20SBram Moolenaar CENT("MoreMsg term=bold ctermfg=DarkGreen",
169f9cc9f20SBram Moolenaar "MoreMsg term=bold ctermfg=DarkGreen gui=bold guifg=SeaGreen"),
170f9cc9f20SBram Moolenaar CENT("Question term=standout ctermfg=DarkGreen",
171f9cc9f20SBram Moolenaar "Question term=standout ctermfg=DarkGreen gui=bold guifg=SeaGreen"),
172f9cc9f20SBram Moolenaar CENT("Search term=reverse ctermbg=Yellow ctermfg=NONE",
173f9cc9f20SBram Moolenaar "Search term=reverse ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE"),
174f9cc9f20SBram Moolenaar #ifdef FEAT_SPELL
175f9cc9f20SBram Moolenaar CENT("SpellBad term=reverse ctermbg=LightRed",
176f9cc9f20SBram Moolenaar "SpellBad term=reverse ctermbg=LightRed guisp=Red gui=undercurl"),
177f9cc9f20SBram Moolenaar CENT("SpellCap term=reverse ctermbg=LightBlue",
178f9cc9f20SBram Moolenaar "SpellCap term=reverse ctermbg=LightBlue guisp=Blue gui=undercurl"),
179f9cc9f20SBram Moolenaar CENT("SpellRare term=reverse ctermbg=LightMagenta",
180f9cc9f20SBram Moolenaar "SpellRare term=reverse ctermbg=LightMagenta guisp=Magenta gui=undercurl"),
181f9cc9f20SBram Moolenaar CENT("SpellLocal term=underline ctermbg=Cyan",
182f9cc9f20SBram Moolenaar "SpellLocal term=underline ctermbg=Cyan guisp=DarkCyan gui=undercurl"),
183f9cc9f20SBram Moolenaar #endif
184f9cc9f20SBram Moolenaar CENT("PmenuThumb ctermbg=Black",
185f9cc9f20SBram Moolenaar "PmenuThumb ctermbg=Black guibg=Black"),
186f9cc9f20SBram Moolenaar CENT("Pmenu ctermbg=LightMagenta ctermfg=Black",
187f9cc9f20SBram Moolenaar "Pmenu ctermbg=LightMagenta ctermfg=Black guibg=LightMagenta"),
188f9cc9f20SBram Moolenaar CENT("PmenuSel ctermbg=LightGrey ctermfg=Black",
189f9cc9f20SBram Moolenaar "PmenuSel ctermbg=LightGrey ctermfg=Black guibg=Grey"),
190f9cc9f20SBram Moolenaar CENT("SpecialKey term=bold ctermfg=DarkBlue",
191f9cc9f20SBram Moolenaar "SpecialKey term=bold ctermfg=DarkBlue guifg=Blue"),
192f9cc9f20SBram Moolenaar CENT("Title term=bold ctermfg=DarkMagenta",
193f9cc9f20SBram Moolenaar "Title term=bold ctermfg=DarkMagenta gui=bold guifg=Magenta"),
194f9cc9f20SBram Moolenaar CENT("WarningMsg term=standout ctermfg=DarkRed",
195f9cc9f20SBram Moolenaar "WarningMsg term=standout ctermfg=DarkRed guifg=Red"),
196f9cc9f20SBram Moolenaar #ifdef FEAT_WILDMENU
197f9cc9f20SBram Moolenaar CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black",
198f9cc9f20SBram Moolenaar "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
199f9cc9f20SBram Moolenaar #endif
200f9cc9f20SBram Moolenaar #ifdef FEAT_FOLDING
201f9cc9f20SBram Moolenaar CENT("Folded term=standout ctermbg=Grey ctermfg=DarkBlue",
202f9cc9f20SBram Moolenaar "Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue"),
203f9cc9f20SBram Moolenaar CENT("FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue",
204f9cc9f20SBram Moolenaar "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"),
205f9cc9f20SBram Moolenaar #endif
206f9cc9f20SBram Moolenaar #ifdef FEAT_SIGNS
207f9cc9f20SBram Moolenaar CENT("SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue",
208f9cc9f20SBram Moolenaar "SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"),
209f9cc9f20SBram Moolenaar #endif
210f9cc9f20SBram Moolenaar CENT("Visual term=reverse",
211f9cc9f20SBram Moolenaar "Visual term=reverse guibg=LightGrey"),
212f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF
213f9cc9f20SBram Moolenaar CENT("DiffAdd term=bold ctermbg=LightBlue",
214f9cc9f20SBram Moolenaar "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue"),
215f9cc9f20SBram Moolenaar CENT("DiffChange term=bold ctermbg=LightMagenta",
216f9cc9f20SBram Moolenaar "DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta"),
217f9cc9f20SBram Moolenaar CENT("DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan",
218f9cc9f20SBram Moolenaar "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan"),
219f9cc9f20SBram Moolenaar #endif
220f9cc9f20SBram Moolenaar CENT("TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey",
221f9cc9f20SBram Moolenaar "TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey gui=underline guibg=LightGrey"),
222f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL
223f9cc9f20SBram Moolenaar CENT("CursorColumn term=reverse ctermbg=LightGrey",
224f9cc9f20SBram Moolenaar "CursorColumn term=reverse ctermbg=LightGrey guibg=Grey90"),
225f9cc9f20SBram Moolenaar CENT("CursorLine term=underline cterm=underline",
226f9cc9f20SBram Moolenaar "CursorLine term=underline cterm=underline guibg=Grey90"),
227f9cc9f20SBram Moolenaar CENT("ColorColumn term=reverse ctermbg=LightRed",
228f9cc9f20SBram Moolenaar "ColorColumn term=reverse ctermbg=LightRed guibg=LightRed"),
229f9cc9f20SBram Moolenaar #endif
230f9cc9f20SBram Moolenaar #ifdef FEAT_CONCEAL
231f9cc9f20SBram Moolenaar CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey",
232f9cc9f20SBram Moolenaar "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"),
233f9cc9f20SBram Moolenaar #endif
234f9cc9f20SBram Moolenaar CENT("MatchParen term=reverse ctermbg=Cyan",
235f9cc9f20SBram Moolenaar "MatchParen term=reverse ctermbg=Cyan guibg=Cyan"),
236f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL
237f9cc9f20SBram Moolenaar CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen",
238f9cc9f20SBram Moolenaar "StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen gui=bold guifg=bg guibg=DarkGreen"),
239f9cc9f20SBram Moolenaar CENT("StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen",
240f9cc9f20SBram Moolenaar "StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen guifg=bg guibg=DarkGreen"),
241f9cc9f20SBram Moolenaar #endif
242f9cc9f20SBram Moolenaar #ifdef FEAT_MENU
243f9cc9f20SBram Moolenaar CENT("ToolbarLine term=underline ctermbg=LightGrey",
244f9cc9f20SBram Moolenaar "ToolbarLine term=underline ctermbg=LightGrey guibg=LightGrey"),
245f9cc9f20SBram Moolenaar CENT("ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey",
246f9cc9f20SBram Moolenaar "ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey gui=bold guifg=White guibg=Grey40"),
247f9cc9f20SBram Moolenaar #endif
248f9cc9f20SBram Moolenaar NULL
249f9cc9f20SBram Moolenaar };
250f9cc9f20SBram Moolenaar
2511f164b19SBram Moolenaar // Default colors only used with a dark background.
252f9cc9f20SBram Moolenaar static char *(highlight_init_dark[]) = {
253f9cc9f20SBram Moolenaar CENT("Directory term=bold ctermfg=LightCyan",
254f9cc9f20SBram Moolenaar "Directory term=bold ctermfg=LightCyan guifg=Cyan"),
255f9cc9f20SBram Moolenaar CENT("LineNr term=underline ctermfg=Yellow",
256f9cc9f20SBram Moolenaar "LineNr term=underline ctermfg=Yellow guifg=Yellow"),
257017ba07fSBram Moolenaar CENT("CursorLineNr term=bold cterm=underline ctermfg=Yellow",
258017ba07fSBram Moolenaar "CursorLineNr term=bold cterm=underline ctermfg=Yellow gui=bold guifg=Yellow"),
259f9cc9f20SBram Moolenaar CENT("MoreMsg term=bold ctermfg=LightGreen",
260f9cc9f20SBram Moolenaar "MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen"),
261f9cc9f20SBram Moolenaar CENT("Question term=standout ctermfg=LightGreen",
262f9cc9f20SBram Moolenaar "Question term=standout ctermfg=LightGreen gui=bold guifg=Green"),
263f9cc9f20SBram Moolenaar CENT("Search term=reverse ctermbg=Yellow ctermfg=Black",
264f9cc9f20SBram Moolenaar "Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
265f9cc9f20SBram Moolenaar CENT("SpecialKey term=bold ctermfg=LightBlue",
266f9cc9f20SBram Moolenaar "SpecialKey term=bold ctermfg=LightBlue guifg=Cyan"),
267f9cc9f20SBram Moolenaar #ifdef FEAT_SPELL
268f9cc9f20SBram Moolenaar CENT("SpellBad term=reverse ctermbg=Red",
269f9cc9f20SBram Moolenaar "SpellBad term=reverse ctermbg=Red guisp=Red gui=undercurl"),
270f9cc9f20SBram Moolenaar CENT("SpellCap term=reverse ctermbg=Blue",
271f9cc9f20SBram Moolenaar "SpellCap term=reverse ctermbg=Blue guisp=Blue gui=undercurl"),
272f9cc9f20SBram Moolenaar CENT("SpellRare term=reverse ctermbg=Magenta",
273f9cc9f20SBram Moolenaar "SpellRare term=reverse ctermbg=Magenta guisp=Magenta gui=undercurl"),
274f9cc9f20SBram Moolenaar CENT("SpellLocal term=underline ctermbg=Cyan",
275f9cc9f20SBram Moolenaar "SpellLocal term=underline ctermbg=Cyan guisp=Cyan gui=undercurl"),
276f9cc9f20SBram Moolenaar #endif
277f9cc9f20SBram Moolenaar CENT("PmenuThumb ctermbg=White",
278f9cc9f20SBram Moolenaar "PmenuThumb ctermbg=White guibg=White"),
279f9cc9f20SBram Moolenaar CENT("Pmenu ctermbg=Magenta ctermfg=Black",
280f9cc9f20SBram Moolenaar "Pmenu ctermbg=Magenta ctermfg=Black guibg=Magenta"),
281f9cc9f20SBram Moolenaar CENT("PmenuSel ctermbg=Black ctermfg=DarkGrey",
282f9cc9f20SBram Moolenaar "PmenuSel ctermbg=Black ctermfg=DarkGrey guibg=DarkGrey"),
283f9cc9f20SBram Moolenaar CENT("Title term=bold ctermfg=LightMagenta",
284f9cc9f20SBram Moolenaar "Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta"),
285f9cc9f20SBram Moolenaar CENT("WarningMsg term=standout ctermfg=LightRed",
286f9cc9f20SBram Moolenaar "WarningMsg term=standout ctermfg=LightRed guifg=Red"),
287f9cc9f20SBram Moolenaar #ifdef FEAT_WILDMENU
288f9cc9f20SBram Moolenaar CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black",
289f9cc9f20SBram Moolenaar "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"),
290f9cc9f20SBram Moolenaar #endif
291f9cc9f20SBram Moolenaar #ifdef FEAT_FOLDING
292f9cc9f20SBram Moolenaar CENT("Folded term=standout ctermbg=DarkGrey ctermfg=Cyan",
293f9cc9f20SBram Moolenaar "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan"),
294f9cc9f20SBram Moolenaar CENT("FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan",
295f9cc9f20SBram Moolenaar "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"),
296f9cc9f20SBram Moolenaar #endif
297f9cc9f20SBram Moolenaar #ifdef FEAT_SIGNS
298f9cc9f20SBram Moolenaar CENT("SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan",
299f9cc9f20SBram Moolenaar "SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"),
300f9cc9f20SBram Moolenaar #endif
301f9cc9f20SBram Moolenaar CENT("Visual term=reverse",
302f9cc9f20SBram Moolenaar "Visual term=reverse guibg=DarkGrey"),
303f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF
304f9cc9f20SBram Moolenaar CENT("DiffAdd term=bold ctermbg=DarkBlue",
305f9cc9f20SBram Moolenaar "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue"),
306f9cc9f20SBram Moolenaar CENT("DiffChange term=bold ctermbg=DarkMagenta",
307f9cc9f20SBram Moolenaar "DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta"),
308f9cc9f20SBram Moolenaar CENT("DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan",
309f9cc9f20SBram Moolenaar "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan"),
310f9cc9f20SBram Moolenaar #endif
311f9cc9f20SBram Moolenaar CENT("TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey",
312f9cc9f20SBram Moolenaar "TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey gui=underline guibg=DarkGrey"),
313f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL
314f9cc9f20SBram Moolenaar CENT("CursorColumn term=reverse ctermbg=DarkGrey",
315f9cc9f20SBram Moolenaar "CursorColumn term=reverse ctermbg=DarkGrey guibg=Grey40"),
316f9cc9f20SBram Moolenaar CENT("CursorLine term=underline cterm=underline",
317f9cc9f20SBram Moolenaar "CursorLine term=underline cterm=underline guibg=Grey40"),
318f9cc9f20SBram Moolenaar CENT("ColorColumn term=reverse ctermbg=DarkRed",
319f9cc9f20SBram Moolenaar "ColorColumn term=reverse ctermbg=DarkRed guibg=DarkRed"),
320f9cc9f20SBram Moolenaar #endif
321f9cc9f20SBram Moolenaar CENT("MatchParen term=reverse ctermbg=DarkCyan",
322f9cc9f20SBram Moolenaar "MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan"),
323f9cc9f20SBram Moolenaar #ifdef FEAT_CONCEAL
324f9cc9f20SBram Moolenaar CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey",
325f9cc9f20SBram Moolenaar "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"),
326f9cc9f20SBram Moolenaar #endif
327f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL
328f9cc9f20SBram Moolenaar CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen",
329f9cc9f20SBram Moolenaar "StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen gui=bold guifg=bg guibg=LightGreen"),
330f9cc9f20SBram Moolenaar CENT("StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen",
331f9cc9f20SBram Moolenaar "StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen guifg=bg guibg=LightGreen"),
332f9cc9f20SBram Moolenaar #endif
333f9cc9f20SBram Moolenaar #ifdef FEAT_MENU
334f9cc9f20SBram Moolenaar CENT("ToolbarLine term=underline ctermbg=DarkGrey",
335f9cc9f20SBram Moolenaar "ToolbarLine term=underline ctermbg=DarkGrey guibg=Grey50"),
336f9cc9f20SBram Moolenaar CENT("ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey",
337f9cc9f20SBram Moolenaar "ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey gui=bold guifg=Black guibg=LightGrey"),
338f9cc9f20SBram Moolenaar #endif
339f9cc9f20SBram Moolenaar NULL
340f9cc9f20SBram Moolenaar };
341f9cc9f20SBram Moolenaar
3422ac6e82aSBram Moolenaar /*
3432ac6e82aSBram Moolenaar * Returns the number of highlight groups.
3442ac6e82aSBram Moolenaar */
3452ac6e82aSBram Moolenaar int
highlight_num_groups(void)3462ac6e82aSBram Moolenaar highlight_num_groups(void)
3472ac6e82aSBram Moolenaar {
3482ac6e82aSBram Moolenaar return highlight_ga.ga_len;
3492ac6e82aSBram Moolenaar }
3502ac6e82aSBram Moolenaar
3512ac6e82aSBram Moolenaar /*
3522ac6e82aSBram Moolenaar * Returns the name of a highlight group.
3532ac6e82aSBram Moolenaar */
3542ac6e82aSBram Moolenaar char_u *
highlight_group_name(int id)3552ac6e82aSBram Moolenaar highlight_group_name(int id)
3562ac6e82aSBram Moolenaar {
3572ac6e82aSBram Moolenaar return HL_TABLE()[id].sg_name;
3582ac6e82aSBram Moolenaar }
3592ac6e82aSBram Moolenaar
3602ac6e82aSBram Moolenaar /*
3612ac6e82aSBram Moolenaar * Returns the ID of the link to a highlight group.
3622ac6e82aSBram Moolenaar */
3632ac6e82aSBram Moolenaar int
highlight_link_id(int id)3642ac6e82aSBram Moolenaar highlight_link_id(int id)
3652ac6e82aSBram Moolenaar {
3662ac6e82aSBram Moolenaar return HL_TABLE()[id].sg_link;
3672ac6e82aSBram Moolenaar }
3682ac6e82aSBram Moolenaar
369f9cc9f20SBram Moolenaar void
init_highlight(int both,int reset)370f9cc9f20SBram Moolenaar init_highlight(
371f9cc9f20SBram Moolenaar int both, // include groups where 'bg' doesn't matter
372f9cc9f20SBram Moolenaar int reset) // clear group first
373f9cc9f20SBram Moolenaar {
374f9cc9f20SBram Moolenaar int i;
375f9cc9f20SBram Moolenaar char **pp;
376f9cc9f20SBram Moolenaar static int had_both = FALSE;
377f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL
378f9cc9f20SBram Moolenaar char_u *p;
379f9cc9f20SBram Moolenaar
380ad6b90c3SYegappan Lakshmanan // Try finding the color scheme file. Used when a color file was loaded
381ad6b90c3SYegappan Lakshmanan // and 'background' or 't_Co' is changed.
382f9cc9f20SBram Moolenaar p = get_var_value((char_u *)"g:colors_name");
383f9cc9f20SBram Moolenaar if (p != NULL)
384f9cc9f20SBram Moolenaar {
385f9cc9f20SBram Moolenaar // The value of g:colors_name could be freed when sourcing the script,
386f9cc9f20SBram Moolenaar // making "p" invalid, so copy it.
387f9cc9f20SBram Moolenaar char_u *copy_p = vim_strsave(p);
388f9cc9f20SBram Moolenaar int r;
389f9cc9f20SBram Moolenaar
390f9cc9f20SBram Moolenaar if (copy_p != NULL)
391f9cc9f20SBram Moolenaar {
392f9cc9f20SBram Moolenaar r = load_colors(copy_p);
393f9cc9f20SBram Moolenaar vim_free(copy_p);
394f9cc9f20SBram Moolenaar if (r == OK)
395f9cc9f20SBram Moolenaar return;
396f9cc9f20SBram Moolenaar }
397f9cc9f20SBram Moolenaar }
398f9cc9f20SBram Moolenaar
399f9cc9f20SBram Moolenaar #endif
400f9cc9f20SBram Moolenaar
401ad6b90c3SYegappan Lakshmanan // Didn't use a color file, use the compiled-in colors.
402f9cc9f20SBram Moolenaar if (both)
403f9cc9f20SBram Moolenaar {
404f9cc9f20SBram Moolenaar had_both = TRUE;
405f9cc9f20SBram Moolenaar pp = highlight_init_both;
406f9cc9f20SBram Moolenaar for (i = 0; pp[i] != NULL; ++i)
407f9cc9f20SBram Moolenaar do_highlight((char_u *)pp[i], reset, TRUE);
408f9cc9f20SBram Moolenaar }
409f9cc9f20SBram Moolenaar else if (!had_both)
410f9cc9f20SBram Moolenaar // Don't do anything before the call with both == TRUE from main().
411f9cc9f20SBram Moolenaar // Not everything has been setup then, and that call will overrule
412f9cc9f20SBram Moolenaar // everything anyway.
413f9cc9f20SBram Moolenaar return;
414f9cc9f20SBram Moolenaar
415f9cc9f20SBram Moolenaar if (*p_bg == 'l')
416f9cc9f20SBram Moolenaar pp = highlight_init_light;
417f9cc9f20SBram Moolenaar else
418f9cc9f20SBram Moolenaar pp = highlight_init_dark;
419f9cc9f20SBram Moolenaar for (i = 0; pp[i] != NULL; ++i)
420f9cc9f20SBram Moolenaar do_highlight((char_u *)pp[i], reset, TRUE);
421f9cc9f20SBram Moolenaar
422f9cc9f20SBram Moolenaar // Reverse looks ugly, but grey may not work for 8 colors. Thus let it
423f9cc9f20SBram Moolenaar // depend on the number of colors available.
424f9cc9f20SBram Moolenaar // With 8 colors brown is equal to yellow, need to use black for Search fg
425f9cc9f20SBram Moolenaar // to avoid Statement highlighted text disappears.
426f9cc9f20SBram Moolenaar // Clear the attributes, needed when changing the t_Co value.
427f9cc9f20SBram Moolenaar if (t_colors > 8)
428f9cc9f20SBram Moolenaar do_highlight((char_u *)(*p_bg == 'l'
429f9cc9f20SBram Moolenaar ? "Visual cterm=NONE ctermbg=LightGrey"
430f9cc9f20SBram Moolenaar : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE, TRUE);
431f9cc9f20SBram Moolenaar else
432f9cc9f20SBram Moolenaar {
433f9cc9f20SBram Moolenaar do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE",
434f9cc9f20SBram Moolenaar FALSE, TRUE);
435f9cc9f20SBram Moolenaar if (*p_bg == 'l')
436f9cc9f20SBram Moolenaar do_highlight((char_u *)"Search ctermfg=black", FALSE, TRUE);
437f9cc9f20SBram Moolenaar }
438f9cc9f20SBram Moolenaar
439f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL
440ad6b90c3SYegappan Lakshmanan // If syntax highlighting is enabled load the highlighting for it.
441f9cc9f20SBram Moolenaar if (get_var_value((char_u *)"g:syntax_on") != NULL)
442f9cc9f20SBram Moolenaar {
443f9cc9f20SBram Moolenaar static int recursive = 0;
444f9cc9f20SBram Moolenaar
445f9cc9f20SBram Moolenaar if (recursive >= 5)
446f9cc9f20SBram Moolenaar emsg(_("E679: recursive loop loading syncolor.vim"));
447f9cc9f20SBram Moolenaar else
448f9cc9f20SBram Moolenaar {
449f9cc9f20SBram Moolenaar ++recursive;
450f9cc9f20SBram Moolenaar (void)source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL);
451f9cc9f20SBram Moolenaar --recursive;
452f9cc9f20SBram Moolenaar }
453f9cc9f20SBram Moolenaar }
454f9cc9f20SBram Moolenaar #endif
455f9cc9f20SBram Moolenaar }
456f9cc9f20SBram Moolenaar
457f9cc9f20SBram Moolenaar /*
458f9cc9f20SBram Moolenaar * Load color file "name".
459f9cc9f20SBram Moolenaar * Return OK for success, FAIL for failure.
460f9cc9f20SBram Moolenaar */
461f9cc9f20SBram Moolenaar int
load_colors(char_u * name)462f9cc9f20SBram Moolenaar load_colors(char_u *name)
463f9cc9f20SBram Moolenaar {
464f9cc9f20SBram Moolenaar char_u *buf;
465f9cc9f20SBram Moolenaar int retval = FAIL;
466f9cc9f20SBram Moolenaar static int recursive = FALSE;
467f9cc9f20SBram Moolenaar
468f9cc9f20SBram Moolenaar // When being called recursively, this is probably because setting
469f9cc9f20SBram Moolenaar // 'background' caused the highlighting to be reloaded. This means it is
470f9cc9f20SBram Moolenaar // working, thus we should return OK.
471f9cc9f20SBram Moolenaar if (recursive)
472f9cc9f20SBram Moolenaar return OK;
473f9cc9f20SBram Moolenaar
474f9cc9f20SBram Moolenaar recursive = TRUE;
475f9cc9f20SBram Moolenaar buf = alloc(STRLEN(name) + 12);
476f9cc9f20SBram Moolenaar if (buf != NULL)
477f9cc9f20SBram Moolenaar {
4782a52196bSBram Moolenaar #if defined(FEAT_EVAL) && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS))
479e30d1025SDrew Vogel load_default_colors_lists();
480e30d1025SDrew Vogel #endif
481f9cc9f20SBram Moolenaar apply_autocmds(EVENT_COLORSCHEMEPRE, name,
482f9cc9f20SBram Moolenaar curbuf->b_fname, FALSE, curbuf);
483f9cc9f20SBram Moolenaar sprintf((char *)buf, "colors/%s.vim", name);
484f9cc9f20SBram Moolenaar retval = source_runtime(buf, DIP_START + DIP_OPT);
485f9cc9f20SBram Moolenaar vim_free(buf);
486f9cc9f20SBram Moolenaar apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf);
487f9cc9f20SBram Moolenaar }
488f9cc9f20SBram Moolenaar recursive = FALSE;
489f9cc9f20SBram Moolenaar
490f9cc9f20SBram Moolenaar return retval;
491f9cc9f20SBram Moolenaar }
492f9cc9f20SBram Moolenaar
493f9cc9f20SBram Moolenaar static char *(color_names[28]) = {
494f9cc9f20SBram Moolenaar "Black", "DarkBlue", "DarkGreen", "DarkCyan",
495f9cc9f20SBram Moolenaar "DarkRed", "DarkMagenta", "Brown", "DarkYellow",
496f9cc9f20SBram Moolenaar "Gray", "Grey", "LightGray", "LightGrey",
497f9cc9f20SBram Moolenaar "DarkGray", "DarkGrey",
498f9cc9f20SBram Moolenaar "Blue", "LightBlue", "Green", "LightGreen",
499f9cc9f20SBram Moolenaar "Cyan", "LightCyan", "Red", "LightRed", "Magenta",
500f9cc9f20SBram Moolenaar "LightMagenta", "Yellow", "LightYellow", "White", "NONE"};
501f9cc9f20SBram Moolenaar // indices:
502f9cc9f20SBram Moolenaar // 0, 1, 2, 3,
503f9cc9f20SBram Moolenaar // 4, 5, 6, 7,
504f9cc9f20SBram Moolenaar // 8, 9, 10, 11,
505f9cc9f20SBram Moolenaar // 12, 13,
506f9cc9f20SBram Moolenaar // 14, 15, 16, 17,
507f9cc9f20SBram Moolenaar // 18, 19, 20, 21, 22,
508f9cc9f20SBram Moolenaar // 23, 24, 25, 26, 27
509f9cc9f20SBram Moolenaar static int color_numbers_16[28] = {0, 1, 2, 3,
510f9cc9f20SBram Moolenaar 4, 5, 6, 6,
511f9cc9f20SBram Moolenaar 7, 7, 7, 7,
512f9cc9f20SBram Moolenaar 8, 8,
513f9cc9f20SBram Moolenaar 9, 9, 10, 10,
514f9cc9f20SBram Moolenaar 11, 11, 12, 12, 13,
515f9cc9f20SBram Moolenaar 13, 14, 14, 15, -1};
516f9cc9f20SBram Moolenaar // for xterm with 88 colors...
517f9cc9f20SBram Moolenaar static int color_numbers_88[28] = {0, 4, 2, 6,
518f9cc9f20SBram Moolenaar 1, 5, 32, 72,
519f9cc9f20SBram Moolenaar 84, 84, 7, 7,
520f9cc9f20SBram Moolenaar 82, 82,
521f9cc9f20SBram Moolenaar 12, 43, 10, 61,
522f9cc9f20SBram Moolenaar 14, 63, 9, 74, 13,
523f9cc9f20SBram Moolenaar 75, 11, 78, 15, -1};
524f9cc9f20SBram Moolenaar // for xterm with 256 colors...
525f9cc9f20SBram Moolenaar static int color_numbers_256[28] = {0, 4, 2, 6,
526e93c968fSBram Moolenaar 1, 5, 130, 3,
527f9cc9f20SBram Moolenaar 248, 248, 7, 7,
528f9cc9f20SBram Moolenaar 242, 242,
529f9cc9f20SBram Moolenaar 12, 81, 10, 121,
530f9cc9f20SBram Moolenaar 14, 159, 9, 224, 13,
531f9cc9f20SBram Moolenaar 225, 11, 229, 15, -1};
532f9cc9f20SBram Moolenaar // for terminals with less than 16 colors...
533f9cc9f20SBram Moolenaar static int color_numbers_8[28] = {0, 4, 2, 6,
534f9cc9f20SBram Moolenaar 1, 5, 3, 3,
535f9cc9f20SBram Moolenaar 7, 7, 7, 7,
536f9cc9f20SBram Moolenaar 0+8, 0+8,
537f9cc9f20SBram Moolenaar 4+8, 4+8, 2+8, 2+8,
538f9cc9f20SBram Moolenaar 6+8, 6+8, 1+8, 1+8, 5+8,
539f9cc9f20SBram Moolenaar 5+8, 3+8, 3+8, 7+8, -1};
540f9cc9f20SBram Moolenaar
541f9cc9f20SBram Moolenaar /*
542f9cc9f20SBram Moolenaar * Lookup the "cterm" value to be used for color with index "idx" in
543f9cc9f20SBram Moolenaar * color_names[].
544f9cc9f20SBram Moolenaar * "boldp" will be set to TRUE or FALSE for a foreground color when using 8
545f9cc9f20SBram Moolenaar * colors, otherwise it will be unchanged.
546f9cc9f20SBram Moolenaar */
547f9cc9f20SBram Moolenaar int
lookup_color(int idx,int foreground,int * boldp)548f9cc9f20SBram Moolenaar lookup_color(int idx, int foreground, int *boldp)
549f9cc9f20SBram Moolenaar {
550f9cc9f20SBram Moolenaar int color = color_numbers_16[idx];
551f9cc9f20SBram Moolenaar char_u *p;
552f9cc9f20SBram Moolenaar
553f9cc9f20SBram Moolenaar // Use the _16 table to check if it's a valid color name.
554f9cc9f20SBram Moolenaar if (color < 0)
555f9cc9f20SBram Moolenaar return -1;
556f9cc9f20SBram Moolenaar
557f9cc9f20SBram Moolenaar if (t_colors == 8)
558f9cc9f20SBram Moolenaar {
559f9cc9f20SBram Moolenaar // t_Co is 8: use the 8 colors table
560f9cc9f20SBram Moolenaar #if defined(__QNXNTO__)
561c95e8d64SBram Moolenaar // On qnx, the 8 & 16 color arrays are the same
562c95e8d64SBram Moolenaar if (STRNCMP(T_NAME, "qansi", 5) == 0)
563c95e8d64SBram Moolenaar color = color_numbers_16[idx];
564c95e8d64SBram Moolenaar else
565f9cc9f20SBram Moolenaar #endif
566c95e8d64SBram Moolenaar color = color_numbers_8[idx];
567f9cc9f20SBram Moolenaar if (foreground)
568f9cc9f20SBram Moolenaar {
569f9cc9f20SBram Moolenaar // set/reset bold attribute to get light foreground
570f9cc9f20SBram Moolenaar // colors (on some terminals, e.g. "linux")
571f9cc9f20SBram Moolenaar if (color & 8)
572f9cc9f20SBram Moolenaar *boldp = TRUE;
573f9cc9f20SBram Moolenaar else
574f9cc9f20SBram Moolenaar *boldp = FALSE;
575f9cc9f20SBram Moolenaar }
576f9cc9f20SBram Moolenaar color &= 7; // truncate to 8 colors
577f9cc9f20SBram Moolenaar }
578f9cc9f20SBram Moolenaar else if (t_colors == 16 || t_colors == 88
579f9cc9f20SBram Moolenaar || t_colors >= 256)
580f9cc9f20SBram Moolenaar {
581ad6b90c3SYegappan Lakshmanan // Guess: if the termcap entry ends in 'm', it is
582ad6b90c3SYegappan Lakshmanan // probably an xterm-like terminal. Use the changed
583ad6b90c3SYegappan Lakshmanan // order for colors.
584f9cc9f20SBram Moolenaar if (*T_CAF != NUL)
585f9cc9f20SBram Moolenaar p = T_CAF;
586f9cc9f20SBram Moolenaar else
587f9cc9f20SBram Moolenaar p = T_CSF;
588f9cc9f20SBram Moolenaar if (*p != NUL && (t_colors > 256
589f9cc9f20SBram Moolenaar || *(p + STRLEN(p) - 1) == 'm'))
590f9cc9f20SBram Moolenaar {
591f9cc9f20SBram Moolenaar if (t_colors == 88)
592f9cc9f20SBram Moolenaar color = color_numbers_88[idx];
593f9cc9f20SBram Moolenaar else if (t_colors >= 256)
594f9cc9f20SBram Moolenaar color = color_numbers_256[idx];
595f9cc9f20SBram Moolenaar else
596f9cc9f20SBram Moolenaar color = color_numbers_8[idx];
597f9cc9f20SBram Moolenaar }
598f9cc9f20SBram Moolenaar #ifdef FEAT_TERMRESPONSE
599f9cc9f20SBram Moolenaar if (t_colors >= 256 && color == 15 && is_mac_terminal)
600f9cc9f20SBram Moolenaar // Terminal.app has a bug: 15 is light grey. Use white
601f9cc9f20SBram Moolenaar // from the color cube instead.
602f9cc9f20SBram Moolenaar color = 231;
603f9cc9f20SBram Moolenaar #endif
604f9cc9f20SBram Moolenaar }
605f9cc9f20SBram Moolenaar return color;
606f9cc9f20SBram Moolenaar }
607f9cc9f20SBram Moolenaar
608f9cc9f20SBram Moolenaar /*
609ad6b90c3SYegappan Lakshmanan * Link highlight group 'from_hg' to 'to_hg'.
610ad6b90c3SYegappan Lakshmanan * 'dodefault' is set to TRUE for ":highlight default link".
611ad6b90c3SYegappan Lakshmanan * 'forceit' is set to TRUE for ":higlight! link"
612ad6b90c3SYegappan Lakshmanan * 'init' is set to TRUE when initializing all the highlight groups.
613f9cc9f20SBram Moolenaar */
614ad6b90c3SYegappan Lakshmanan static void
highlight_group_link(char_u * from_hg,int from_len,char_u * to_hg,int to_len,int dodefault,int forceit,int init)615ad6b90c3SYegappan Lakshmanan highlight_group_link(
616ad6b90c3SYegappan Lakshmanan char_u *from_hg,
617ad6b90c3SYegappan Lakshmanan int from_len,
618ad6b90c3SYegappan Lakshmanan char_u *to_hg,
619ad6b90c3SYegappan Lakshmanan int to_len,
620ad6b90c3SYegappan Lakshmanan int dodefault,
621f9cc9f20SBram Moolenaar int forceit,
622ad6b90c3SYegappan Lakshmanan int init)
623f9cc9f20SBram Moolenaar {
624f9cc9f20SBram Moolenaar int from_id;
625f9cc9f20SBram Moolenaar int to_id;
626213da551SBram Moolenaar hl_group_T *hlgroup = NULL;
627f9cc9f20SBram Moolenaar
628ad6b90c3SYegappan Lakshmanan from_id = syn_check_group(from_hg, from_len);
629ad6b90c3SYegappan Lakshmanan if (STRNCMP(to_hg, "NONE", 4) == 0)
630f9cc9f20SBram Moolenaar to_id = 0;
631f9cc9f20SBram Moolenaar else
632ad6b90c3SYegappan Lakshmanan to_id = syn_check_group(to_hg, to_len);
633f9cc9f20SBram Moolenaar
634213da551SBram Moolenaar if (from_id > 0)
635213da551SBram Moolenaar {
636213da551SBram Moolenaar hlgroup = &HL_TABLE()[from_id - 1];
637213da551SBram Moolenaar if (dodefault && (forceit || hlgroup->sg_deflink == 0))
638e8df0104SBram Moolenaar {
639213da551SBram Moolenaar hlgroup->sg_deflink = to_id;
640e8df0104SBram Moolenaar #ifdef FEAT_EVAL
641e8df0104SBram Moolenaar hlgroup->sg_deflink_sctx = current_sctx;
642e8df0104SBram Moolenaar hlgroup->sg_deflink_sctx.sc_lnum += SOURCING_LNUM;
643e8df0104SBram Moolenaar #endif
644e8df0104SBram Moolenaar }
645213da551SBram Moolenaar }
646213da551SBram Moolenaar
647213da551SBram Moolenaar if (from_id > 0 && (!init || hlgroup->sg_set == 0))
648f9cc9f20SBram Moolenaar {
649ad6b90c3SYegappan Lakshmanan // Don't allow a link when there already is some highlighting
650ad6b90c3SYegappan Lakshmanan // for the group, unless '!' is used
651f9cc9f20SBram Moolenaar if (to_id > 0 && !forceit && !init
652f9cc9f20SBram Moolenaar && hl_has_settings(from_id - 1, dodefault))
653f9cc9f20SBram Moolenaar {
6541a47ae32SBram Moolenaar if (SOURCING_NAME == NULL && !dodefault)
655f9cc9f20SBram Moolenaar emsg(_("E414: group has settings, highlight link ignored"));
656f9cc9f20SBram Moolenaar }
657213da551SBram Moolenaar else if (hlgroup->sg_link != to_id
658f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL
659213da551SBram Moolenaar || hlgroup->sg_script_ctx.sc_sid != current_sctx.sc_sid
660f9cc9f20SBram Moolenaar #endif
661213da551SBram Moolenaar || hlgroup->sg_cleared)
662f9cc9f20SBram Moolenaar {
663f9cc9f20SBram Moolenaar if (!init)
664213da551SBram Moolenaar hlgroup->sg_set |= SG_LINK;
665213da551SBram Moolenaar hlgroup->sg_link = to_id;
666f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL
667213da551SBram Moolenaar hlgroup->sg_script_ctx = current_sctx;
668213da551SBram Moolenaar hlgroup->sg_script_ctx.sc_lnum += SOURCING_LNUM;
669f9cc9f20SBram Moolenaar #endif
670213da551SBram Moolenaar hlgroup->sg_cleared = FALSE;
671f9cc9f20SBram Moolenaar redraw_all_later(SOME_VALID);
672f9cc9f20SBram Moolenaar
673f9cc9f20SBram Moolenaar // Only call highlight_changed() once after multiple changes.
674f9cc9f20SBram Moolenaar need_highlight_changed = TRUE;
675f9cc9f20SBram Moolenaar }
676f9cc9f20SBram Moolenaar }
677f9cc9f20SBram Moolenaar
678f9cc9f20SBram Moolenaar }
679f9cc9f20SBram Moolenaar
680f9cc9f20SBram Moolenaar /*
681ad6b90c3SYegappan Lakshmanan * Reset all highlighting to the defaults. Removes all highlighting for the
682ad6b90c3SYegappan Lakshmanan * groups added by the user.
683f9cc9f20SBram Moolenaar */
684ad6b90c3SYegappan Lakshmanan static void
highlight_reset_all(void)685ad6b90c3SYegappan Lakshmanan highlight_reset_all(void)
686f9cc9f20SBram Moolenaar {
687ad6b90c3SYegappan Lakshmanan int idx;
688ad6b90c3SYegappan Lakshmanan
689f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
690f9cc9f20SBram Moolenaar // First, we do not destroy the old values, but allocate the new
691f9cc9f20SBram Moolenaar // ones and update the display. THEN we destroy the old values.
692f9cc9f20SBram Moolenaar // If we destroy the old values first, then the old values
693f9cc9f20SBram Moolenaar // (such as GuiFont's or GuiFontset's) will still be displayed but
694f9cc9f20SBram Moolenaar // invalid because they were free'd.
695f9cc9f20SBram Moolenaar if (gui.in_use)
696f9cc9f20SBram Moolenaar {
697f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP
698f9cc9f20SBram Moolenaar gui_init_tooltip_font();
699f9cc9f20SBram Moolenaar # endif
700f9cc9f20SBram Moolenaar # if defined(FEAT_MENU) && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF))
701f9cc9f20SBram Moolenaar gui_init_menu_font();
702f9cc9f20SBram Moolenaar # endif
703f9cc9f20SBram Moolenaar }
704f9cc9f20SBram Moolenaar # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_X11)
705f9cc9f20SBram Moolenaar gui_mch_def_colors();
706f9cc9f20SBram Moolenaar # endif
707f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11
708f9cc9f20SBram Moolenaar # ifdef FEAT_MENU
709f9cc9f20SBram Moolenaar
710f9cc9f20SBram Moolenaar // This only needs to be done when there is no Menu highlight
711f9cc9f20SBram Moolenaar // group defined by default, which IS currently the case.
712f9cc9f20SBram Moolenaar gui_mch_new_menu_colors();
713f9cc9f20SBram Moolenaar # endif
714f9cc9f20SBram Moolenaar if (gui.in_use)
715f9cc9f20SBram Moolenaar {
716f9cc9f20SBram Moolenaar gui_new_scrollbar_colors();
717f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI
718f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors();
719f9cc9f20SBram Moolenaar # endif
720f9cc9f20SBram Moolenaar # ifdef FEAT_MENU
721f9cc9f20SBram Moolenaar gui_mch_new_menu_font();
722f9cc9f20SBram Moolenaar # endif
723f9cc9f20SBram Moolenaar }
724f9cc9f20SBram Moolenaar # endif
725f9cc9f20SBram Moolenaar
726f9cc9f20SBram Moolenaar // Ok, we're done allocating the new default graphics items.
727f9cc9f20SBram Moolenaar // The screen should already be refreshed at this point.
728f9cc9f20SBram Moolenaar // It is now Ok to clear out the old data.
729f9cc9f20SBram Moolenaar #endif
730f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL
7311966c248SBram Moolenaar do_unlet((char_u *)"g:colors_name", TRUE);
732f9cc9f20SBram Moolenaar #endif
733f9cc9f20SBram Moolenaar restore_cterm_colors();
734f9cc9f20SBram Moolenaar
735ad6b90c3SYegappan Lakshmanan // Clear all default highlight groups and load the defaults.
736f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx)
737f9cc9f20SBram Moolenaar highlight_clear(idx);
738f9cc9f20SBram Moolenaar init_highlight(TRUE, TRUE);
739f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
740f9cc9f20SBram Moolenaar if (USE_24BIT)
741f9cc9f20SBram Moolenaar highlight_gui_started();
742f9cc9f20SBram Moolenaar else
743f9cc9f20SBram Moolenaar #endif
744f9cc9f20SBram Moolenaar highlight_changed();
745f9cc9f20SBram Moolenaar redraw_later_clear();
746f9cc9f20SBram Moolenaar }
747f9cc9f20SBram Moolenaar
748f9cc9f20SBram Moolenaar /*
749ad6b90c3SYegappan Lakshmanan * Set the 'term' or 'cterm' or 'gui' attributes for the highlight group at
750ad6b90c3SYegappan Lakshmanan * index 'idx'.
751ad6b90c3SYegappan Lakshmanan * 'key' is one of 'TERM' or 'CTERM' or 'GUI'
752ad6b90c3SYegappan Lakshmanan * 'arg' is the list of attribute names separated by comma.
753ad6b90c3SYegappan Lakshmanan * 'init' is set to TRUE when initializing all the highlight groups.
754ad6b90c3SYegappan Lakshmanan * Returns TRUE if the attributes are set.
755f9cc9f20SBram Moolenaar */
756ad6b90c3SYegappan Lakshmanan static int
highlight_set_termgui_attr(int idx,char_u * key,char_u * arg,int init)757ad6b90c3SYegappan Lakshmanan highlight_set_termgui_attr(int idx, char_u *key, char_u *arg, int init)
758ad6b90c3SYegappan Lakshmanan {
759ad6b90c3SYegappan Lakshmanan int attr;
760ad6b90c3SYegappan Lakshmanan int off;
761ad6b90c3SYegappan Lakshmanan long i;
762ad6b90c3SYegappan Lakshmanan int len;
763f9cc9f20SBram Moolenaar
764f9cc9f20SBram Moolenaar attr = 0;
765f9cc9f20SBram Moolenaar off = 0;
766f9cc9f20SBram Moolenaar while (arg[off] != NUL)
767f9cc9f20SBram Moolenaar {
768eeec2548SK.Takata for (i = ARRAY_LENGTH(hl_attr_table); --i >= 0; )
769f9cc9f20SBram Moolenaar {
770f9cc9f20SBram Moolenaar len = (int)STRLEN(hl_name_table[i]);
771f9cc9f20SBram Moolenaar if (STRNICMP(arg + off, hl_name_table[i], len) == 0)
772f9cc9f20SBram Moolenaar {
773f9cc9f20SBram Moolenaar attr |= hl_attr_table[i];
774f9cc9f20SBram Moolenaar off += len;
775f9cc9f20SBram Moolenaar break;
776f9cc9f20SBram Moolenaar }
777f9cc9f20SBram Moolenaar }
778f9cc9f20SBram Moolenaar if (i < 0)
779f9cc9f20SBram Moolenaar {
780f9cc9f20SBram Moolenaar semsg(_("E418: Illegal value: %s"), arg);
781ad6b90c3SYegappan Lakshmanan return FALSE;
782f9cc9f20SBram Moolenaar }
783f9cc9f20SBram Moolenaar if (arg[off] == ',') // another one follows
784f9cc9f20SBram Moolenaar ++off;
785f9cc9f20SBram Moolenaar }
786f9cc9f20SBram Moolenaar if (*key == 'T')
787f9cc9f20SBram Moolenaar {
788f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM))
789f9cc9f20SBram Moolenaar {
790f9cc9f20SBram Moolenaar if (!init)
791f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_TERM;
792f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term = attr;
793f9cc9f20SBram Moolenaar }
794f9cc9f20SBram Moolenaar }
795f9cc9f20SBram Moolenaar else if (*key == 'C')
796f9cc9f20SBram Moolenaar {
797f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
798f9cc9f20SBram Moolenaar {
799f9cc9f20SBram Moolenaar if (!init)
800f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_CTERM;
801f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm = attr;
802f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = FALSE;
803f9cc9f20SBram Moolenaar }
804f9cc9f20SBram Moolenaar }
805f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL)
806f9cc9f20SBram Moolenaar else
807f9cc9f20SBram Moolenaar {
808f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
809f9cc9f20SBram Moolenaar {
810f9cc9f20SBram Moolenaar if (!init)
811f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI;
812f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui = attr;
813f9cc9f20SBram Moolenaar }
814f9cc9f20SBram Moolenaar }
815f9cc9f20SBram Moolenaar #endif
816ad6b90c3SYegappan Lakshmanan
817ad6b90c3SYegappan Lakshmanan return TRUE;
818f9cc9f20SBram Moolenaar }
819ad6b90c3SYegappan Lakshmanan
820f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
821ad6b90c3SYegappan Lakshmanan /*
822ad6b90c3SYegappan Lakshmanan * Set the font for the highlight group at 'idx'.
823ad6b90c3SYegappan Lakshmanan * 'arg' is the font name.
824ad6b90c3SYegappan Lakshmanan * Returns TRUE if the font is changed.
825ad6b90c3SYegappan Lakshmanan */
826ad6b90c3SYegappan Lakshmanan static int
highlight_set_font(int idx,char_u * arg,int is_normal_group,int is_menu_group,int is_tooltip_group)827ad6b90c3SYegappan Lakshmanan highlight_set_font(
828ad6b90c3SYegappan Lakshmanan int idx,
829ad6b90c3SYegappan Lakshmanan char_u *arg,
830ad6b90c3SYegappan Lakshmanan int is_normal_group,
831ad6b90c3SYegappan Lakshmanan int is_menu_group,
832ad6b90c3SYegappan Lakshmanan int is_tooltip_group)
833ad6b90c3SYegappan Lakshmanan {
834ad6b90c3SYegappan Lakshmanan int did_change = FALSE;
835ad6b90c3SYegappan Lakshmanan
836ad6b90c3SYegappan Lakshmanan // in non-GUI fonts are simply ignored
837f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font_name != NULL
838f9cc9f20SBram Moolenaar && STRCMP(HL_TABLE()[idx].sg_font_name, arg) == 0)
839f9cc9f20SBram Moolenaar {
840f9cc9f20SBram Moolenaar // Font name didn't change, ignore.
841f9cc9f20SBram Moolenaar }
842f9cc9f20SBram Moolenaar else if (!gui.shell_created)
843f9cc9f20SBram Moolenaar {
844f9cc9f20SBram Moolenaar // GUI not started yet, always accept the name.
845f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name);
846f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
847f9cc9f20SBram Moolenaar did_change = TRUE;
848f9cc9f20SBram Moolenaar }
849f9cc9f20SBram Moolenaar else
850f9cc9f20SBram Moolenaar {
851f9cc9f20SBram Moolenaar GuiFont temp_sg_font = HL_TABLE()[idx].sg_font;
852f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
853f9cc9f20SBram Moolenaar GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset;
854f9cc9f20SBram Moolenaar # endif
855f9cc9f20SBram Moolenaar // First, save the current font/fontset.
856f9cc9f20SBram Moolenaar // Then try to allocate the font/fontset.
857f9cc9f20SBram Moolenaar // If the allocation fails, HL_TABLE()[idx].sg_font OR
858f9cc9f20SBram Moolenaar // sg_fontset will be set to NOFONT or NOFONTSET respectively.
859f9cc9f20SBram Moolenaar
860f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT;
861f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
862f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET;
863f9cc9f20SBram Moolenaar # endif
864f9cc9f20SBram Moolenaar hl_do_font(idx, arg, is_normal_group, is_menu_group,
865f9cc9f20SBram Moolenaar is_tooltip_group, FALSE);
866f9cc9f20SBram Moolenaar
867f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
868f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_fontset != NOFONTSET)
869f9cc9f20SBram Moolenaar {
870f9cc9f20SBram Moolenaar // New fontset was accepted. Free the old one, if there
871f9cc9f20SBram Moolenaar // was one.
872f9cc9f20SBram Moolenaar gui_mch_free_fontset(temp_sg_fontset);
873f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name);
874f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
875f9cc9f20SBram Moolenaar did_change = TRUE;
876f9cc9f20SBram Moolenaar }
877f9cc9f20SBram Moolenaar else
878f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = temp_sg_fontset;
879f9cc9f20SBram Moolenaar # endif
880f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font != NOFONT)
881f9cc9f20SBram Moolenaar {
882f9cc9f20SBram Moolenaar // New font was accepted. Free the old one, if there was
883f9cc9f20SBram Moolenaar // one.
884f9cc9f20SBram Moolenaar gui_mch_free_font(temp_sg_font);
885f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name);
886f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
887f9cc9f20SBram Moolenaar did_change = TRUE;
888f9cc9f20SBram Moolenaar }
889f9cc9f20SBram Moolenaar else
890f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = temp_sg_font;
891f9cc9f20SBram Moolenaar }
892ad6b90c3SYegappan Lakshmanan
893ad6b90c3SYegappan Lakshmanan return did_change;
894ad6b90c3SYegappan Lakshmanan }
895f9cc9f20SBram Moolenaar #endif
896f9cc9f20SBram Moolenaar
897ad6b90c3SYegappan Lakshmanan /*
898ad6b90c3SYegappan Lakshmanan * Set the cterm foreground color for the highlight group at 'idx' to 'color'.
899ad6b90c3SYegappan Lakshmanan * Returns TRUE if the foreground color is set.
900ad6b90c3SYegappan Lakshmanan */
901ad6b90c3SYegappan Lakshmanan static void
highlight_set_ctermfg(int idx,int color,int is_normal_group)902ad6b90c3SYegappan Lakshmanan highlight_set_ctermfg(int idx, int color, int is_normal_group)
903f9cc9f20SBram Moolenaar {
904f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_fg = color + 1;
905f9cc9f20SBram Moolenaar if (is_normal_group)
906f9cc9f20SBram Moolenaar {
907f9cc9f20SBram Moolenaar cterm_normal_fg_color = color + 1;
908f9cc9f20SBram Moolenaar cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD);
909f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
910f9cc9f20SBram Moolenaar // Don't do this if the GUI is used.
911f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting)
912f9cc9f20SBram Moolenaar #endif
913f9cc9f20SBram Moolenaar {
914f9cc9f20SBram Moolenaar must_redraw = CLEAR;
915f9cc9f20SBram Moolenaar if (termcap_active && color >= 0)
916f9cc9f20SBram Moolenaar term_fg_color(color);
917f9cc9f20SBram Moolenaar }
918f9cc9f20SBram Moolenaar }
919f9cc9f20SBram Moolenaar }
920ad6b90c3SYegappan Lakshmanan
921ad6b90c3SYegappan Lakshmanan /*
922ad6b90c3SYegappan Lakshmanan * Set the cterm background color for the highlight group at 'idx' to 'color'.
923ad6b90c3SYegappan Lakshmanan * Returns TRUE if the background color is set.
924ad6b90c3SYegappan Lakshmanan */
925ad6b90c3SYegappan Lakshmanan static void
highlight_set_ctermbg(int idx,int color,int is_normal_group)926ad6b90c3SYegappan Lakshmanan highlight_set_ctermbg(int idx, int color, int is_normal_group)
927f9cc9f20SBram Moolenaar {
928f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bg = color + 1;
929f9cc9f20SBram Moolenaar if (is_normal_group)
930f9cc9f20SBram Moolenaar {
931f9cc9f20SBram Moolenaar cterm_normal_bg_color = color + 1;
932f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
933f9cc9f20SBram Moolenaar // Don't mess with 'background' if the GUI is used.
934f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting)
935f9cc9f20SBram Moolenaar #endif
936f9cc9f20SBram Moolenaar {
937f9cc9f20SBram Moolenaar must_redraw = CLEAR;
938f9cc9f20SBram Moolenaar if (color >= 0)
939f9cc9f20SBram Moolenaar {
940f9cc9f20SBram Moolenaar int dark = -1;
941f9cc9f20SBram Moolenaar
942f9cc9f20SBram Moolenaar if (termcap_active)
943f9cc9f20SBram Moolenaar term_bg_color(color);
944f9cc9f20SBram Moolenaar if (t_colors < 16)
945f9cc9f20SBram Moolenaar dark = (color == 0 || color == 4);
946f9cc9f20SBram Moolenaar // Limit the heuristic to the standard 16 colors
947f9cc9f20SBram Moolenaar else if (color < 16)
948f9cc9f20SBram Moolenaar dark = (color < 7 || color == 8);
949f9cc9f20SBram Moolenaar // Set the 'background' option if the value is
950f9cc9f20SBram Moolenaar // wrong.
951f9cc9f20SBram Moolenaar if (dark != -1
952f9cc9f20SBram Moolenaar && dark != (*p_bg == 'd')
953f9cc9f20SBram Moolenaar && !option_was_set((char_u *)"bg"))
954f9cc9f20SBram Moolenaar {
955f9cc9f20SBram Moolenaar set_option_value((char_u *)"bg", 0L,
956f9cc9f20SBram Moolenaar (char_u *)(dark ? "dark" : "light"), 0);
957f9cc9f20SBram Moolenaar reset_option_was_set((char_u *)"bg");
958f9cc9f20SBram Moolenaar }
959f9cc9f20SBram Moolenaar }
960f9cc9f20SBram Moolenaar }
961f9cc9f20SBram Moolenaar }
962f9cc9f20SBram Moolenaar }
963ad6b90c3SYegappan Lakshmanan
964ad6b90c3SYegappan Lakshmanan /*
965ad6b90c3SYegappan Lakshmanan * Set the cterm underline color for the highlight group at 'idx' to 'color'.
966ad6b90c3SYegappan Lakshmanan * Returns TRUE if the underline color is set.
967ad6b90c3SYegappan Lakshmanan */
968ad6b90c3SYegappan Lakshmanan static void
highlight_set_ctermul(int idx,int color,int is_normal_group)969ad6b90c3SYegappan Lakshmanan highlight_set_ctermul(int idx, int color, int is_normal_group)
970e023e88bSBram Moolenaar {
971e023e88bSBram Moolenaar HL_TABLE()[idx].sg_cterm_ul = color + 1;
972e023e88bSBram Moolenaar if (is_normal_group)
973e023e88bSBram Moolenaar {
974e023e88bSBram Moolenaar cterm_normal_ul_color = color + 1;
975e023e88bSBram Moolenaar #ifdef FEAT_GUI
976e023e88bSBram Moolenaar // Don't do this if the GUI is used.
977e023e88bSBram Moolenaar if (!gui.in_use && !gui.starting)
978e023e88bSBram Moolenaar #endif
979e023e88bSBram Moolenaar {
980e023e88bSBram Moolenaar must_redraw = CLEAR;
981e023e88bSBram Moolenaar if (termcap_active && color >= 0)
982e023e88bSBram Moolenaar term_ul_color(color);
983e023e88bSBram Moolenaar }
984e023e88bSBram Moolenaar }
985e023e88bSBram Moolenaar }
986f9cc9f20SBram Moolenaar
987ad6b90c3SYegappan Lakshmanan /*
988ad6b90c3SYegappan Lakshmanan * Set the cterm fg/bg/ul color for the highlight group at 'idx'.
989ad6b90c3SYegappan Lakshmanan * 'key' is one of 'CTERMFG' or 'CTERMBG' or 'CTERMUL'.
990ad6b90c3SYegappan Lakshmanan * 'keystart' is the color name/value.
991ad6b90c3SYegappan Lakshmanan * 'arg' is the color name or the numeric value as a string.
992ad6b90c3SYegappan Lakshmanan * 'is_normal_group' is set if the highlight group is 'NORMAL'
993ad6b90c3SYegappan Lakshmanan * 'init' is set to TRUE when initializing highlighting.
994ad6b90c3SYegappan Lakshmanan * Called for the ":highlight" command and the "hlset()" function.
995ad6b90c3SYegappan Lakshmanan *
996ad6b90c3SYegappan Lakshmanan * Returns TRUE if the color is set.
997ad6b90c3SYegappan Lakshmanan */
998ad6b90c3SYegappan Lakshmanan static int
highlight_set_cterm_color(int idx,char_u * key,char_u * key_start,char_u * arg,int is_normal_group,int init)999ad6b90c3SYegappan Lakshmanan highlight_set_cterm_color(
1000ad6b90c3SYegappan Lakshmanan int idx,
1001ad6b90c3SYegappan Lakshmanan char_u *key,
1002ad6b90c3SYegappan Lakshmanan char_u *key_start,
1003ad6b90c3SYegappan Lakshmanan char_u *arg,
1004ad6b90c3SYegappan Lakshmanan int is_normal_group,
1005ad6b90c3SYegappan Lakshmanan int init)
1006ad6b90c3SYegappan Lakshmanan {
1007ad6b90c3SYegappan Lakshmanan int color;
1008ad6b90c3SYegappan Lakshmanan long i;
1009ad6b90c3SYegappan Lakshmanan int off;
1010ad6b90c3SYegappan Lakshmanan
1011ad6b90c3SYegappan Lakshmanan if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
1012ad6b90c3SYegappan Lakshmanan {
1013ad6b90c3SYegappan Lakshmanan if (!init)
1014ad6b90c3SYegappan Lakshmanan HL_TABLE()[idx].sg_set |= SG_CTERM;
1015ad6b90c3SYegappan Lakshmanan
1016ad6b90c3SYegappan Lakshmanan // When setting the foreground color, and previously the "bold"
1017ad6b90c3SYegappan Lakshmanan // flag was set for a light color, reset it now
1018ad6b90c3SYegappan Lakshmanan if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold)
1019ad6b90c3SYegappan Lakshmanan {
1020ad6b90c3SYegappan Lakshmanan HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
1021ad6b90c3SYegappan Lakshmanan HL_TABLE()[idx].sg_cterm_bold = FALSE;
1022ad6b90c3SYegappan Lakshmanan }
1023ad6b90c3SYegappan Lakshmanan
1024ad6b90c3SYegappan Lakshmanan if (VIM_ISDIGIT(*arg))
1025ad6b90c3SYegappan Lakshmanan color = atoi((char *)arg);
1026ad6b90c3SYegappan Lakshmanan else if (STRICMP(arg, "fg") == 0)
1027ad6b90c3SYegappan Lakshmanan {
1028ad6b90c3SYegappan Lakshmanan if (cterm_normal_fg_color)
1029ad6b90c3SYegappan Lakshmanan color = cterm_normal_fg_color - 1;
1030ad6b90c3SYegappan Lakshmanan else
1031ad6b90c3SYegappan Lakshmanan {
1032ad6b90c3SYegappan Lakshmanan emsg(_("E419: FG color unknown"));
1033ad6b90c3SYegappan Lakshmanan return FALSE;
1034ad6b90c3SYegappan Lakshmanan }
1035ad6b90c3SYegappan Lakshmanan }
1036ad6b90c3SYegappan Lakshmanan else if (STRICMP(arg, "bg") == 0)
1037ad6b90c3SYegappan Lakshmanan {
1038ad6b90c3SYegappan Lakshmanan if (cterm_normal_bg_color > 0)
1039ad6b90c3SYegappan Lakshmanan color = cterm_normal_bg_color - 1;
1040ad6b90c3SYegappan Lakshmanan else
1041ad6b90c3SYegappan Lakshmanan {
1042ad6b90c3SYegappan Lakshmanan emsg(_("E420: BG color unknown"));
1043ad6b90c3SYegappan Lakshmanan return FALSE;
1044ad6b90c3SYegappan Lakshmanan }
1045ad6b90c3SYegappan Lakshmanan }
1046ad6b90c3SYegappan Lakshmanan else if (STRICMP(arg, "ul") == 0)
1047ad6b90c3SYegappan Lakshmanan {
1048ad6b90c3SYegappan Lakshmanan if (cterm_normal_ul_color > 0)
1049ad6b90c3SYegappan Lakshmanan color = cterm_normal_ul_color - 1;
1050ad6b90c3SYegappan Lakshmanan else
1051ad6b90c3SYegappan Lakshmanan {
1052ad6b90c3SYegappan Lakshmanan emsg(_("E453: UL color unknown"));
1053ad6b90c3SYegappan Lakshmanan return FALSE;
1054ad6b90c3SYegappan Lakshmanan }
1055ad6b90c3SYegappan Lakshmanan }
1056ad6b90c3SYegappan Lakshmanan else
1057ad6b90c3SYegappan Lakshmanan {
1058ad6b90c3SYegappan Lakshmanan int bold = MAYBE;
1059ad6b90c3SYegappan Lakshmanan
1060ad6b90c3SYegappan Lakshmanan // reduce calls to STRICMP a bit, it can be slow
1061ad6b90c3SYegappan Lakshmanan off = TOUPPER_ASC(*arg);
1062ad6b90c3SYegappan Lakshmanan for (i = ARRAY_LENGTH(color_names); --i >= 0; )
1063ad6b90c3SYegappan Lakshmanan if (off == color_names[i][0]
1064ad6b90c3SYegappan Lakshmanan && STRICMP(arg + 1, color_names[i] + 1) == 0)
1065ad6b90c3SYegappan Lakshmanan break;
1066ad6b90c3SYegappan Lakshmanan if (i < 0)
1067ad6b90c3SYegappan Lakshmanan {
1068ad6b90c3SYegappan Lakshmanan semsg(_("E421: Color name or number not recognized: %s"),
1069ad6b90c3SYegappan Lakshmanan key_start);
1070ad6b90c3SYegappan Lakshmanan return FALSE;
1071ad6b90c3SYegappan Lakshmanan }
1072ad6b90c3SYegappan Lakshmanan
1073ad6b90c3SYegappan Lakshmanan color = lookup_color(i, key[5] == 'F', &bold);
1074ad6b90c3SYegappan Lakshmanan
1075ad6b90c3SYegappan Lakshmanan // set/reset bold attribute to get light foreground
1076ad6b90c3SYegappan Lakshmanan // colors (on some terminals, e.g. "linux")
1077ad6b90c3SYegappan Lakshmanan if (bold == TRUE)
1078ad6b90c3SYegappan Lakshmanan {
1079ad6b90c3SYegappan Lakshmanan HL_TABLE()[idx].sg_cterm |= HL_BOLD;
1080ad6b90c3SYegappan Lakshmanan HL_TABLE()[idx].sg_cterm_bold = TRUE;
1081ad6b90c3SYegappan Lakshmanan }
1082ad6b90c3SYegappan Lakshmanan else if (bold == FALSE)
1083ad6b90c3SYegappan Lakshmanan HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
1084ad6b90c3SYegappan Lakshmanan }
1085ad6b90c3SYegappan Lakshmanan
1086ad6b90c3SYegappan Lakshmanan // Add one to the argument, to avoid zero. Zero is used for
1087ad6b90c3SYegappan Lakshmanan // "NONE", then "color" is -1.
1088ad6b90c3SYegappan Lakshmanan if (key[5] == 'F')
1089ad6b90c3SYegappan Lakshmanan highlight_set_ctermfg(idx, color, is_normal_group);
1090ad6b90c3SYegappan Lakshmanan else if (key[5] == 'B')
1091ad6b90c3SYegappan Lakshmanan highlight_set_ctermbg(idx, color, is_normal_group);
1092ad6b90c3SYegappan Lakshmanan else // ctermul
1093ad6b90c3SYegappan Lakshmanan highlight_set_ctermul(idx, color, is_normal_group);
1094ad6b90c3SYegappan Lakshmanan }
1095ad6b90c3SYegappan Lakshmanan
1096ad6b90c3SYegappan Lakshmanan return TRUE;
1097ad6b90c3SYegappan Lakshmanan }
1098ad6b90c3SYegappan Lakshmanan
1099ad6b90c3SYegappan Lakshmanan #if defined(FEAT_GUI) || defined(FEAT_EVAL)
1100ad6b90c3SYegappan Lakshmanan /*
1101ad6b90c3SYegappan Lakshmanan * Set the GUI foreground color for the highlight group at 'idx'.
1102ad6b90c3SYegappan Lakshmanan * Returns TRUE if the color is set.
1103ad6b90c3SYegappan Lakshmanan */
1104ad6b90c3SYegappan Lakshmanan static int
highlight_set_guifg(int idx,char_u * arg,int is_menu_group UNUSED,int is_scrollbar_group UNUSED,int is_tooltip_group UNUSED,int * do_colors UNUSED,int init)1105ad6b90c3SYegappan Lakshmanan highlight_set_guifg(
1106ad6b90c3SYegappan Lakshmanan int idx,
1107ad6b90c3SYegappan Lakshmanan char_u *arg,
1108ad6b90c3SYegappan Lakshmanan int is_menu_group UNUSED,
1109ad6b90c3SYegappan Lakshmanan int is_scrollbar_group UNUSED,
1110ad6b90c3SYegappan Lakshmanan int is_tooltip_group UNUSED,
1111ad6b90c3SYegappan Lakshmanan int *do_colors UNUSED,
1112ad6b90c3SYegappan Lakshmanan int init)
1113ad6b90c3SYegappan Lakshmanan {
1114731fba10SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1115ad6b90c3SYegappan Lakshmanan long i;
1116731fba10SBram Moolenaar # endif
1117ad6b90c3SYegappan Lakshmanan char_u **namep;
1118ad6b90c3SYegappan Lakshmanan int did_change = FALSE;
1119ad6b90c3SYegappan Lakshmanan
1120ad6b90c3SYegappan Lakshmanan namep = &HL_TABLE()[idx].sg_gui_fg_name;
1121f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
1122f9cc9f20SBram Moolenaar {
1123f9cc9f20SBram Moolenaar if (!init)
1124f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI;
1125f9cc9f20SBram Moolenaar
1126f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1127f9cc9f20SBram Moolenaar // In GUI guifg colors are only used when recognized
1128f9cc9f20SBram Moolenaar i = color_name2handle(arg);
1129f9cc9f20SBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
1130f9cc9f20SBram Moolenaar {
1131f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg = i;
1132f9cc9f20SBram Moolenaar # endif
1133f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0)
1134f9cc9f20SBram Moolenaar {
1135f9cc9f20SBram Moolenaar vim_free(*namep);
1136f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0)
1137f9cc9f20SBram Moolenaar *namep = vim_strsave(arg);
1138f9cc9f20SBram Moolenaar else
1139f9cc9f20SBram Moolenaar *namep = NULL;
1140f9cc9f20SBram Moolenaar did_change = TRUE;
1141f9cc9f20SBram Moolenaar }
1142f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1143f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11
1144f9cc9f20SBram Moolenaar if (is_menu_group && gui.menu_fg_pixel != i)
1145f9cc9f20SBram Moolenaar {
1146f9cc9f20SBram Moolenaar gui.menu_fg_pixel = i;
1147ad6b90c3SYegappan Lakshmanan *do_colors = TRUE;
1148f9cc9f20SBram Moolenaar }
1149f9cc9f20SBram Moolenaar if (is_scrollbar_group && gui.scroll_fg_pixel != i)
1150f9cc9f20SBram Moolenaar {
1151f9cc9f20SBram Moolenaar gui.scroll_fg_pixel = i;
1152ad6b90c3SYegappan Lakshmanan *do_colors = TRUE;
1153f9cc9f20SBram Moolenaar }
1154f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI
1155f9cc9f20SBram Moolenaar if (is_tooltip_group && gui.tooltip_fg_pixel != i)
1156f9cc9f20SBram Moolenaar {
1157f9cc9f20SBram Moolenaar gui.tooltip_fg_pixel = i;
1158ad6b90c3SYegappan Lakshmanan *do_colors = TRUE;
1159f9cc9f20SBram Moolenaar }
1160f9cc9f20SBram Moolenaar # endif
1161f9cc9f20SBram Moolenaar # endif
1162f9cc9f20SBram Moolenaar }
1163f9cc9f20SBram Moolenaar # endif
1164f9cc9f20SBram Moolenaar }
1165f9cc9f20SBram Moolenaar
1166ad6b90c3SYegappan Lakshmanan return did_change;
1167ad6b90c3SYegappan Lakshmanan }
1168ad6b90c3SYegappan Lakshmanan
1169ad6b90c3SYegappan Lakshmanan /*
1170ad6b90c3SYegappan Lakshmanan * Set the GUI background color for the highlight group at 'idx'.
1171ad6b90c3SYegappan Lakshmanan * Returns TRUE if the color is set.
1172ad6b90c3SYegappan Lakshmanan */
1173ad6b90c3SYegappan Lakshmanan static int
highlight_set_guibg(int idx,char_u * arg,int is_menu_group UNUSED,int is_scrollbar_group UNUSED,int is_tooltip_group UNUSED,int * do_colors UNUSED,int init)1174ad6b90c3SYegappan Lakshmanan highlight_set_guibg(
1175ad6b90c3SYegappan Lakshmanan int idx,
1176ad6b90c3SYegappan Lakshmanan char_u *arg,
1177ad6b90c3SYegappan Lakshmanan int is_menu_group UNUSED,
1178ad6b90c3SYegappan Lakshmanan int is_scrollbar_group UNUSED,
1179ad6b90c3SYegappan Lakshmanan int is_tooltip_group UNUSED,
1180ad6b90c3SYegappan Lakshmanan int *do_colors UNUSED,
1181ad6b90c3SYegappan Lakshmanan int init)
1182ad6b90c3SYegappan Lakshmanan {
1183731fba10SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1184ad6b90c3SYegappan Lakshmanan int i;
1185731fba10SBram Moolenaar # endif
1186ad6b90c3SYegappan Lakshmanan char_u **namep;
1187ad6b90c3SYegappan Lakshmanan int did_change = FALSE;
1188ad6b90c3SYegappan Lakshmanan
1189ad6b90c3SYegappan Lakshmanan namep = &HL_TABLE()[idx].sg_gui_bg_name;
1190f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
1191f9cc9f20SBram Moolenaar {
1192f9cc9f20SBram Moolenaar if (!init)
1193f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI;
1194f9cc9f20SBram Moolenaar
1195f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1196e30d1025SDrew Vogel // In GUI guibg colors are only used when recognized
1197f9cc9f20SBram Moolenaar i = color_name2handle(arg);
1198f9cc9f20SBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
1199f9cc9f20SBram Moolenaar {
1200f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg = i;
1201f9cc9f20SBram Moolenaar # endif
1202f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0)
1203f9cc9f20SBram Moolenaar {
1204f9cc9f20SBram Moolenaar vim_free(*namep);
1205f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0)
1206f9cc9f20SBram Moolenaar *namep = vim_strsave(arg);
1207f9cc9f20SBram Moolenaar else
1208f9cc9f20SBram Moolenaar *namep = NULL;
1209f9cc9f20SBram Moolenaar did_change = TRUE;
1210f9cc9f20SBram Moolenaar }
1211f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1212f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11
1213f9cc9f20SBram Moolenaar if (is_menu_group && gui.menu_bg_pixel != i)
1214f9cc9f20SBram Moolenaar {
1215f9cc9f20SBram Moolenaar gui.menu_bg_pixel = i;
1216ad6b90c3SYegappan Lakshmanan *do_colors = TRUE;
1217f9cc9f20SBram Moolenaar }
1218f9cc9f20SBram Moolenaar if (is_scrollbar_group && gui.scroll_bg_pixel != i)
1219f9cc9f20SBram Moolenaar {
1220f9cc9f20SBram Moolenaar gui.scroll_bg_pixel = i;
1221ad6b90c3SYegappan Lakshmanan *do_colors = TRUE;
1222f9cc9f20SBram Moolenaar }
1223f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI
1224f9cc9f20SBram Moolenaar if (is_tooltip_group && gui.tooltip_bg_pixel != i)
1225f9cc9f20SBram Moolenaar {
1226f9cc9f20SBram Moolenaar gui.tooltip_bg_pixel = i;
1227ad6b90c3SYegappan Lakshmanan *do_colors = TRUE;
1228f9cc9f20SBram Moolenaar }
1229f9cc9f20SBram Moolenaar # endif
1230f9cc9f20SBram Moolenaar # endif
1231f9cc9f20SBram Moolenaar }
1232f9cc9f20SBram Moolenaar # endif
1233f9cc9f20SBram Moolenaar }
1234f9cc9f20SBram Moolenaar
1235ad6b90c3SYegappan Lakshmanan return did_change;
1236ad6b90c3SYegappan Lakshmanan }
1237ad6b90c3SYegappan Lakshmanan
1238ad6b90c3SYegappan Lakshmanan /*
1239ad6b90c3SYegappan Lakshmanan * Set the GUI undercurl/strikethrough color for the highlight group at 'idx'.
1240ad6b90c3SYegappan Lakshmanan * Returns TRUE if the color is set.
1241ad6b90c3SYegappan Lakshmanan */
1242ad6b90c3SYegappan Lakshmanan static int
highlight_set_guisp(int idx,char_u * arg,int init)1243ad6b90c3SYegappan Lakshmanan highlight_set_guisp(int idx, char_u *arg, int init)
1244ad6b90c3SYegappan Lakshmanan {
1245ad6b90c3SYegappan Lakshmanan # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1246ad6b90c3SYegappan Lakshmanan int i;
1247ad6b90c3SYegappan Lakshmanan # endif
1248ad6b90c3SYegappan Lakshmanan int did_change = FALSE;
1249ad6b90c3SYegappan Lakshmanan char_u **namep;
1250ad6b90c3SYegappan Lakshmanan
1251ad6b90c3SYegappan Lakshmanan namep = &HL_TABLE()[idx].sg_gui_sp_name;
1252f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
1253f9cc9f20SBram Moolenaar {
1254f9cc9f20SBram Moolenaar if (!init)
1255f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI;
1256f9cc9f20SBram Moolenaar
1257e023e88bSBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1258e023e88bSBram Moolenaar // In GUI guisp colors are only used when recognized
1259f9cc9f20SBram Moolenaar i = color_name2handle(arg);
1260e023e88bSBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
1261f9cc9f20SBram Moolenaar {
1262f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_sp = i;
1263f9cc9f20SBram Moolenaar # endif
1264f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0)
1265f9cc9f20SBram Moolenaar {
1266f9cc9f20SBram Moolenaar vim_free(*namep);
1267f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0)
1268f9cc9f20SBram Moolenaar *namep = vim_strsave(arg);
1269f9cc9f20SBram Moolenaar else
1270f9cc9f20SBram Moolenaar *namep = NULL;
1271f9cc9f20SBram Moolenaar did_change = TRUE;
1272f9cc9f20SBram Moolenaar }
1273e023e88bSBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1274f9cc9f20SBram Moolenaar }
1275f9cc9f20SBram Moolenaar # endif
1276f9cc9f20SBram Moolenaar }
1277ad6b90c3SYegappan Lakshmanan
1278ad6b90c3SYegappan Lakshmanan return did_change;
1279f9cc9f20SBram Moolenaar }
1280ad6b90c3SYegappan Lakshmanan #endif
1281ad6b90c3SYegappan Lakshmanan
1282ad6b90c3SYegappan Lakshmanan /*
1283ad6b90c3SYegappan Lakshmanan * Set the start/stop terminal codes for a highlight group.
1284ad6b90c3SYegappan Lakshmanan * Returns TRUE if the terminal code is set.
1285ad6b90c3SYegappan Lakshmanan */
1286ad6b90c3SYegappan Lakshmanan static int
highlight_set_startstop_termcode(int idx,char_u * key,char_u * arg,int init)1287ad6b90c3SYegappan Lakshmanan highlight_set_startstop_termcode(int idx, char_u *key, char_u *arg, int init)
1288f9cc9f20SBram Moolenaar {
1289ad6b90c3SYegappan Lakshmanan int off;
1290f9cc9f20SBram Moolenaar char_u buf[100];
1291ad6b90c3SYegappan Lakshmanan int len;
1292f9cc9f20SBram Moolenaar char_u *tname;
1293ad6b90c3SYegappan Lakshmanan char_u *p;
1294f9cc9f20SBram Moolenaar
1295f9cc9f20SBram Moolenaar if (!init)
1296f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_TERM;
1297f9cc9f20SBram Moolenaar
1298ad6b90c3SYegappan Lakshmanan // The "start" and "stop" arguments can be a literal escape
1299ad6b90c3SYegappan Lakshmanan // sequence, or a comma separated list of terminal codes.
1300f9cc9f20SBram Moolenaar if (STRNCMP(arg, "t_", 2) == 0)
1301f9cc9f20SBram Moolenaar {
1302f9cc9f20SBram Moolenaar off = 0;
1303f9cc9f20SBram Moolenaar buf[0] = 0;
1304f9cc9f20SBram Moolenaar while (arg[off] != NUL)
1305f9cc9f20SBram Moolenaar {
1306f9cc9f20SBram Moolenaar // Isolate one termcap name
1307f9cc9f20SBram Moolenaar for (len = 0; arg[off + len] &&
1308f9cc9f20SBram Moolenaar arg[off + len] != ','; ++len)
1309f9cc9f20SBram Moolenaar ;
1310f9cc9f20SBram Moolenaar tname = vim_strnsave(arg + off, len);
1311f9cc9f20SBram Moolenaar if (tname == NULL) // out of memory
1312ad6b90c3SYegappan Lakshmanan return FALSE;
1313f9cc9f20SBram Moolenaar // lookup the escape sequence for the item
1314f9cc9f20SBram Moolenaar p = get_term_code(tname);
1315f9cc9f20SBram Moolenaar vim_free(tname);
1316f9cc9f20SBram Moolenaar if (p == NULL) // ignore non-existing things
1317f9cc9f20SBram Moolenaar p = (char_u *)"";
1318f9cc9f20SBram Moolenaar
1319f9cc9f20SBram Moolenaar // Append it to the already found stuff
1320f9cc9f20SBram Moolenaar if ((int)(STRLEN(buf) + STRLEN(p)) >= 99)
1321f9cc9f20SBram Moolenaar {
1322f9cc9f20SBram Moolenaar semsg(_("E422: terminal code too long: %s"), arg);
1323ad6b90c3SYegappan Lakshmanan return FALSE;
1324f9cc9f20SBram Moolenaar }
1325f9cc9f20SBram Moolenaar STRCAT(buf, p);
1326f9cc9f20SBram Moolenaar
1327f9cc9f20SBram Moolenaar // Advance to the next item
1328f9cc9f20SBram Moolenaar off += len;
1329f9cc9f20SBram Moolenaar if (arg[off] == ',') // another one follows
1330f9cc9f20SBram Moolenaar ++off;
1331f9cc9f20SBram Moolenaar }
1332f9cc9f20SBram Moolenaar }
1333f9cc9f20SBram Moolenaar else
1334f9cc9f20SBram Moolenaar {
1335ad6b90c3SYegappan Lakshmanan // Copy characters from arg[] to buf[], translating <> codes.
1336f9cc9f20SBram Moolenaar for (p = arg, off = 0; off < 100 - 6 && *p; )
1337f9cc9f20SBram Moolenaar {
1338ebe9d34aSBram Moolenaar len = trans_special(&p, buf + off, FSK_SIMPLIFY, NULL);
1339f9cc9f20SBram Moolenaar if (len > 0) // recognized special char
1340f9cc9f20SBram Moolenaar off += len;
1341f9cc9f20SBram Moolenaar else // copy as normal char
1342f9cc9f20SBram Moolenaar buf[off++] = *p++;
1343f9cc9f20SBram Moolenaar }
1344f9cc9f20SBram Moolenaar buf[off] = NUL;
1345f9cc9f20SBram Moolenaar }
1346f9cc9f20SBram Moolenaar
1347f9cc9f20SBram Moolenaar if (STRCMP(buf, "NONE") == 0) // resetting the value
1348f9cc9f20SBram Moolenaar p = NULL;
1349f9cc9f20SBram Moolenaar else
1350f9cc9f20SBram Moolenaar p = vim_strsave(buf);
1351f9cc9f20SBram Moolenaar if (key[2] == 'A')
1352f9cc9f20SBram Moolenaar {
1353f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_start);
1354f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_start = p;
1355f9cc9f20SBram Moolenaar }
1356f9cc9f20SBram Moolenaar else
1357f9cc9f20SBram Moolenaar {
1358f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_stop);
1359f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_stop = p;
1360f9cc9f20SBram Moolenaar }
1361ad6b90c3SYegappan Lakshmanan return TRUE;
1362ad6b90c3SYegappan Lakshmanan }
1363ad6b90c3SYegappan Lakshmanan
1364ad6b90c3SYegappan Lakshmanan /*
1365ad6b90c3SYegappan Lakshmanan * Handle the ":highlight .." command.
1366ad6b90c3SYegappan Lakshmanan * When using ":hi clear" this is called recursively for each group with
1367ad6b90c3SYegappan Lakshmanan * "forceit" and "init" both TRUE.
1368ad6b90c3SYegappan Lakshmanan */
1369ad6b90c3SYegappan Lakshmanan void
do_highlight(char_u * line,int forceit,int init)1370ad6b90c3SYegappan Lakshmanan do_highlight(
1371ad6b90c3SYegappan Lakshmanan char_u *line,
1372ad6b90c3SYegappan Lakshmanan int forceit,
1373ad6b90c3SYegappan Lakshmanan int init) // TRUE when called for initializing
1374ad6b90c3SYegappan Lakshmanan {
1375ad6b90c3SYegappan Lakshmanan char_u *name_end;
1376ad6b90c3SYegappan Lakshmanan char_u *linep;
1377ad6b90c3SYegappan Lakshmanan char_u *key_start;
1378ad6b90c3SYegappan Lakshmanan char_u *arg_start;
1379ad6b90c3SYegappan Lakshmanan char_u *key = NULL, *arg = NULL;
1380ad6b90c3SYegappan Lakshmanan long i;
1381ad6b90c3SYegappan Lakshmanan int id;
1382ad6b90c3SYegappan Lakshmanan int idx;
1383ad6b90c3SYegappan Lakshmanan hl_group_T item_before;
1384ad6b90c3SYegappan Lakshmanan int did_change = FALSE;
1385ad6b90c3SYegappan Lakshmanan int dodefault = FALSE;
1386ad6b90c3SYegappan Lakshmanan int doclear = FALSE;
1387ad6b90c3SYegappan Lakshmanan int dolink = FALSE;
1388ad6b90c3SYegappan Lakshmanan int error = FALSE;
1389ad6b90c3SYegappan Lakshmanan int is_normal_group = FALSE; // "Normal" group
1390ad6b90c3SYegappan Lakshmanan #ifdef FEAT_GUI_X11
1391ad6b90c3SYegappan Lakshmanan int is_menu_group = FALSE; // "Menu" group
1392ad6b90c3SYegappan Lakshmanan int is_scrollbar_group = FALSE; // "Scrollbar" group
1393ad6b90c3SYegappan Lakshmanan int is_tooltip_group = FALSE; // "Tooltip" group
1394ad6b90c3SYegappan Lakshmanan #else
1395ad6b90c3SYegappan Lakshmanan # define is_menu_group 0
1396ad6b90c3SYegappan Lakshmanan # define is_tooltip_group 0
1397ad6b90c3SYegappan Lakshmanan # define is_scrollbar_group 0
1398ad6b90c3SYegappan Lakshmanan #endif
1399ad6b90c3SYegappan Lakshmanan #if defined(FEAT_GUI) || defined(FEAT_EVAL)
1400ad6b90c3SYegappan Lakshmanan int do_colors = FALSE; // need to update colors?
1401ad6b90c3SYegappan Lakshmanan #endif
1402ad6b90c3SYegappan Lakshmanan #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1403ad6b90c3SYegappan Lakshmanan int did_highlight_changed = FALSE;
1404ad6b90c3SYegappan Lakshmanan #endif
1405ad6b90c3SYegappan Lakshmanan
1406ad6b90c3SYegappan Lakshmanan // If no argument, list current highlighting.
1407ad6b90c3SYegappan Lakshmanan if (!init && ends_excmd2(line - 1, line))
1408ad6b90c3SYegappan Lakshmanan {
1409ad6b90c3SYegappan Lakshmanan for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
1410ad6b90c3SYegappan Lakshmanan // TODO: only call when the group has attributes set
1411ad6b90c3SYegappan Lakshmanan highlight_list_one((int)i);
1412ad6b90c3SYegappan Lakshmanan return;
1413ad6b90c3SYegappan Lakshmanan }
1414ad6b90c3SYegappan Lakshmanan
1415ad6b90c3SYegappan Lakshmanan // Isolate the name.
1416ad6b90c3SYegappan Lakshmanan name_end = skiptowhite(line);
1417ad6b90c3SYegappan Lakshmanan linep = skipwhite(name_end);
1418ad6b90c3SYegappan Lakshmanan
1419ad6b90c3SYegappan Lakshmanan // Check for "default" argument.
1420ad6b90c3SYegappan Lakshmanan if (STRNCMP(line, "default", name_end - line) == 0)
1421ad6b90c3SYegappan Lakshmanan {
1422ad6b90c3SYegappan Lakshmanan dodefault = TRUE;
1423ad6b90c3SYegappan Lakshmanan line = linep;
1424ad6b90c3SYegappan Lakshmanan name_end = skiptowhite(line);
1425ad6b90c3SYegappan Lakshmanan linep = skipwhite(name_end);
1426ad6b90c3SYegappan Lakshmanan }
1427ad6b90c3SYegappan Lakshmanan
1428ad6b90c3SYegappan Lakshmanan // Check for "clear" or "link" argument.
1429ad6b90c3SYegappan Lakshmanan if (STRNCMP(line, "clear", name_end - line) == 0)
1430ad6b90c3SYegappan Lakshmanan doclear = TRUE;
1431ad6b90c3SYegappan Lakshmanan if (STRNCMP(line, "link", name_end - line) == 0)
1432ad6b90c3SYegappan Lakshmanan dolink = TRUE;
1433ad6b90c3SYegappan Lakshmanan
1434ad6b90c3SYegappan Lakshmanan // ":highlight {group-name}": list highlighting for one group.
1435ad6b90c3SYegappan Lakshmanan if (!doclear && !dolink && ends_excmd2(line, linep))
1436ad6b90c3SYegappan Lakshmanan {
1437ad6b90c3SYegappan Lakshmanan id = syn_namen2id(line, (int)(name_end - line));
1438ad6b90c3SYegappan Lakshmanan if (id == 0)
1439ad6b90c3SYegappan Lakshmanan semsg(_("E411: highlight group not found: %s"), line);
1440ad6b90c3SYegappan Lakshmanan else
1441ad6b90c3SYegappan Lakshmanan highlight_list_one(id);
1442ad6b90c3SYegappan Lakshmanan return;
1443ad6b90c3SYegappan Lakshmanan }
1444ad6b90c3SYegappan Lakshmanan
1445ad6b90c3SYegappan Lakshmanan // Handle ":highlight link {from} {to}" command.
1446ad6b90c3SYegappan Lakshmanan if (dolink)
1447ad6b90c3SYegappan Lakshmanan {
1448ad6b90c3SYegappan Lakshmanan char_u *from_start = linep;
1449ad6b90c3SYegappan Lakshmanan char_u *from_end;
1450ad6b90c3SYegappan Lakshmanan int from_len;
1451ad6b90c3SYegappan Lakshmanan char_u *to_start;
1452ad6b90c3SYegappan Lakshmanan char_u *to_end;
1453ad6b90c3SYegappan Lakshmanan int to_len;
1454ad6b90c3SYegappan Lakshmanan
1455ad6b90c3SYegappan Lakshmanan from_end = skiptowhite(from_start);
1456ad6b90c3SYegappan Lakshmanan to_start = skipwhite(from_end);
1457ad6b90c3SYegappan Lakshmanan to_end = skiptowhite(to_start);
1458ad6b90c3SYegappan Lakshmanan
1459ad6b90c3SYegappan Lakshmanan if (ends_excmd2(line, from_start) || ends_excmd2(line, to_start))
1460ad6b90c3SYegappan Lakshmanan {
1461ad6b90c3SYegappan Lakshmanan semsg(_("E412: Not enough arguments: \":highlight link %s\""),
1462ad6b90c3SYegappan Lakshmanan from_start);
1463ad6b90c3SYegappan Lakshmanan return;
1464ad6b90c3SYegappan Lakshmanan }
1465ad6b90c3SYegappan Lakshmanan
1466ad6b90c3SYegappan Lakshmanan if (!ends_excmd2(line, skipwhite(to_end)))
1467ad6b90c3SYegappan Lakshmanan {
1468ad6b90c3SYegappan Lakshmanan semsg(_("E413: Too many arguments: \":highlight link %s\""),
1469ad6b90c3SYegappan Lakshmanan from_start);
1470ad6b90c3SYegappan Lakshmanan return;
1471ad6b90c3SYegappan Lakshmanan }
1472ad6b90c3SYegappan Lakshmanan
1473ad6b90c3SYegappan Lakshmanan from_len = (int)(from_end - from_start);
1474ad6b90c3SYegappan Lakshmanan to_len = (int)(to_end - to_start);
1475ad6b90c3SYegappan Lakshmanan highlight_group_link(from_start, from_len, to_start, to_len,
1476ad6b90c3SYegappan Lakshmanan dodefault, forceit, init);
1477ad6b90c3SYegappan Lakshmanan return;
1478ad6b90c3SYegappan Lakshmanan }
1479ad6b90c3SYegappan Lakshmanan
1480ad6b90c3SYegappan Lakshmanan if (doclear)
1481ad6b90c3SYegappan Lakshmanan {
1482ad6b90c3SYegappan Lakshmanan // ":highlight clear [group]" command.
1483ad6b90c3SYegappan Lakshmanan if (ends_excmd2(line, linep))
1484ad6b90c3SYegappan Lakshmanan {
1485ad6b90c3SYegappan Lakshmanan // ":highlight clear" without group name
1486ad6b90c3SYegappan Lakshmanan highlight_reset_all();
1487ad6b90c3SYegappan Lakshmanan return;
1488ad6b90c3SYegappan Lakshmanan }
1489ad6b90c3SYegappan Lakshmanan line = linep;
1490ad6b90c3SYegappan Lakshmanan name_end = skiptowhite(line);
1491ad6b90c3SYegappan Lakshmanan linep = skipwhite(name_end);
1492ad6b90c3SYegappan Lakshmanan }
1493ad6b90c3SYegappan Lakshmanan
1494ad6b90c3SYegappan Lakshmanan // Find the group name in the table. If it does not exist yet, add it.
1495ad6b90c3SYegappan Lakshmanan id = syn_check_group(line, (int)(name_end - line));
1496ad6b90c3SYegappan Lakshmanan if (id == 0) // failed (out of memory)
1497ad6b90c3SYegappan Lakshmanan return;
1498ad6b90c3SYegappan Lakshmanan idx = id - 1; // index is ID minus one
1499ad6b90c3SYegappan Lakshmanan
1500ad6b90c3SYegappan Lakshmanan // Return if "default" was used and the group already has settings.
1501ad6b90c3SYegappan Lakshmanan if (dodefault && hl_has_settings(idx, TRUE))
1502ad6b90c3SYegappan Lakshmanan return;
1503ad6b90c3SYegappan Lakshmanan
1504ad6b90c3SYegappan Lakshmanan // Make a copy so we can check if any attribute actually changed.
1505ad6b90c3SYegappan Lakshmanan item_before = HL_TABLE()[idx];
1506ad6b90c3SYegappan Lakshmanan
1507ad6b90c3SYegappan Lakshmanan if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0)
1508ad6b90c3SYegappan Lakshmanan is_normal_group = TRUE;
1509ad6b90c3SYegappan Lakshmanan #ifdef FEAT_GUI_X11
1510ad6b90c3SYegappan Lakshmanan else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0)
1511ad6b90c3SYegappan Lakshmanan is_menu_group = TRUE;
1512ad6b90c3SYegappan Lakshmanan else if (STRCMP(HL_TABLE()[idx].sg_name_u, "SCROLLBAR") == 0)
1513ad6b90c3SYegappan Lakshmanan is_scrollbar_group = TRUE;
1514ad6b90c3SYegappan Lakshmanan else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TOOLTIP") == 0)
1515ad6b90c3SYegappan Lakshmanan is_tooltip_group = TRUE;
1516ad6b90c3SYegappan Lakshmanan #endif
1517ad6b90c3SYegappan Lakshmanan
1518ad6b90c3SYegappan Lakshmanan // Clear the highlighting for ":hi clear {group}" and ":hi clear".
1519ad6b90c3SYegappan Lakshmanan if (doclear || (forceit && init))
1520ad6b90c3SYegappan Lakshmanan {
1521ad6b90c3SYegappan Lakshmanan highlight_clear(idx);
1522ad6b90c3SYegappan Lakshmanan if (!doclear)
1523ad6b90c3SYegappan Lakshmanan HL_TABLE()[idx].sg_set = 0;
1524ad6b90c3SYegappan Lakshmanan }
1525ad6b90c3SYegappan Lakshmanan
1526ad6b90c3SYegappan Lakshmanan if (!doclear)
1527ad6b90c3SYegappan Lakshmanan while (!ends_excmd2(line, linep))
1528ad6b90c3SYegappan Lakshmanan {
1529ad6b90c3SYegappan Lakshmanan key_start = linep;
1530ad6b90c3SYegappan Lakshmanan if (*linep == '=')
1531ad6b90c3SYegappan Lakshmanan {
1532ad6b90c3SYegappan Lakshmanan semsg(_("E415: unexpected equal sign: %s"), key_start);
1533ad6b90c3SYegappan Lakshmanan error = TRUE;
1534ad6b90c3SYegappan Lakshmanan break;
1535ad6b90c3SYegappan Lakshmanan }
1536ad6b90c3SYegappan Lakshmanan
1537ad6b90c3SYegappan Lakshmanan // Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg"
1538ad6b90c3SYegappan Lakshmanan // or "guibg").
1539ad6b90c3SYegappan Lakshmanan while (*linep && !VIM_ISWHITE(*linep) && *linep != '=')
1540ad6b90c3SYegappan Lakshmanan ++linep;
1541ad6b90c3SYegappan Lakshmanan vim_free(key);
1542ad6b90c3SYegappan Lakshmanan key = vim_strnsave_up(key_start, linep - key_start);
1543ad6b90c3SYegappan Lakshmanan if (key == NULL)
1544ad6b90c3SYegappan Lakshmanan {
1545ad6b90c3SYegappan Lakshmanan error = TRUE;
1546ad6b90c3SYegappan Lakshmanan break;
1547ad6b90c3SYegappan Lakshmanan }
1548ad6b90c3SYegappan Lakshmanan linep = skipwhite(linep);
1549ad6b90c3SYegappan Lakshmanan
1550ad6b90c3SYegappan Lakshmanan if (STRCMP(key, "NONE") == 0)
1551ad6b90c3SYegappan Lakshmanan {
1552ad6b90c3SYegappan Lakshmanan if (!init || HL_TABLE()[idx].sg_set == 0)
1553ad6b90c3SYegappan Lakshmanan {
1554ad6b90c3SYegappan Lakshmanan if (!init)
1555ad6b90c3SYegappan Lakshmanan HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI;
1556ad6b90c3SYegappan Lakshmanan highlight_clear(idx);
1557ad6b90c3SYegappan Lakshmanan }
1558ad6b90c3SYegappan Lakshmanan continue;
1559ad6b90c3SYegappan Lakshmanan }
1560ad6b90c3SYegappan Lakshmanan
1561ad6b90c3SYegappan Lakshmanan // Check for the equal sign.
1562ad6b90c3SYegappan Lakshmanan if (*linep != '=')
1563ad6b90c3SYegappan Lakshmanan {
1564ad6b90c3SYegappan Lakshmanan semsg(_("E416: missing equal sign: %s"), key_start);
1565ad6b90c3SYegappan Lakshmanan error = TRUE;
1566ad6b90c3SYegappan Lakshmanan break;
1567ad6b90c3SYegappan Lakshmanan }
1568ad6b90c3SYegappan Lakshmanan ++linep;
1569ad6b90c3SYegappan Lakshmanan
1570ad6b90c3SYegappan Lakshmanan // Isolate the argument.
1571ad6b90c3SYegappan Lakshmanan linep = skipwhite(linep);
1572ad6b90c3SYegappan Lakshmanan if (*linep == '\'') // guifg='color name'
1573ad6b90c3SYegappan Lakshmanan {
1574ad6b90c3SYegappan Lakshmanan arg_start = ++linep;
1575ad6b90c3SYegappan Lakshmanan linep = vim_strchr(linep, '\'');
1576ad6b90c3SYegappan Lakshmanan if (linep == NULL)
1577ad6b90c3SYegappan Lakshmanan {
1578ad6b90c3SYegappan Lakshmanan semsg(_(e_invarg2), key_start);
1579ad6b90c3SYegappan Lakshmanan error = TRUE;
1580ad6b90c3SYegappan Lakshmanan break;
1581ad6b90c3SYegappan Lakshmanan }
1582ad6b90c3SYegappan Lakshmanan }
1583ad6b90c3SYegappan Lakshmanan else
1584ad6b90c3SYegappan Lakshmanan {
1585ad6b90c3SYegappan Lakshmanan arg_start = linep;
1586ad6b90c3SYegappan Lakshmanan linep = skiptowhite(linep);
1587ad6b90c3SYegappan Lakshmanan }
1588ad6b90c3SYegappan Lakshmanan if (linep == arg_start)
1589ad6b90c3SYegappan Lakshmanan {
1590ad6b90c3SYegappan Lakshmanan semsg(_("E417: missing argument: %s"), key_start);
1591ad6b90c3SYegappan Lakshmanan error = TRUE;
1592ad6b90c3SYegappan Lakshmanan break;
1593ad6b90c3SYegappan Lakshmanan }
1594ad6b90c3SYegappan Lakshmanan vim_free(arg);
1595ad6b90c3SYegappan Lakshmanan arg = vim_strnsave(arg_start, linep - arg_start);
1596ad6b90c3SYegappan Lakshmanan if (arg == NULL)
1597ad6b90c3SYegappan Lakshmanan {
1598ad6b90c3SYegappan Lakshmanan error = TRUE;
1599ad6b90c3SYegappan Lakshmanan break;
1600ad6b90c3SYegappan Lakshmanan }
1601ad6b90c3SYegappan Lakshmanan if (*linep == '\'')
1602ad6b90c3SYegappan Lakshmanan ++linep;
1603ad6b90c3SYegappan Lakshmanan
1604ad6b90c3SYegappan Lakshmanan // Store the argument.
1605ad6b90c3SYegappan Lakshmanan if (STRCMP(key, "TERM") == 0
1606ad6b90c3SYegappan Lakshmanan || STRCMP(key, "CTERM") == 0
1607ad6b90c3SYegappan Lakshmanan || STRCMP(key, "GUI") == 0)
1608ad6b90c3SYegappan Lakshmanan {
1609ad6b90c3SYegappan Lakshmanan if (!highlight_set_termgui_attr(idx, key, arg, init))
1610ad6b90c3SYegappan Lakshmanan {
1611ad6b90c3SYegappan Lakshmanan error = TRUE;
1612ad6b90c3SYegappan Lakshmanan break;
1613ad6b90c3SYegappan Lakshmanan }
1614ad6b90c3SYegappan Lakshmanan }
1615ad6b90c3SYegappan Lakshmanan else if (STRCMP(key, "FONT") == 0)
1616ad6b90c3SYegappan Lakshmanan {
1617ad6b90c3SYegappan Lakshmanan // in non-GUI fonts are simply ignored
1618ad6b90c3SYegappan Lakshmanan #ifdef FEAT_GUI
1619ad6b90c3SYegappan Lakshmanan if (highlight_set_font(idx, arg, is_normal_group,
1620ad6b90c3SYegappan Lakshmanan is_menu_group, is_tooltip_group))
1621ad6b90c3SYegappan Lakshmanan did_change = TRUE;
1622ad6b90c3SYegappan Lakshmanan #endif
1623ad6b90c3SYegappan Lakshmanan }
1624ad6b90c3SYegappan Lakshmanan else if (STRCMP(key, "CTERMFG") == 0
1625ad6b90c3SYegappan Lakshmanan || STRCMP(key, "CTERMBG") == 0
1626ad6b90c3SYegappan Lakshmanan || STRCMP(key, "CTERMUL") == 0)
1627ad6b90c3SYegappan Lakshmanan {
1628ad6b90c3SYegappan Lakshmanan if (!highlight_set_cterm_color(idx, key, key_start, arg,
1629ad6b90c3SYegappan Lakshmanan is_normal_group, init))
1630ad6b90c3SYegappan Lakshmanan {
1631ad6b90c3SYegappan Lakshmanan error = TRUE;
1632ad6b90c3SYegappan Lakshmanan break;
1633ad6b90c3SYegappan Lakshmanan }
1634ad6b90c3SYegappan Lakshmanan }
1635ad6b90c3SYegappan Lakshmanan else if (STRCMP(key, "GUIFG") == 0)
1636ad6b90c3SYegappan Lakshmanan {
1637ad6b90c3SYegappan Lakshmanan #if defined(FEAT_GUI) || defined(FEAT_EVAL)
1638ad6b90c3SYegappan Lakshmanan if (highlight_set_guifg(idx, arg, is_menu_group,
1639ad6b90c3SYegappan Lakshmanan is_scrollbar_group, is_tooltip_group,
1640ad6b90c3SYegappan Lakshmanan &do_colors, init))
1641ad6b90c3SYegappan Lakshmanan did_change = TRUE;
1642ad6b90c3SYegappan Lakshmanan #endif
1643ad6b90c3SYegappan Lakshmanan }
1644ad6b90c3SYegappan Lakshmanan else if (STRCMP(key, "GUIBG") == 0)
1645ad6b90c3SYegappan Lakshmanan {
1646ad6b90c3SYegappan Lakshmanan #if defined(FEAT_GUI) || defined(FEAT_EVAL)
1647ad6b90c3SYegappan Lakshmanan if (highlight_set_guibg(idx, arg, is_menu_group,
1648ad6b90c3SYegappan Lakshmanan is_scrollbar_group, is_tooltip_group,
1649ad6b90c3SYegappan Lakshmanan &do_colors, init))
1650ad6b90c3SYegappan Lakshmanan did_change = TRUE;
1651ad6b90c3SYegappan Lakshmanan #endif
1652ad6b90c3SYegappan Lakshmanan }
1653ad6b90c3SYegappan Lakshmanan else if (STRCMP(key, "GUISP") == 0)
1654ad6b90c3SYegappan Lakshmanan {
1655ad6b90c3SYegappan Lakshmanan #if defined(FEAT_GUI) || defined(FEAT_EVAL)
1656ad6b90c3SYegappan Lakshmanan if (highlight_set_guisp(idx, arg, init))
1657ad6b90c3SYegappan Lakshmanan did_change = TRUE;
1658ad6b90c3SYegappan Lakshmanan #endif
1659ad6b90c3SYegappan Lakshmanan }
1660ad6b90c3SYegappan Lakshmanan else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0)
1661ad6b90c3SYegappan Lakshmanan {
1662ad6b90c3SYegappan Lakshmanan if (!highlight_set_startstop_termcode(idx, key, arg, init))
1663ad6b90c3SYegappan Lakshmanan {
1664ad6b90c3SYegappan Lakshmanan error = TRUE;
1665ad6b90c3SYegappan Lakshmanan break;
1666ad6b90c3SYegappan Lakshmanan }
1667f9cc9f20SBram Moolenaar }
1668f9cc9f20SBram Moolenaar else
1669f9cc9f20SBram Moolenaar {
1670f9cc9f20SBram Moolenaar semsg(_("E423: Illegal argument: %s"), key_start);
1671f9cc9f20SBram Moolenaar error = TRUE;
1672f9cc9f20SBram Moolenaar break;
1673f9cc9f20SBram Moolenaar }
1674f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cleared = FALSE;
1675f9cc9f20SBram Moolenaar
1676ad6b90c3SYegappan Lakshmanan // When highlighting has been given for a group, don't link it.
1677f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
1678f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_link = 0;
1679f9cc9f20SBram Moolenaar
1680ad6b90c3SYegappan Lakshmanan // Continue with next argument.
1681f9cc9f20SBram Moolenaar linep = skipwhite(linep);
1682f9cc9f20SBram Moolenaar }
1683f9cc9f20SBram Moolenaar
1684ad6b90c3SYegappan Lakshmanan // If there is an error, and it's a new entry, remove it from the table.
1685f9cc9f20SBram Moolenaar if (error && idx == highlight_ga.ga_len)
1686f9cc9f20SBram Moolenaar syn_unadd_group();
1687f9cc9f20SBram Moolenaar else
1688f9cc9f20SBram Moolenaar {
1689f9cc9f20SBram Moolenaar if (is_normal_group)
1690f9cc9f20SBram Moolenaar {
1691f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term_attr = 0;
1692f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_attr = 0;
1693f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
1694f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_attr = 0;
1695ad6b90c3SYegappan Lakshmanan // Need to update all groups, because they might be using "bg"
1696ad6b90c3SYegappan Lakshmanan // and/or "fg", which have been changed now.
1697f9cc9f20SBram Moolenaar #endif
1698f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1699f9cc9f20SBram Moolenaar if (USE_24BIT)
1700f9cc9f20SBram Moolenaar {
1701f9cc9f20SBram Moolenaar highlight_gui_started();
1702f9cc9f20SBram Moolenaar did_highlight_changed = TRUE;
1703f9cc9f20SBram Moolenaar redraw_all_later(NOT_VALID);
1704f9cc9f20SBram Moolenaar }
1705f9cc9f20SBram Moolenaar #endif
1706a8bd3496SBram Moolenaar #ifdef FEAT_VTP
1707a8bd3496SBram Moolenaar control_console_color_rgb();
1708a8bd3496SBram Moolenaar #endif
1709f9cc9f20SBram Moolenaar }
1710f9cc9f20SBram Moolenaar #ifdef FEAT_GUI_X11
1711f9cc9f20SBram Moolenaar # ifdef FEAT_MENU
1712f9cc9f20SBram Moolenaar else if (is_menu_group)
1713f9cc9f20SBram Moolenaar {
1714f9cc9f20SBram Moolenaar if (gui.in_use && do_colors)
1715f9cc9f20SBram Moolenaar gui_mch_new_menu_colors();
1716f9cc9f20SBram Moolenaar }
1717f9cc9f20SBram Moolenaar # endif
1718f9cc9f20SBram Moolenaar else if (is_scrollbar_group)
1719f9cc9f20SBram Moolenaar {
1720f9cc9f20SBram Moolenaar if (gui.in_use && do_colors)
1721f9cc9f20SBram Moolenaar gui_new_scrollbar_colors();
1722f9cc9f20SBram Moolenaar else
1723f9cc9f20SBram Moolenaar set_hl_attr(idx);
1724f9cc9f20SBram Moolenaar }
1725f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI
1726f9cc9f20SBram Moolenaar else if (is_tooltip_group)
1727f9cc9f20SBram Moolenaar {
1728f9cc9f20SBram Moolenaar if (gui.in_use && do_colors)
1729f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors();
1730f9cc9f20SBram Moolenaar }
1731f9cc9f20SBram Moolenaar # endif
1732f9cc9f20SBram Moolenaar #endif
1733f9cc9f20SBram Moolenaar else
1734f9cc9f20SBram Moolenaar set_hl_attr(idx);
1735f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL
1736f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_script_ctx = current_sctx;
17371a47ae32SBram Moolenaar HL_TABLE()[idx].sg_script_ctx.sc_lnum += SOURCING_LNUM;
1738f9cc9f20SBram Moolenaar #endif
1739f9cc9f20SBram Moolenaar }
1740f9cc9f20SBram Moolenaar
1741f9cc9f20SBram Moolenaar vim_free(key);
1742f9cc9f20SBram Moolenaar vim_free(arg);
1743f9cc9f20SBram Moolenaar
1744f9cc9f20SBram Moolenaar // Only call highlight_changed() once, after a sequence of highlight
1745f9cc9f20SBram Moolenaar // commands, and only if an attribute actually changed.
1746f9cc9f20SBram Moolenaar if ((did_change
1747f9cc9f20SBram Moolenaar || memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0)
1748f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1749f9cc9f20SBram Moolenaar && !did_highlight_changed
1750f9cc9f20SBram Moolenaar #endif
1751f9cc9f20SBram Moolenaar )
1752f9cc9f20SBram Moolenaar {
1753f9cc9f20SBram Moolenaar // Do not trigger a redraw when highlighting is changed while
1754f9cc9f20SBram Moolenaar // redrawing. This may happen when evaluating 'statusline' changes the
1755f9cc9f20SBram Moolenaar // StatusLine group.
1756f9cc9f20SBram Moolenaar if (!updating_screen)
1757f9cc9f20SBram Moolenaar redraw_all_later(NOT_VALID);
1758f9cc9f20SBram Moolenaar need_highlight_changed = TRUE;
1759f9cc9f20SBram Moolenaar }
1760f9cc9f20SBram Moolenaar }
1761f9cc9f20SBram Moolenaar
1762f9cc9f20SBram Moolenaar #if defined(EXITFREE) || defined(PROTO)
1763f9cc9f20SBram Moolenaar void
free_highlight(void)1764f9cc9f20SBram Moolenaar free_highlight(void)
1765f9cc9f20SBram Moolenaar {
1766f9cc9f20SBram Moolenaar int i;
1767f9cc9f20SBram Moolenaar
1768f9cc9f20SBram Moolenaar for (i = 0; i < highlight_ga.ga_len; ++i)
1769f9cc9f20SBram Moolenaar {
1770f9cc9f20SBram Moolenaar highlight_clear(i);
1771f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[i].sg_name);
1772f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[i].sg_name_u);
1773f9cc9f20SBram Moolenaar }
1774f9cc9f20SBram Moolenaar ga_clear(&highlight_ga);
1775f9cc9f20SBram Moolenaar }
1776f9cc9f20SBram Moolenaar #endif
1777f9cc9f20SBram Moolenaar
1778f9cc9f20SBram Moolenaar /*
1779f9cc9f20SBram Moolenaar * Reset the cterm colors to what they were before Vim was started, if
1780f9cc9f20SBram Moolenaar * possible. Otherwise reset them to zero.
1781f9cc9f20SBram Moolenaar */
1782f9cc9f20SBram Moolenaar void
restore_cterm_colors(void)1783f9cc9f20SBram Moolenaar restore_cterm_colors(void)
1784f9cc9f20SBram Moolenaar {
1785f9cc9f20SBram Moolenaar #if defined(MSWIN) && !defined(FEAT_GUI_MSWIN)
1786f9cc9f20SBram Moolenaar // Since t_me has been set, this probably means that the user
1787f9cc9f20SBram Moolenaar // wants to use this as default colors. Need to reset default
1788f9cc9f20SBram Moolenaar // background/foreground colors.
1789f9cc9f20SBram Moolenaar mch_set_normal_colors();
1790f9cc9f20SBram Moolenaar #else
1791f9cc9f20SBram Moolenaar # ifdef VIMDLL
1792f9cc9f20SBram Moolenaar if (!gui.in_use)
1793f9cc9f20SBram Moolenaar {
1794f9cc9f20SBram Moolenaar mch_set_normal_colors();
1795f9cc9f20SBram Moolenaar return;
1796f9cc9f20SBram Moolenaar }
1797f9cc9f20SBram Moolenaar # endif
1798f9cc9f20SBram Moolenaar cterm_normal_fg_color = 0;
1799f9cc9f20SBram Moolenaar cterm_normal_fg_bold = 0;
1800f9cc9f20SBram Moolenaar cterm_normal_bg_color = 0;
1801f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS
1802f9cc9f20SBram Moolenaar cterm_normal_fg_gui_color = INVALCOLOR;
1803f9cc9f20SBram Moolenaar cterm_normal_bg_gui_color = INVALCOLOR;
1804e023e88bSBram Moolenaar cterm_normal_ul_gui_color = INVALCOLOR;
1805f9cc9f20SBram Moolenaar # endif
1806f9cc9f20SBram Moolenaar #endif
1807f9cc9f20SBram Moolenaar }
1808f9cc9f20SBram Moolenaar
1809f9cc9f20SBram Moolenaar /*
1810f9cc9f20SBram Moolenaar * Return TRUE if highlight group "idx" has any settings.
1811f9cc9f20SBram Moolenaar * When "check_link" is TRUE also check for an existing link.
1812f9cc9f20SBram Moolenaar */
1813f9cc9f20SBram Moolenaar static int
hl_has_settings(int idx,int check_link)1814f9cc9f20SBram Moolenaar hl_has_settings(int idx, int check_link)
1815f9cc9f20SBram Moolenaar {
181605eb5b9cSBram Moolenaar return HL_TABLE()[idx].sg_cleared == 0
181705eb5b9cSBram Moolenaar && ( HL_TABLE()[idx].sg_term_attr != 0
1818f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_attr != 0
1819f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_fg != 0
1820f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_bg != 0
1821f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
1822f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_attr != 0
1823f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_fg_name != NULL
1824f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_bg_name != NULL
1825f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_sp_name != NULL
1826f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_font_name != NULL
1827f9cc9f20SBram Moolenaar #endif
1828f9cc9f20SBram Moolenaar || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK)));
1829f9cc9f20SBram Moolenaar }
1830f9cc9f20SBram Moolenaar
1831f9cc9f20SBram Moolenaar /*
1832f9cc9f20SBram Moolenaar * Clear highlighting for one group.
1833f9cc9f20SBram Moolenaar */
1834f9cc9f20SBram Moolenaar static void
highlight_clear(int idx)1835f9cc9f20SBram Moolenaar highlight_clear(int idx)
1836f9cc9f20SBram Moolenaar {
1837f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cleared = TRUE;
1838f9cc9f20SBram Moolenaar
1839f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term = 0;
1840f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_start);
1841f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_stop);
1842f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term_attr = 0;
1843f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm = 0;
1844f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = FALSE;
1845f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_fg = 0;
1846f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bg = 0;
1847f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_attr = 0;
1848f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL)
1849f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui = 0;
1850f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_fg_name);
1851f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_bg_name);
1852f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_sp_name);
1853f9cc9f20SBram Moolenaar #endif
1854f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
1855f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg = INVALCOLOR;
1856f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg = INVALCOLOR;
1857e023e88bSBram Moolenaar HL_TABLE()[idx].sg_gui_sp = INVALCOLOR;
1858f9cc9f20SBram Moolenaar #endif
1859f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
1860f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font);
1861f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT;
1862f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
1863f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset);
1864f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET;
1865f9cc9f20SBram Moolenaar # endif
1866f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_font_name);
1867f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_attr = 0;
1868f9cc9f20SBram Moolenaar #endif
1869e8df0104SBram Moolenaar // Restore default link and context if they exist. Otherwise clears.
1870213da551SBram Moolenaar HL_TABLE()[idx].sg_link = HL_TABLE()[idx].sg_deflink;
1871e8df0104SBram Moolenaar #ifdef FEAT_EVAL
1872e8df0104SBram Moolenaar // Since we set the default link, set the location to where the default
1873e8df0104SBram Moolenaar // link was set.
1874e8df0104SBram Moolenaar HL_TABLE()[idx].sg_script_ctx = HL_TABLE()[idx].sg_deflink_sctx;
1875f9cc9f20SBram Moolenaar #endif
1876f9cc9f20SBram Moolenaar }
1877f9cc9f20SBram Moolenaar
1878f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO)
1879f9cc9f20SBram Moolenaar /*
1880f9cc9f20SBram Moolenaar * Set the normal foreground and background colors according to the "Normal"
1881f9cc9f20SBram Moolenaar * highlighting group. For X11 also set "Menu", "Scrollbar", and
1882f9cc9f20SBram Moolenaar * "Tooltip" colors.
1883f9cc9f20SBram Moolenaar */
1884f9cc9f20SBram Moolenaar void
set_normal_colors(void)1885f9cc9f20SBram Moolenaar set_normal_colors(void)
1886f9cc9f20SBram Moolenaar {
1887f9cc9f20SBram Moolenaar # ifdef FEAT_GUI
1888f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS
1889f9cc9f20SBram Moolenaar if (gui.in_use)
1890f9cc9f20SBram Moolenaar # endif
1891f9cc9f20SBram Moolenaar {
1892f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Normal",
1893f9cc9f20SBram Moolenaar &gui.norm_pixel, &gui.back_pixel,
1894f9cc9f20SBram Moolenaar FALSE, TRUE, FALSE))
1895f9cc9f20SBram Moolenaar {
1896f9cc9f20SBram Moolenaar gui_mch_new_colors();
1897f9cc9f20SBram Moolenaar must_redraw = CLEAR;
1898f9cc9f20SBram Moolenaar }
1899f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11
1900f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Menu",
1901f9cc9f20SBram Moolenaar &gui.menu_fg_pixel, &gui.menu_bg_pixel,
1902f9cc9f20SBram Moolenaar TRUE, FALSE, FALSE))
1903f9cc9f20SBram Moolenaar {
1904f9cc9f20SBram Moolenaar # ifdef FEAT_MENU
1905f9cc9f20SBram Moolenaar gui_mch_new_menu_colors();
1906f9cc9f20SBram Moolenaar # endif
1907f9cc9f20SBram Moolenaar must_redraw = CLEAR;
1908f9cc9f20SBram Moolenaar }
1909f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI
1910f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Tooltip",
1911f9cc9f20SBram Moolenaar &gui.tooltip_fg_pixel, &gui.tooltip_bg_pixel,
1912f9cc9f20SBram Moolenaar FALSE, FALSE, TRUE))
1913f9cc9f20SBram Moolenaar {
1914f9cc9f20SBram Moolenaar # ifdef FEAT_TOOLBAR
1915f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors();
1916f9cc9f20SBram Moolenaar # endif
1917f9cc9f20SBram Moolenaar must_redraw = CLEAR;
1918f9cc9f20SBram Moolenaar }
1919f9cc9f20SBram Moolenaar # endif
1920f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Scrollbar",
1921f9cc9f20SBram Moolenaar &gui.scroll_fg_pixel, &gui.scroll_bg_pixel,
1922f9cc9f20SBram Moolenaar FALSE, FALSE, FALSE))
1923f9cc9f20SBram Moolenaar {
1924f9cc9f20SBram Moolenaar gui_new_scrollbar_colors();
1925f9cc9f20SBram Moolenaar must_redraw = CLEAR;
1926f9cc9f20SBram Moolenaar }
1927f9cc9f20SBram Moolenaar # endif
1928f9cc9f20SBram Moolenaar }
1929f9cc9f20SBram Moolenaar # endif
1930f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS
1931f9cc9f20SBram Moolenaar # ifdef FEAT_GUI
1932f9cc9f20SBram Moolenaar else
1933f9cc9f20SBram Moolenaar # endif
1934f9cc9f20SBram Moolenaar {
1935f9cc9f20SBram Moolenaar int idx;
1936f9cc9f20SBram Moolenaar
1937f9cc9f20SBram Moolenaar idx = syn_name2id((char_u *)"Normal") - 1;
1938f9cc9f20SBram Moolenaar if (idx >= 0)
1939f9cc9f20SBram Moolenaar {
1940f9cc9f20SBram Moolenaar gui_do_one_color(idx, FALSE, FALSE);
1941f9cc9f20SBram Moolenaar
1942f9cc9f20SBram Moolenaar // If the normal fg or bg color changed a complete redraw is
1943f9cc9f20SBram Moolenaar // required.
1944f9cc9f20SBram Moolenaar if (cterm_normal_fg_gui_color != HL_TABLE()[idx].sg_gui_fg
1945f9cc9f20SBram Moolenaar || cterm_normal_bg_gui_color != HL_TABLE()[idx].sg_gui_bg)
1946f9cc9f20SBram Moolenaar {
1947f9cc9f20SBram Moolenaar // if the GUI color is INVALCOLOR then we use the default cterm
1948f9cc9f20SBram Moolenaar // color
1949f9cc9f20SBram Moolenaar cterm_normal_fg_gui_color = HL_TABLE()[idx].sg_gui_fg;
1950f9cc9f20SBram Moolenaar cterm_normal_bg_gui_color = HL_TABLE()[idx].sg_gui_bg;
1951f9cc9f20SBram Moolenaar must_redraw = CLEAR;
1952f9cc9f20SBram Moolenaar }
1953f9cc9f20SBram Moolenaar }
1954f9cc9f20SBram Moolenaar }
1955f9cc9f20SBram Moolenaar # endif
1956f9cc9f20SBram Moolenaar }
1957f9cc9f20SBram Moolenaar #endif
1958f9cc9f20SBram Moolenaar
1959f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(PROTO)
1960f9cc9f20SBram Moolenaar /*
1961f9cc9f20SBram Moolenaar * Set the colors for "Normal", "Menu", "Tooltip" or "Scrollbar".
1962f9cc9f20SBram Moolenaar */
1963f9cc9f20SBram Moolenaar static int
set_group_colors(char_u * name,guicolor_T * fgp,guicolor_T * bgp,int do_menu,int use_norm,int do_tooltip)1964f9cc9f20SBram Moolenaar set_group_colors(
1965f9cc9f20SBram Moolenaar char_u *name,
1966f9cc9f20SBram Moolenaar guicolor_T *fgp,
1967f9cc9f20SBram Moolenaar guicolor_T *bgp,
1968f9cc9f20SBram Moolenaar int do_menu,
1969f9cc9f20SBram Moolenaar int use_norm,
1970f9cc9f20SBram Moolenaar int do_tooltip)
1971f9cc9f20SBram Moolenaar {
1972f9cc9f20SBram Moolenaar int idx;
1973f9cc9f20SBram Moolenaar
1974f9cc9f20SBram Moolenaar idx = syn_name2id(name) - 1;
1975f9cc9f20SBram Moolenaar if (idx >= 0)
1976f9cc9f20SBram Moolenaar {
1977f9cc9f20SBram Moolenaar gui_do_one_color(idx, do_menu, do_tooltip);
1978f9cc9f20SBram Moolenaar
1979f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_fg != INVALCOLOR)
1980f9cc9f20SBram Moolenaar *fgp = HL_TABLE()[idx].sg_gui_fg;
1981f9cc9f20SBram Moolenaar else if (use_norm)
1982f9cc9f20SBram Moolenaar *fgp = gui.def_norm_pixel;
1983f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_bg != INVALCOLOR)
1984f9cc9f20SBram Moolenaar *bgp = HL_TABLE()[idx].sg_gui_bg;
1985f9cc9f20SBram Moolenaar else if (use_norm)
1986f9cc9f20SBram Moolenaar *bgp = gui.def_back_pixel;
1987f9cc9f20SBram Moolenaar return TRUE;
1988f9cc9f20SBram Moolenaar }
1989f9cc9f20SBram Moolenaar return FALSE;
1990f9cc9f20SBram Moolenaar }
1991f9cc9f20SBram Moolenaar
1992f9cc9f20SBram Moolenaar /*
1993f9cc9f20SBram Moolenaar * Get the font of the "Normal" group.
1994f9cc9f20SBram Moolenaar * Returns "" when it's not found or not set.
1995f9cc9f20SBram Moolenaar */
1996f9cc9f20SBram Moolenaar char_u *
hl_get_font_name(void)1997f9cc9f20SBram Moolenaar hl_get_font_name(void)
1998f9cc9f20SBram Moolenaar {
1999f9cc9f20SBram Moolenaar int id;
2000f9cc9f20SBram Moolenaar char_u *s;
2001f9cc9f20SBram Moolenaar
2002f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal");
2003f9cc9f20SBram Moolenaar if (id > 0)
2004f9cc9f20SBram Moolenaar {
2005f9cc9f20SBram Moolenaar s = HL_TABLE()[id - 1].sg_font_name;
2006f9cc9f20SBram Moolenaar if (s != NULL)
2007f9cc9f20SBram Moolenaar return s;
2008f9cc9f20SBram Moolenaar }
2009f9cc9f20SBram Moolenaar return (char_u *)"";
2010f9cc9f20SBram Moolenaar }
2011f9cc9f20SBram Moolenaar
2012f9cc9f20SBram Moolenaar /*
2013f9cc9f20SBram Moolenaar * Set font for "Normal" group. Called by gui_mch_init_font() when a font has
2014f9cc9f20SBram Moolenaar * actually chosen to be used.
2015f9cc9f20SBram Moolenaar */
2016f9cc9f20SBram Moolenaar void
hl_set_font_name(char_u * font_name)2017f9cc9f20SBram Moolenaar hl_set_font_name(char_u *font_name)
2018f9cc9f20SBram Moolenaar {
2019f9cc9f20SBram Moolenaar int id;
2020f9cc9f20SBram Moolenaar
2021f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal");
2022f9cc9f20SBram Moolenaar if (id > 0)
2023f9cc9f20SBram Moolenaar {
2024f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_font_name);
2025f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_font_name = vim_strsave(font_name);
2026f9cc9f20SBram Moolenaar }
2027f9cc9f20SBram Moolenaar }
2028f9cc9f20SBram Moolenaar
2029f9cc9f20SBram Moolenaar /*
2030f9cc9f20SBram Moolenaar * Set background color for "Normal" group. Called by gui_set_bg_color()
2031f9cc9f20SBram Moolenaar * when the color is known.
2032f9cc9f20SBram Moolenaar */
2033f9cc9f20SBram Moolenaar void
hl_set_bg_color_name(char_u * name)2034f9cc9f20SBram Moolenaar hl_set_bg_color_name(
2035f9cc9f20SBram Moolenaar char_u *name) // must have been allocated
2036f9cc9f20SBram Moolenaar {
2037f9cc9f20SBram Moolenaar int id;
2038f9cc9f20SBram Moolenaar
2039f9cc9f20SBram Moolenaar if (name != NULL)
2040f9cc9f20SBram Moolenaar {
2041f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal");
2042f9cc9f20SBram Moolenaar if (id > 0)
2043f9cc9f20SBram Moolenaar {
2044f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_gui_bg_name);
2045f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_gui_bg_name = name;
2046f9cc9f20SBram Moolenaar }
2047f9cc9f20SBram Moolenaar }
2048f9cc9f20SBram Moolenaar }
2049f9cc9f20SBram Moolenaar
2050f9cc9f20SBram Moolenaar /*
2051f9cc9f20SBram Moolenaar * Set foreground color for "Normal" group. Called by gui_set_fg_color()
2052f9cc9f20SBram Moolenaar * when the color is known.
2053f9cc9f20SBram Moolenaar */
2054f9cc9f20SBram Moolenaar void
hl_set_fg_color_name(char_u * name)2055f9cc9f20SBram Moolenaar hl_set_fg_color_name(
2056f9cc9f20SBram Moolenaar char_u *name) // must have been allocated
2057f9cc9f20SBram Moolenaar {
2058f9cc9f20SBram Moolenaar int id;
2059f9cc9f20SBram Moolenaar
2060f9cc9f20SBram Moolenaar if (name != NULL)
2061f9cc9f20SBram Moolenaar {
2062f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal");
2063f9cc9f20SBram Moolenaar if (id > 0)
2064f9cc9f20SBram Moolenaar {
2065f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_gui_fg_name);
2066f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_gui_fg_name = name;
2067f9cc9f20SBram Moolenaar }
2068f9cc9f20SBram Moolenaar }
2069f9cc9f20SBram Moolenaar }
2070f9cc9f20SBram Moolenaar
2071f9cc9f20SBram Moolenaar /*
2072f9cc9f20SBram Moolenaar * Return the handle for a font name.
2073f9cc9f20SBram Moolenaar * Returns NOFONT when failed.
2074f9cc9f20SBram Moolenaar */
2075f9cc9f20SBram Moolenaar static GuiFont
font_name2handle(char_u * name)2076f9cc9f20SBram Moolenaar font_name2handle(char_u *name)
2077f9cc9f20SBram Moolenaar {
2078f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0)
2079f9cc9f20SBram Moolenaar return NOFONT;
2080f9cc9f20SBram Moolenaar
2081f9cc9f20SBram Moolenaar return gui_mch_get_font(name, TRUE);
2082f9cc9f20SBram Moolenaar }
2083f9cc9f20SBram Moolenaar
2084f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
2085f9cc9f20SBram Moolenaar /*
2086f9cc9f20SBram Moolenaar * Return the handle for a fontset name.
2087f9cc9f20SBram Moolenaar * Returns NOFONTSET when failed.
2088f9cc9f20SBram Moolenaar */
2089f9cc9f20SBram Moolenaar static GuiFontset
fontset_name2handle(char_u * name,int fixed_width)2090f9cc9f20SBram Moolenaar fontset_name2handle(char_u *name, int fixed_width)
2091f9cc9f20SBram Moolenaar {
2092f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0)
2093f9cc9f20SBram Moolenaar return NOFONTSET;
2094f9cc9f20SBram Moolenaar
2095f9cc9f20SBram Moolenaar return gui_mch_get_fontset(name, TRUE, fixed_width);
2096f9cc9f20SBram Moolenaar }
2097f9cc9f20SBram Moolenaar # endif
2098f9cc9f20SBram Moolenaar
2099f9cc9f20SBram Moolenaar /*
2100f9cc9f20SBram Moolenaar * Get the font or fontset for one highlight group.
2101f9cc9f20SBram Moolenaar */
2102f9cc9f20SBram Moolenaar static void
hl_do_font(int idx,char_u * arg,int do_normal,int do_menu UNUSED,int do_tooltip UNUSED,int free_font)2103f9cc9f20SBram Moolenaar hl_do_font(
2104f9cc9f20SBram Moolenaar int idx,
2105f9cc9f20SBram Moolenaar char_u *arg,
2106f9cc9f20SBram Moolenaar int do_normal, // set normal font
2107f9cc9f20SBram Moolenaar int do_menu UNUSED, // set menu font
2108f9cc9f20SBram Moolenaar int do_tooltip UNUSED, // set tooltip font
2109f9cc9f20SBram Moolenaar int free_font) // free current font/fontset
2110f9cc9f20SBram Moolenaar {
2111f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
2112f9cc9f20SBram Moolenaar // If 'guifontset' is not empty, first try using the name as a
2113f9cc9f20SBram Moolenaar // fontset. If that doesn't work, use it as a font name.
2114f9cc9f20SBram Moolenaar if (*p_guifontset != NUL
2115f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS
2116f9cc9f20SBram Moolenaar || do_menu
2117f9cc9f20SBram Moolenaar # endif
2118f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP
2119f9cc9f20SBram Moolenaar // In Athena & Motif, the Tooltip highlight group is always a fontset
2120f9cc9f20SBram Moolenaar || do_tooltip
2121f9cc9f20SBram Moolenaar # endif
2122f9cc9f20SBram Moolenaar )
2123f9cc9f20SBram Moolenaar {
2124f9cc9f20SBram Moolenaar if (free_font)
2125f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset);
2126f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = fontset_name2handle(arg, 0
2127f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS
2128f9cc9f20SBram Moolenaar || do_menu
2129f9cc9f20SBram Moolenaar # endif
2130f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP
2131f9cc9f20SBram Moolenaar || do_tooltip
2132f9cc9f20SBram Moolenaar # endif
2133f9cc9f20SBram Moolenaar );
2134f9cc9f20SBram Moolenaar }
2135f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_fontset != NOFONTSET)
2136f9cc9f20SBram Moolenaar {
2137f9cc9f20SBram Moolenaar // If it worked and it's the Normal group, use it as the normal
2138f9cc9f20SBram Moolenaar // fontset. Same for the Menu group.
2139f9cc9f20SBram Moolenaar if (do_normal)
2140f9cc9f20SBram Moolenaar gui_init_font(arg, TRUE);
2141f9cc9f20SBram Moolenaar # if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU)
2142f9cc9f20SBram Moolenaar if (do_menu)
2143f9cc9f20SBram Moolenaar {
2144f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS
2145f9cc9f20SBram Moolenaar gui.menu_fontset = HL_TABLE()[idx].sg_fontset;
2146f9cc9f20SBram Moolenaar # else
2147f9cc9f20SBram Moolenaar // YIKES! This is a bug waiting to crash the program
2148f9cc9f20SBram Moolenaar gui.menu_font = HL_TABLE()[idx].sg_fontset;
2149f9cc9f20SBram Moolenaar # endif
2150f9cc9f20SBram Moolenaar gui_mch_new_menu_font();
2151f9cc9f20SBram Moolenaar }
2152f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI
2153f9cc9f20SBram Moolenaar if (do_tooltip)
2154f9cc9f20SBram Moolenaar {
2155f9cc9f20SBram Moolenaar // The Athena widget set cannot currently handle switching between
2156f9cc9f20SBram Moolenaar // displaying a single font and a fontset.
2157f9cc9f20SBram Moolenaar // If the XtNinternational resource is set to True at widget
2158f9cc9f20SBram Moolenaar // creation, then a fontset is always used, otherwise an
2159f9cc9f20SBram Moolenaar // XFontStruct is used.
2160f9cc9f20SBram Moolenaar gui.tooltip_fontset = (XFontSet)HL_TABLE()[idx].sg_fontset;
2161f9cc9f20SBram Moolenaar gui_mch_new_tooltip_font();
2162f9cc9f20SBram Moolenaar }
2163f9cc9f20SBram Moolenaar # endif
2164f9cc9f20SBram Moolenaar # endif
2165f9cc9f20SBram Moolenaar }
2166f9cc9f20SBram Moolenaar else
2167f9cc9f20SBram Moolenaar # endif
2168f9cc9f20SBram Moolenaar {
2169f9cc9f20SBram Moolenaar if (free_font)
2170f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font);
2171f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = font_name2handle(arg);
2172f9cc9f20SBram Moolenaar // If it worked and it's the Normal group, use it as the
2173f9cc9f20SBram Moolenaar // normal font. Same for the Menu group.
2174f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font != NOFONT)
2175f9cc9f20SBram Moolenaar {
2176f9cc9f20SBram Moolenaar if (do_normal)
2177f9cc9f20SBram Moolenaar gui_init_font(arg, FALSE);
2178f9cc9f20SBram Moolenaar #ifndef FONTSET_ALWAYS
2179f9cc9f20SBram Moolenaar # if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU)
2180f9cc9f20SBram Moolenaar if (do_menu)
2181f9cc9f20SBram Moolenaar {
2182f9cc9f20SBram Moolenaar gui.menu_font = HL_TABLE()[idx].sg_font;
2183f9cc9f20SBram Moolenaar gui_mch_new_menu_font();
2184f9cc9f20SBram Moolenaar }
2185f9cc9f20SBram Moolenaar # endif
2186f9cc9f20SBram Moolenaar #endif
2187f9cc9f20SBram Moolenaar }
2188f9cc9f20SBram Moolenaar }
2189f9cc9f20SBram Moolenaar }
2190f9cc9f20SBram Moolenaar
2191f9cc9f20SBram Moolenaar #endif // FEAT_GUI
2192f9cc9f20SBram Moolenaar
2193f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO)
2194f9cc9f20SBram Moolenaar /*
2195f9cc9f20SBram Moolenaar * Return the handle for a color name.
2196f9cc9f20SBram Moolenaar * Returns INVALCOLOR when failed.
2197f9cc9f20SBram Moolenaar */
2198f9cc9f20SBram Moolenaar guicolor_T
color_name2handle(char_u * name)2199f9cc9f20SBram Moolenaar color_name2handle(char_u *name)
2200f9cc9f20SBram Moolenaar {
2201f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0)
2202f9cc9f20SBram Moolenaar return INVALCOLOR;
2203f9cc9f20SBram Moolenaar
2204f9cc9f20SBram Moolenaar if (STRICMP(name, "fg") == 0 || STRICMP(name, "foreground") == 0)
2205f9cc9f20SBram Moolenaar {
2206f9cc9f20SBram Moolenaar #if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI)
2207f9cc9f20SBram Moolenaar if (gui.in_use)
2208f9cc9f20SBram Moolenaar #endif
2209f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2210f9cc9f20SBram Moolenaar return gui.norm_pixel;
2211f9cc9f20SBram Moolenaar #endif
2212f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS
2213f9cc9f20SBram Moolenaar if (cterm_normal_fg_gui_color != INVALCOLOR)
2214f9cc9f20SBram Moolenaar return cterm_normal_fg_gui_color;
2215f9cc9f20SBram Moolenaar // Guess that the foreground is black or white.
2216f9cc9f20SBram Moolenaar return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "black" : "white"));
2217f9cc9f20SBram Moolenaar #endif
2218f9cc9f20SBram Moolenaar }
2219f9cc9f20SBram Moolenaar if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0)
2220f9cc9f20SBram Moolenaar {
2221f9cc9f20SBram Moolenaar #if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI)
2222f9cc9f20SBram Moolenaar if (gui.in_use)
2223f9cc9f20SBram Moolenaar #endif
2224f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2225f9cc9f20SBram Moolenaar return gui.back_pixel;
2226f9cc9f20SBram Moolenaar #endif
2227f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS
2228f9cc9f20SBram Moolenaar if (cterm_normal_bg_gui_color != INVALCOLOR)
2229f9cc9f20SBram Moolenaar return cterm_normal_bg_gui_color;
2230f9cc9f20SBram Moolenaar // Guess that the background is white or black.
2231f9cc9f20SBram Moolenaar return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "white" : "black"));
2232f9cc9f20SBram Moolenaar #endif
2233f9cc9f20SBram Moolenaar }
2234f9cc9f20SBram Moolenaar
2235f9cc9f20SBram Moolenaar return GUI_GET_COLOR(name);
2236f9cc9f20SBram Moolenaar }
2237e30d1025SDrew Vogel
2238e30d1025SDrew Vogel // On MS-Windows an RGB macro is available and it produces 0x00bbggrr color
2239e30d1025SDrew Vogel // values as used by the MS-Windows GDI api. It should be used only for
2240e30d1025SDrew Vogel // MS-Windows GDI builds.
2241e30d1025SDrew Vogel # if defined(RGB) && defined(MSWIN) && !defined(FEAT_GUI)
2242e30d1025SDrew Vogel # undef RGB
2243e30d1025SDrew Vogel # endif
2244e30d1025SDrew Vogel # ifndef RGB
2245e30d1025SDrew Vogel # define RGB(r, g, b) ((r<<16) | (g<<8) | (b))
2246e30d1025SDrew Vogel # endif
2247e30d1025SDrew Vogel
2248e30d1025SDrew Vogel # ifdef VIMDLL
2249e30d1025SDrew Vogel static guicolor_T
gui_adjust_rgb(guicolor_T c)2250e30d1025SDrew Vogel gui_adjust_rgb(guicolor_T c)
2251e30d1025SDrew Vogel {
2252e30d1025SDrew Vogel if (gui.in_use)
2253e30d1025SDrew Vogel return c;
2254e30d1025SDrew Vogel else
2255e30d1025SDrew Vogel return ((c & 0xff) << 16) | (c & 0x00ff00) | ((c >> 16) & 0xff);
2256e30d1025SDrew Vogel }
2257e30d1025SDrew Vogel # else
2258e30d1025SDrew Vogel # define gui_adjust_rgb(c) (c)
2259e30d1025SDrew Vogel # endif
2260e30d1025SDrew Vogel
2261e30d1025SDrew Vogel static int
hex_digit(int c)2262e30d1025SDrew Vogel hex_digit(int c)
2263e30d1025SDrew Vogel {
2264e30d1025SDrew Vogel if (isdigit(c))
2265e30d1025SDrew Vogel return c - '0';
2266e30d1025SDrew Vogel c = TOLOWER_ASC(c);
2267e30d1025SDrew Vogel if (c >= 'a' && c <= 'f')
2268e30d1025SDrew Vogel return c - 'a' + 10;
2269e30d1025SDrew Vogel return 0x1ffffff;
2270e30d1025SDrew Vogel }
2271e30d1025SDrew Vogel
2272e30d1025SDrew Vogel guicolor_T
decode_hex_color(char_u * hex)2273e30d1025SDrew Vogel decode_hex_color(char_u *hex)
2274e30d1025SDrew Vogel {
2275e30d1025SDrew Vogel guicolor_T color;
2276e30d1025SDrew Vogel
2277e30d1025SDrew Vogel if (hex[0] != '#' || STRLEN(hex) != 7)
2278e30d1025SDrew Vogel return INVALCOLOR;
2279e30d1025SDrew Vogel
2280e30d1025SDrew Vogel // Name is in "#rrggbb" format
2281e30d1025SDrew Vogel color = RGB(((hex_digit(hex[1]) << 4) + hex_digit(hex[2])),
2282e30d1025SDrew Vogel ((hex_digit(hex[3]) << 4) + hex_digit(hex[4])),
2283e30d1025SDrew Vogel ((hex_digit(hex[5]) << 4) + hex_digit(hex[6])));
2284e30d1025SDrew Vogel if (color > 0xffffff)
2285e30d1025SDrew Vogel return INVALCOLOR;
2286e30d1025SDrew Vogel return gui_adjust_rgb(color);
2287e30d1025SDrew Vogel }
2288e30d1025SDrew Vogel
22892a52196bSBram Moolenaar #ifdef FEAT_EVAL
2290e30d1025SDrew Vogel // Returns the color currently mapped to the given name or INVALCOLOR if no
2291e30d1025SDrew Vogel // such name exists in the color table. The convention is to use lowercase for
2292e30d1025SDrew Vogel // all keys in the v:colornames dictionary. The value can be either a string in
2293e30d1025SDrew Vogel // the form #rrggbb or a number, either of which is converted to a guicolor_T.
2294e30d1025SDrew Vogel guicolor_T
colorname2rgb(char_u * name)2295e30d1025SDrew Vogel colorname2rgb(char_u *name)
2296e30d1025SDrew Vogel {
2297e30d1025SDrew Vogel dict_T *colornames_table = get_vim_var_dict(VV_COLORNAMES);
2298e30d1025SDrew Vogel char_u *lc_name;
2299e30d1025SDrew Vogel dictitem_T *colentry;
2300e30d1025SDrew Vogel char_u *colstr;
2301e30d1025SDrew Vogel varnumber_T colnum;
2302e30d1025SDrew Vogel
2303e30d1025SDrew Vogel lc_name = strlow_save(name);
2304e30d1025SDrew Vogel if (lc_name == NULL)
2305e30d1025SDrew Vogel return INVALCOLOR;
2306e30d1025SDrew Vogel
2307e30d1025SDrew Vogel colentry = dict_find(colornames_table, lc_name, -1);
2308e30d1025SDrew Vogel vim_free(lc_name);
2309e30d1025SDrew Vogel if (colentry == NULL)
2310e30d1025SDrew Vogel return INVALCOLOR;
2311e30d1025SDrew Vogel
2312e30d1025SDrew Vogel if (colentry->di_tv.v_type == VAR_STRING)
2313e30d1025SDrew Vogel {
2314e30d1025SDrew Vogel colstr = tv_get_string_strict(&colentry->di_tv);
2315e30d1025SDrew Vogel if ((STRLEN(colstr) == 7) && (*colstr == '#'))
2316e30d1025SDrew Vogel {
2317e30d1025SDrew Vogel return decode_hex_color(colstr);
2318e30d1025SDrew Vogel }
2319e30d1025SDrew Vogel else
2320e30d1025SDrew Vogel {
2321e30d1025SDrew Vogel semsg(_(e_bad_color_string_str), colstr);
2322e30d1025SDrew Vogel return INVALCOLOR;
2323e30d1025SDrew Vogel }
2324e30d1025SDrew Vogel }
2325e30d1025SDrew Vogel
2326e30d1025SDrew Vogel if (colentry->di_tv.v_type == VAR_NUMBER)
2327e30d1025SDrew Vogel {
2328e30d1025SDrew Vogel colnum = tv_get_number(&colentry->di_tv);
2329e30d1025SDrew Vogel return (guicolor_T)colnum;
2330e30d1025SDrew Vogel }
2331e30d1025SDrew Vogel
2332e30d1025SDrew Vogel return INVALCOLOR;
2333e30d1025SDrew Vogel }
2334e30d1025SDrew Vogel
2335e30d1025SDrew Vogel /*
2336e30d1025SDrew Vogel * Load a default color list. Intended to support legacy color names but allows
2337e30d1025SDrew Vogel * the user to override the color values. Only loaded once.
2338e30d1025SDrew Vogel */
2339e30d1025SDrew Vogel void
load_default_colors_lists()2340e30d1025SDrew Vogel load_default_colors_lists()
2341e30d1025SDrew Vogel {
2342e30d1025SDrew Vogel // Lacking a default color list isn't the end of the world but it is likely
2343e30d1025SDrew Vogel // an inconvenience so users should know when it is missing.
2344e30d1025SDrew Vogel if (source_runtime((char_u *)"colors/lists/default.vim", DIP_ALL) != OK)
2345e30d1025SDrew Vogel msg("failed to load colors/lists/default.vim");
2346e30d1025SDrew Vogel }
2347e30d1025SDrew Vogel #endif
2348e30d1025SDrew Vogel
2349e30d1025SDrew Vogel guicolor_T
gui_get_color_cmn(char_u * name)2350e30d1025SDrew Vogel gui_get_color_cmn(char_u *name)
2351e30d1025SDrew Vogel {
2352e30d1025SDrew Vogel int i;
2353e30d1025SDrew Vogel guicolor_T color;
2354e30d1025SDrew Vogel
2355e30d1025SDrew Vogel struct rgbcolor_table_S {
2356e30d1025SDrew Vogel char_u *color_name;
2357e30d1025SDrew Vogel guicolor_T color;
2358e30d1025SDrew Vogel };
2359e30d1025SDrew Vogel
2360e30d1025SDrew Vogel // Only non X11 colors (not present in rgb.txt) and colors in
2361e30d1025SDrew Vogel // color_names[], useful when $VIMRUNTIME is not found,.
2362e30d1025SDrew Vogel static struct rgbcolor_table_S rgb_table[] = {
2363e30d1025SDrew Vogel {(char_u *)"black", RGB(0x00, 0x00, 0x00)},
2364e30d1025SDrew Vogel {(char_u *)"blue", RGB(0x00, 0x00, 0xFF)},
2365e30d1025SDrew Vogel {(char_u *)"brown", RGB(0xA5, 0x2A, 0x2A)},
2366e30d1025SDrew Vogel {(char_u *)"cyan", RGB(0x00, 0xFF, 0xFF)},
2367e30d1025SDrew Vogel {(char_u *)"darkblue", RGB(0x00, 0x00, 0x8B)},
2368e30d1025SDrew Vogel {(char_u *)"darkcyan", RGB(0x00, 0x8B, 0x8B)},
2369e30d1025SDrew Vogel {(char_u *)"darkgray", RGB(0xA9, 0xA9, 0xA9)},
2370e30d1025SDrew Vogel {(char_u *)"darkgreen", RGB(0x00, 0x64, 0x00)},
2371e30d1025SDrew Vogel {(char_u *)"darkgrey", RGB(0xA9, 0xA9, 0xA9)},
2372e30d1025SDrew Vogel {(char_u *)"darkmagenta", RGB(0x8B, 0x00, 0x8B)},
2373e30d1025SDrew Vogel {(char_u *)"darkred", RGB(0x8B, 0x00, 0x00)},
2374e30d1025SDrew Vogel {(char_u *)"darkyellow", RGB(0x8B, 0x8B, 0x00)}, // No X11
2375e30d1025SDrew Vogel {(char_u *)"gray", RGB(0xBE, 0xBE, 0xBE)},
2376e30d1025SDrew Vogel {(char_u *)"green", RGB(0x00, 0xFF, 0x00)},
2377e30d1025SDrew Vogel {(char_u *)"grey", RGB(0xBE, 0xBE, 0xBE)},
2378e30d1025SDrew Vogel {(char_u *)"grey40", RGB(0x66, 0x66, 0x66)},
2379e30d1025SDrew Vogel {(char_u *)"grey50", RGB(0x7F, 0x7F, 0x7F)},
2380e30d1025SDrew Vogel {(char_u *)"grey90", RGB(0xE5, 0xE5, 0xE5)},
2381e30d1025SDrew Vogel {(char_u *)"lightblue", RGB(0xAD, 0xD8, 0xE6)},
2382e30d1025SDrew Vogel {(char_u *)"lightcyan", RGB(0xE0, 0xFF, 0xFF)},
2383e30d1025SDrew Vogel {(char_u *)"lightgray", RGB(0xD3, 0xD3, 0xD3)},
2384e30d1025SDrew Vogel {(char_u *)"lightgreen", RGB(0x90, 0xEE, 0x90)},
2385e30d1025SDrew Vogel {(char_u *)"lightgrey", RGB(0xD3, 0xD3, 0xD3)},
2386e30d1025SDrew Vogel {(char_u *)"lightmagenta", RGB(0xFF, 0x8B, 0xFF)}, // No X11
2387e30d1025SDrew Vogel {(char_u *)"lightred", RGB(0xFF, 0x8B, 0x8B)}, // No X11
2388e30d1025SDrew Vogel {(char_u *)"lightyellow", RGB(0xFF, 0xFF, 0xE0)},
2389e30d1025SDrew Vogel {(char_u *)"magenta", RGB(0xFF, 0x00, 0xFF)},
2390e30d1025SDrew Vogel {(char_u *)"red", RGB(0xFF, 0x00, 0x00)},
2391e30d1025SDrew Vogel {(char_u *)"seagreen", RGB(0x2E, 0x8B, 0x57)},
2392e30d1025SDrew Vogel {(char_u *)"white", RGB(0xFF, 0xFF, 0xFF)},
2393e30d1025SDrew Vogel {(char_u *)"yellow", RGB(0xFF, 0xFF, 0x00)},
2394e30d1025SDrew Vogel };
2395e30d1025SDrew Vogel
2396e30d1025SDrew Vogel color = decode_hex_color(name);
2397e30d1025SDrew Vogel if (color != INVALCOLOR)
2398e30d1025SDrew Vogel return color;
2399e30d1025SDrew Vogel
2400e30d1025SDrew Vogel // Check if the name is one of the colors we know
2401e30d1025SDrew Vogel for (i = 0; i < (int)ARRAY_LENGTH(rgb_table); i++)
2402e30d1025SDrew Vogel if (STRICMP(name, rgb_table[i].color_name) == 0)
2403e30d1025SDrew Vogel return gui_adjust_rgb(rgb_table[i].color);
2404e30d1025SDrew Vogel
2405e30d1025SDrew Vogel #if defined(FEAT_EVAL)
2406e30d1025SDrew Vogel /*
2407e30d1025SDrew Vogel * Not a traditional color. Load additional color aliases and then consult the alias table.
2408e30d1025SDrew Vogel */
2409e30d1025SDrew Vogel
2410e30d1025SDrew Vogel color = colorname2rgb(name);
2411e30d1025SDrew Vogel if (color == INVALCOLOR)
2412e30d1025SDrew Vogel {
2413e30d1025SDrew Vogel load_default_colors_lists();
2414e30d1025SDrew Vogel color = colorname2rgb(name);
2415e30d1025SDrew Vogel }
2416e30d1025SDrew Vogel
2417e30d1025SDrew Vogel return color;
2418e30d1025SDrew Vogel #else
2419e30d1025SDrew Vogel return INVALCOLOR;
2420e30d1025SDrew Vogel #endif
2421e30d1025SDrew Vogel }
2422e30d1025SDrew Vogel
2423e30d1025SDrew Vogel guicolor_T
gui_get_rgb_color_cmn(int r,int g,int b)2424e30d1025SDrew Vogel gui_get_rgb_color_cmn(int r, int g, int b)
2425e30d1025SDrew Vogel {
2426e30d1025SDrew Vogel guicolor_T color = RGB(r, g, b);
2427e30d1025SDrew Vogel
2428e30d1025SDrew Vogel if (color > 0xffffff)
2429e30d1025SDrew Vogel return INVALCOLOR;
2430e30d1025SDrew Vogel return gui_adjust_rgb(color);
2431e30d1025SDrew Vogel }
2432f9cc9f20SBram Moolenaar #endif
2433f9cc9f20SBram Moolenaar
2434f9cc9f20SBram Moolenaar /*
2435f9cc9f20SBram Moolenaar * Table with the specifications for an attribute number.
2436f9cc9f20SBram Moolenaar * Note that this table is used by ALL buffers. This is required because the
2437f9cc9f20SBram Moolenaar * GUI can redraw at any time for any buffer.
2438f9cc9f20SBram Moolenaar */
2439f9cc9f20SBram Moolenaar static garray_T term_attr_table = {0, 0, 0, 0, NULL};
2440f9cc9f20SBram Moolenaar
2441f9cc9f20SBram Moolenaar #define TERM_ATTR_ENTRY(idx) ((attrentry_T *)term_attr_table.ga_data)[idx]
2442f9cc9f20SBram Moolenaar
2443f9cc9f20SBram Moolenaar static garray_T cterm_attr_table = {0, 0, 0, 0, NULL};
2444f9cc9f20SBram Moolenaar
2445f9cc9f20SBram Moolenaar #define CTERM_ATTR_ENTRY(idx) ((attrentry_T *)cterm_attr_table.ga_data)[idx]
2446f9cc9f20SBram Moolenaar
2447f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2448f9cc9f20SBram Moolenaar static garray_T gui_attr_table = {0, 0, 0, 0, NULL};
2449f9cc9f20SBram Moolenaar
2450f9cc9f20SBram Moolenaar #define GUI_ATTR_ENTRY(idx) ((attrentry_T *)gui_attr_table.ga_data)[idx]
2451f9cc9f20SBram Moolenaar #endif
2452f9cc9f20SBram Moolenaar
2453f9cc9f20SBram Moolenaar /*
2454f9cc9f20SBram Moolenaar * Return the attr number for a set of colors and font.
2455f9cc9f20SBram Moolenaar * Add a new entry to the term_attr_table, cterm_attr_table or gui_attr_table
2456f9cc9f20SBram Moolenaar * if the combination is new.
2457f9cc9f20SBram Moolenaar * Return 0 for error (no more room).
2458f9cc9f20SBram Moolenaar */
2459f9cc9f20SBram Moolenaar static int
get_attr_entry(garray_T * table,attrentry_T * aep)2460f9cc9f20SBram Moolenaar get_attr_entry(garray_T *table, attrentry_T *aep)
2461f9cc9f20SBram Moolenaar {
2462f9cc9f20SBram Moolenaar int i;
2463f9cc9f20SBram Moolenaar attrentry_T *taep;
2464f9cc9f20SBram Moolenaar static int recursive = FALSE;
2465f9cc9f20SBram Moolenaar
2466ad6b90c3SYegappan Lakshmanan // Init the table, in case it wasn't done yet.
2467f9cc9f20SBram Moolenaar table->ga_itemsize = sizeof(attrentry_T);
2468f9cc9f20SBram Moolenaar table->ga_growsize = 7;
2469f9cc9f20SBram Moolenaar
2470ad6b90c3SYegappan Lakshmanan // Try to find an entry with the same specifications.
2471f9cc9f20SBram Moolenaar for (i = 0; i < table->ga_len; ++i)
2472f9cc9f20SBram Moolenaar {
2473f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)table->ga_data)[i]);
2474f9cc9f20SBram Moolenaar if ( aep->ae_attr == taep->ae_attr
2475f9cc9f20SBram Moolenaar && (
2476f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2477f9cc9f20SBram Moolenaar (table == &gui_attr_table
2478f9cc9f20SBram Moolenaar && (aep->ae_u.gui.fg_color == taep->ae_u.gui.fg_color
2479f9cc9f20SBram Moolenaar && aep->ae_u.gui.bg_color
2480f9cc9f20SBram Moolenaar == taep->ae_u.gui.bg_color
2481f9cc9f20SBram Moolenaar && aep->ae_u.gui.sp_color
2482f9cc9f20SBram Moolenaar == taep->ae_u.gui.sp_color
2483f9cc9f20SBram Moolenaar && aep->ae_u.gui.font == taep->ae_u.gui.font
2484f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
2485f9cc9f20SBram Moolenaar && aep->ae_u.gui.fontset == taep->ae_u.gui.fontset
2486f9cc9f20SBram Moolenaar # endif
2487f9cc9f20SBram Moolenaar ))
2488f9cc9f20SBram Moolenaar ||
2489f9cc9f20SBram Moolenaar #endif
2490f9cc9f20SBram Moolenaar (table == &term_attr_table
2491f9cc9f20SBram Moolenaar && (aep->ae_u.term.start == NULL)
2492f9cc9f20SBram Moolenaar == (taep->ae_u.term.start == NULL)
2493f9cc9f20SBram Moolenaar && (aep->ae_u.term.start == NULL
2494f9cc9f20SBram Moolenaar || STRCMP(aep->ae_u.term.start,
2495f9cc9f20SBram Moolenaar taep->ae_u.term.start) == 0)
2496f9cc9f20SBram Moolenaar && (aep->ae_u.term.stop == NULL)
2497f9cc9f20SBram Moolenaar == (taep->ae_u.term.stop == NULL)
2498f9cc9f20SBram Moolenaar && (aep->ae_u.term.stop == NULL
2499f9cc9f20SBram Moolenaar || STRCMP(aep->ae_u.term.stop,
2500f9cc9f20SBram Moolenaar taep->ae_u.term.stop) == 0))
2501f9cc9f20SBram Moolenaar || (table == &cterm_attr_table
2502f9cc9f20SBram Moolenaar && aep->ae_u.cterm.fg_color
2503f9cc9f20SBram Moolenaar == taep->ae_u.cterm.fg_color
2504f9cc9f20SBram Moolenaar && aep->ae_u.cterm.bg_color
2505f9cc9f20SBram Moolenaar == taep->ae_u.cterm.bg_color
2506e023e88bSBram Moolenaar && aep->ae_u.cterm.ul_color
2507e023e88bSBram Moolenaar == taep->ae_u.cterm.ul_color
2508f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS
2509f9cc9f20SBram Moolenaar && aep->ae_u.cterm.fg_rgb
2510f9cc9f20SBram Moolenaar == taep->ae_u.cterm.fg_rgb
2511f9cc9f20SBram Moolenaar && aep->ae_u.cterm.bg_rgb
2512f9cc9f20SBram Moolenaar == taep->ae_u.cterm.bg_rgb
2513e023e88bSBram Moolenaar && aep->ae_u.cterm.ul_rgb
2514e023e88bSBram Moolenaar == taep->ae_u.cterm.ul_rgb
2515f9cc9f20SBram Moolenaar #endif
2516f9cc9f20SBram Moolenaar )))
2517f9cc9f20SBram Moolenaar
2518f9cc9f20SBram Moolenaar return i + ATTR_OFF;
2519f9cc9f20SBram Moolenaar }
2520f9cc9f20SBram Moolenaar
2521f9cc9f20SBram Moolenaar if (table->ga_len + ATTR_OFF > MAX_TYPENR)
2522f9cc9f20SBram Moolenaar {
2523ad6b90c3SYegappan Lakshmanan // Running out of attribute entries! remove all attributes, and
2524ad6b90c3SYegappan Lakshmanan // compute new ones for all groups.
2525ad6b90c3SYegappan Lakshmanan // When called recursively, we are really out of numbers.
2526f9cc9f20SBram Moolenaar if (recursive)
2527f9cc9f20SBram Moolenaar {
2528f9cc9f20SBram Moolenaar emsg(_("E424: Too many different highlighting attributes in use"));
2529f9cc9f20SBram Moolenaar return 0;
2530f9cc9f20SBram Moolenaar }
2531f9cc9f20SBram Moolenaar recursive = TRUE;
2532f9cc9f20SBram Moolenaar
2533f9cc9f20SBram Moolenaar clear_hl_tables();
2534f9cc9f20SBram Moolenaar
2535f9cc9f20SBram Moolenaar must_redraw = CLEAR;
2536f9cc9f20SBram Moolenaar
2537f9cc9f20SBram Moolenaar for (i = 0; i < highlight_ga.ga_len; ++i)
2538f9cc9f20SBram Moolenaar set_hl_attr(i);
2539f9cc9f20SBram Moolenaar
2540f9cc9f20SBram Moolenaar recursive = FALSE;
2541f9cc9f20SBram Moolenaar }
2542f9cc9f20SBram Moolenaar
2543ad6b90c3SYegappan Lakshmanan // This is a new combination of colors and font, add an entry.
2544f9cc9f20SBram Moolenaar if (ga_grow(table, 1) == FAIL)
2545f9cc9f20SBram Moolenaar return 0;
2546f9cc9f20SBram Moolenaar
2547f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)table->ga_data)[table->ga_len]);
2548a80faa89SBram Moolenaar CLEAR_POINTER(taep);
2549f9cc9f20SBram Moolenaar taep->ae_attr = aep->ae_attr;
2550f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2551f9cc9f20SBram Moolenaar if (table == &gui_attr_table)
2552f9cc9f20SBram Moolenaar {
2553f9cc9f20SBram Moolenaar taep->ae_u.gui.fg_color = aep->ae_u.gui.fg_color;
2554f9cc9f20SBram Moolenaar taep->ae_u.gui.bg_color = aep->ae_u.gui.bg_color;
2555f9cc9f20SBram Moolenaar taep->ae_u.gui.sp_color = aep->ae_u.gui.sp_color;
2556f9cc9f20SBram Moolenaar taep->ae_u.gui.font = aep->ae_u.gui.font;
2557f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
2558f9cc9f20SBram Moolenaar taep->ae_u.gui.fontset = aep->ae_u.gui.fontset;
2559f9cc9f20SBram Moolenaar # endif
2560f9cc9f20SBram Moolenaar }
2561f9cc9f20SBram Moolenaar #endif
2562f9cc9f20SBram Moolenaar if (table == &term_attr_table)
2563f9cc9f20SBram Moolenaar {
2564f9cc9f20SBram Moolenaar if (aep->ae_u.term.start == NULL)
2565f9cc9f20SBram Moolenaar taep->ae_u.term.start = NULL;
2566f9cc9f20SBram Moolenaar else
2567f9cc9f20SBram Moolenaar taep->ae_u.term.start = vim_strsave(aep->ae_u.term.start);
2568f9cc9f20SBram Moolenaar if (aep->ae_u.term.stop == NULL)
2569f9cc9f20SBram Moolenaar taep->ae_u.term.stop = NULL;
2570f9cc9f20SBram Moolenaar else
2571f9cc9f20SBram Moolenaar taep->ae_u.term.stop = vim_strsave(aep->ae_u.term.stop);
2572f9cc9f20SBram Moolenaar }
2573f9cc9f20SBram Moolenaar else if (table == &cterm_attr_table)
2574f9cc9f20SBram Moolenaar {
2575f9cc9f20SBram Moolenaar taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color;
2576f9cc9f20SBram Moolenaar taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color;
2577e023e88bSBram Moolenaar taep->ae_u.cterm.ul_color = aep->ae_u.cterm.ul_color;
2578f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS
2579f9cc9f20SBram Moolenaar taep->ae_u.cterm.fg_rgb = aep->ae_u.cterm.fg_rgb;
2580f9cc9f20SBram Moolenaar taep->ae_u.cterm.bg_rgb = aep->ae_u.cterm.bg_rgb;
2581e023e88bSBram Moolenaar taep->ae_u.cterm.ul_rgb = aep->ae_u.cterm.ul_rgb;
2582f9cc9f20SBram Moolenaar #endif
2583f9cc9f20SBram Moolenaar }
2584f9cc9f20SBram Moolenaar ++table->ga_len;
2585f9cc9f20SBram Moolenaar return (table->ga_len - 1 + ATTR_OFF);
2586f9cc9f20SBram Moolenaar }
2587f9cc9f20SBram Moolenaar
2588f9cc9f20SBram Moolenaar #if defined(FEAT_TERMINAL) || defined(PROTO)
2589f9cc9f20SBram Moolenaar /*
2590f9cc9f20SBram Moolenaar * Get an attribute index for a cterm entry.
2591f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed.
2592f9cc9f20SBram Moolenaar */
2593f9cc9f20SBram Moolenaar int
get_cterm_attr_idx(int attr,int fg,int bg)2594f9cc9f20SBram Moolenaar get_cterm_attr_idx(int attr, int fg, int bg)
2595f9cc9f20SBram Moolenaar {
2596f9cc9f20SBram Moolenaar attrentry_T at_en;
2597f9cc9f20SBram Moolenaar
2598a80faa89SBram Moolenaar CLEAR_FIELD(at_en);
2599f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS
2600f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = INVALCOLOR;
2601f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = INVALCOLOR;
26021e5f8f6dSBram Moolenaar at_en.ae_u.cterm.ul_rgb = INVALCOLOR;
2603f9cc9f20SBram Moolenaar #endif
2604f9cc9f20SBram Moolenaar at_en.ae_attr = attr;
2605f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_color = fg;
2606f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_color = bg;
2607cc836556SBram Moolenaar at_en.ae_u.cterm.ul_color = 0;
2608f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &at_en);
2609f9cc9f20SBram Moolenaar }
2610f9cc9f20SBram Moolenaar #endif
2611f9cc9f20SBram Moolenaar
2612f9cc9f20SBram Moolenaar #if (defined(FEAT_TERMINAL) && defined(FEAT_TERMGUICOLORS)) || defined(PROTO)
2613f9cc9f20SBram Moolenaar /*
2614f9cc9f20SBram Moolenaar * Get an attribute index for a 'termguicolors' entry.
2615f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed.
2616f9cc9f20SBram Moolenaar */
2617f9cc9f20SBram Moolenaar int
get_tgc_attr_idx(int attr,guicolor_T fg,guicolor_T bg)2618f9cc9f20SBram Moolenaar get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg)
2619f9cc9f20SBram Moolenaar {
2620f9cc9f20SBram Moolenaar attrentry_T at_en;
2621f9cc9f20SBram Moolenaar
2622a80faa89SBram Moolenaar CLEAR_FIELD(at_en);
2623f9cc9f20SBram Moolenaar at_en.ae_attr = attr;
2624f9cc9f20SBram Moolenaar if (fg == INVALCOLOR && bg == INVALCOLOR)
2625f9cc9f20SBram Moolenaar {
2626f9cc9f20SBram Moolenaar // If both GUI colors are not set fall back to the cterm colors. Helps
2627f9cc9f20SBram Moolenaar // if the GUI only has an attribute, such as undercurl.
2628f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = CTERMCOLOR;
2629f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = CTERMCOLOR;
2630f9cc9f20SBram Moolenaar }
2631f9cc9f20SBram Moolenaar else
2632f9cc9f20SBram Moolenaar {
2633f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = fg;
2634f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = bg;
2635f9cc9f20SBram Moolenaar }
26361e5f8f6dSBram Moolenaar at_en.ae_u.cterm.ul_rgb = INVALCOLOR;
2637f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &at_en);
2638f9cc9f20SBram Moolenaar }
2639f9cc9f20SBram Moolenaar #endif
2640f9cc9f20SBram Moolenaar
2641f9cc9f20SBram Moolenaar #if (defined(FEAT_TERMINAL) && defined(FEAT_GUI)) || defined(PROTO)
2642f9cc9f20SBram Moolenaar /*
2643f9cc9f20SBram Moolenaar * Get an attribute index for a cterm entry.
2644f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed.
2645f9cc9f20SBram Moolenaar */
2646f9cc9f20SBram Moolenaar int
get_gui_attr_idx(int attr,guicolor_T fg,guicolor_T bg)2647f9cc9f20SBram Moolenaar get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg)
2648f9cc9f20SBram Moolenaar {
2649f9cc9f20SBram Moolenaar attrentry_T at_en;
2650f9cc9f20SBram Moolenaar
2651a80faa89SBram Moolenaar CLEAR_FIELD(at_en);
2652f9cc9f20SBram Moolenaar at_en.ae_attr = attr;
2653f9cc9f20SBram Moolenaar at_en.ae_u.gui.fg_color = fg;
2654f9cc9f20SBram Moolenaar at_en.ae_u.gui.bg_color = bg;
2655f9cc9f20SBram Moolenaar return get_attr_entry(&gui_attr_table, &at_en);
2656f9cc9f20SBram Moolenaar }
2657f9cc9f20SBram Moolenaar #endif
2658f9cc9f20SBram Moolenaar
2659f9cc9f20SBram Moolenaar /*
2660f9cc9f20SBram Moolenaar * Clear all highlight tables.
2661f9cc9f20SBram Moolenaar */
2662f9cc9f20SBram Moolenaar void
clear_hl_tables(void)2663f9cc9f20SBram Moolenaar clear_hl_tables(void)
2664f9cc9f20SBram Moolenaar {
2665f9cc9f20SBram Moolenaar int i;
2666f9cc9f20SBram Moolenaar attrentry_T *taep;
2667f9cc9f20SBram Moolenaar
2668f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2669f9cc9f20SBram Moolenaar ga_clear(&gui_attr_table);
2670f9cc9f20SBram Moolenaar #endif
2671f9cc9f20SBram Moolenaar for (i = 0; i < term_attr_table.ga_len; ++i)
2672f9cc9f20SBram Moolenaar {
2673f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)term_attr_table.ga_data)[i]);
2674f9cc9f20SBram Moolenaar vim_free(taep->ae_u.term.start);
2675f9cc9f20SBram Moolenaar vim_free(taep->ae_u.term.stop);
2676f9cc9f20SBram Moolenaar }
2677f9cc9f20SBram Moolenaar ga_clear(&term_attr_table);
2678f9cc9f20SBram Moolenaar ga_clear(&cterm_attr_table);
2679f9cc9f20SBram Moolenaar }
2680f9cc9f20SBram Moolenaar
2681f9cc9f20SBram Moolenaar /*
2682f9cc9f20SBram Moolenaar * Combine special attributes (e.g., for spelling) with other attributes
2683f9cc9f20SBram Moolenaar * (e.g., for syntax highlighting).
2684f9cc9f20SBram Moolenaar * "prim_attr" overrules "char_attr".
2685f9cc9f20SBram Moolenaar * This creates a new group when required.
2686f9cc9f20SBram Moolenaar * Since we expect there to be few spelling mistakes we don't cache the
2687f9cc9f20SBram Moolenaar * result.
2688f9cc9f20SBram Moolenaar * Return the resulting attributes.
2689f9cc9f20SBram Moolenaar */
2690f9cc9f20SBram Moolenaar int
hl_combine_attr(int char_attr,int prim_attr)2691f9cc9f20SBram Moolenaar hl_combine_attr(int char_attr, int prim_attr)
2692f9cc9f20SBram Moolenaar {
2693f9cc9f20SBram Moolenaar attrentry_T *char_aep = NULL;
2694f9cc9f20SBram Moolenaar attrentry_T *spell_aep;
2695f9cc9f20SBram Moolenaar attrentry_T new_en;
2696f9cc9f20SBram Moolenaar
2697f9cc9f20SBram Moolenaar if (char_attr == 0)
2698f9cc9f20SBram Moolenaar return prim_attr;
2699f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL && prim_attr <= HL_ALL)
2700f9cc9f20SBram Moolenaar return ATTR_COMBINE(char_attr, prim_attr);
2701f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2702f9cc9f20SBram Moolenaar if (gui.in_use)
2703f9cc9f20SBram Moolenaar {
2704f9cc9f20SBram Moolenaar if (char_attr > HL_ALL)
2705f9cc9f20SBram Moolenaar char_aep = syn_gui_attr2entry(char_attr);
2706f9cc9f20SBram Moolenaar if (char_aep != NULL)
2707f9cc9f20SBram Moolenaar new_en = *char_aep;
2708f9cc9f20SBram Moolenaar else
2709f9cc9f20SBram Moolenaar {
2710a80faa89SBram Moolenaar CLEAR_FIELD(new_en);
2711f9cc9f20SBram Moolenaar new_en.ae_u.gui.fg_color = INVALCOLOR;
2712f9cc9f20SBram Moolenaar new_en.ae_u.gui.bg_color = INVALCOLOR;
2713f9cc9f20SBram Moolenaar new_en.ae_u.gui.sp_color = INVALCOLOR;
2714f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL)
2715f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr;
2716f9cc9f20SBram Moolenaar }
2717f9cc9f20SBram Moolenaar
2718f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL)
2719f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr);
2720f9cc9f20SBram Moolenaar else
2721f9cc9f20SBram Moolenaar {
2722f9cc9f20SBram Moolenaar spell_aep = syn_gui_attr2entry(prim_attr);
2723f9cc9f20SBram Moolenaar if (spell_aep != NULL)
2724f9cc9f20SBram Moolenaar {
2725f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr,
2726f9cc9f20SBram Moolenaar spell_aep->ae_attr);
2727f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.fg_color != INVALCOLOR)
2728f9cc9f20SBram Moolenaar new_en.ae_u.gui.fg_color = spell_aep->ae_u.gui.fg_color;
2729f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.bg_color != INVALCOLOR)
2730f9cc9f20SBram Moolenaar new_en.ae_u.gui.bg_color = spell_aep->ae_u.gui.bg_color;
2731f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.sp_color != INVALCOLOR)
2732f9cc9f20SBram Moolenaar new_en.ae_u.gui.sp_color = spell_aep->ae_u.gui.sp_color;
2733f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.font != NOFONT)
2734f9cc9f20SBram Moolenaar new_en.ae_u.gui.font = spell_aep->ae_u.gui.font;
2735f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
2736f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.fontset != NOFONTSET)
2737f9cc9f20SBram Moolenaar new_en.ae_u.gui.fontset = spell_aep->ae_u.gui.fontset;
2738f9cc9f20SBram Moolenaar # endif
2739f9cc9f20SBram Moolenaar }
2740f9cc9f20SBram Moolenaar }
2741f9cc9f20SBram Moolenaar return get_attr_entry(&gui_attr_table, &new_en);
2742f9cc9f20SBram Moolenaar }
2743f9cc9f20SBram Moolenaar #endif
2744f9cc9f20SBram Moolenaar
2745f9cc9f20SBram Moolenaar if (IS_CTERM)
2746f9cc9f20SBram Moolenaar {
2747f9cc9f20SBram Moolenaar if (char_attr > HL_ALL)
2748f9cc9f20SBram Moolenaar char_aep = syn_cterm_attr2entry(char_attr);
2749f9cc9f20SBram Moolenaar if (char_aep != NULL)
2750f9cc9f20SBram Moolenaar new_en = *char_aep;
2751f9cc9f20SBram Moolenaar else
2752f9cc9f20SBram Moolenaar {
2753a80faa89SBram Moolenaar CLEAR_FIELD(new_en);
2754f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS
2755f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = INVALCOLOR;
2756f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = INVALCOLOR;
2757e023e88bSBram Moolenaar new_en.ae_u.cterm.ul_rgb = INVALCOLOR;
2758f9cc9f20SBram Moolenaar #endif
2759f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL)
2760f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr;
2761f9cc9f20SBram Moolenaar }
2762f9cc9f20SBram Moolenaar
2763f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL)
2764f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr);
2765f9cc9f20SBram Moolenaar else
2766f9cc9f20SBram Moolenaar {
2767f9cc9f20SBram Moolenaar spell_aep = syn_cterm_attr2entry(prim_attr);
2768f9cc9f20SBram Moolenaar if (spell_aep != NULL)
2769f9cc9f20SBram Moolenaar {
2770f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr,
2771f9cc9f20SBram Moolenaar spell_aep->ae_attr);
2772f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_color > 0)
2773f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color;
2774f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_color > 0)
2775f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color;
2776e023e88bSBram Moolenaar if (spell_aep->ae_u.cterm.ul_color > 0)
2777e023e88bSBram Moolenaar new_en.ae_u.cterm.ul_color = spell_aep->ae_u.cterm.ul_color;
2778f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS
2779f9cc9f20SBram Moolenaar // If both fg and bg are not set fall back to cterm colors.
2780f9cc9f20SBram Moolenaar // Helps for SpellBad which uses undercurl in the GUI.
2781f9cc9f20SBram Moolenaar if (COLOR_INVALID(spell_aep->ae_u.cterm.fg_rgb)
2782f9cc9f20SBram Moolenaar && COLOR_INVALID(spell_aep->ae_u.cterm.bg_rgb))
2783f9cc9f20SBram Moolenaar {
2784f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_color > 0)
2785f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = CTERMCOLOR;
2786f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_color > 0)
2787f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = CTERMCOLOR;
2788f9cc9f20SBram Moolenaar }
2789f9cc9f20SBram Moolenaar else
2790f9cc9f20SBram Moolenaar {
2791f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_rgb != INVALCOLOR)
2792f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = spell_aep->ae_u.cterm.fg_rgb;
2793f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_rgb != INVALCOLOR)
2794f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = spell_aep->ae_u.cterm.bg_rgb;
2795f9cc9f20SBram Moolenaar }
2796e023e88bSBram Moolenaar if (spell_aep->ae_u.cterm.ul_rgb != INVALCOLOR)
2797e023e88bSBram Moolenaar new_en.ae_u.cterm.ul_rgb = spell_aep->ae_u.cterm.ul_rgb;
2798f9cc9f20SBram Moolenaar #endif
2799f9cc9f20SBram Moolenaar }
2800f9cc9f20SBram Moolenaar }
2801f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &new_en);
2802f9cc9f20SBram Moolenaar }
2803f9cc9f20SBram Moolenaar
2804f9cc9f20SBram Moolenaar if (char_attr > HL_ALL)
2805f9cc9f20SBram Moolenaar char_aep = syn_term_attr2entry(char_attr);
2806f9cc9f20SBram Moolenaar if (char_aep != NULL)
2807f9cc9f20SBram Moolenaar new_en = *char_aep;
2808f9cc9f20SBram Moolenaar else
2809f9cc9f20SBram Moolenaar {
2810a80faa89SBram Moolenaar CLEAR_FIELD(new_en);
2811f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL)
2812f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr;
2813f9cc9f20SBram Moolenaar }
2814f9cc9f20SBram Moolenaar
2815f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL)
2816f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr);
2817f9cc9f20SBram Moolenaar else
2818f9cc9f20SBram Moolenaar {
2819f9cc9f20SBram Moolenaar spell_aep = syn_term_attr2entry(prim_attr);
2820f9cc9f20SBram Moolenaar if (spell_aep != NULL)
2821f9cc9f20SBram Moolenaar {
2822f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, spell_aep->ae_attr);
2823f9cc9f20SBram Moolenaar if (spell_aep->ae_u.term.start != NULL)
2824f9cc9f20SBram Moolenaar {
2825f9cc9f20SBram Moolenaar new_en.ae_u.term.start = spell_aep->ae_u.term.start;
2826f9cc9f20SBram Moolenaar new_en.ae_u.term.stop = spell_aep->ae_u.term.stop;
2827f9cc9f20SBram Moolenaar }
2828f9cc9f20SBram Moolenaar }
2829f9cc9f20SBram Moolenaar }
2830f9cc9f20SBram Moolenaar return get_attr_entry(&term_attr_table, &new_en);
2831f9cc9f20SBram Moolenaar }
2832f9cc9f20SBram Moolenaar
2833f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2834f9cc9f20SBram Moolenaar attrentry_T *
syn_gui_attr2entry(int attr)2835f9cc9f20SBram Moolenaar syn_gui_attr2entry(int attr)
2836f9cc9f20SBram Moolenaar {
2837f9cc9f20SBram Moolenaar attr -= ATTR_OFF;
2838f9cc9f20SBram Moolenaar if (attr >= gui_attr_table.ga_len) // did ":syntax clear"
2839f9cc9f20SBram Moolenaar return NULL;
2840f9cc9f20SBram Moolenaar return &(GUI_ATTR_ENTRY(attr));
2841f9cc9f20SBram Moolenaar }
2842f9cc9f20SBram Moolenaar #endif
2843f9cc9f20SBram Moolenaar
2844f9cc9f20SBram Moolenaar /*
2845f9cc9f20SBram Moolenaar * Get the highlight attributes (HL_BOLD etc.) from an attribute nr.
2846f9cc9f20SBram Moolenaar * Only to be used when "attr" > HL_ALL.
2847f9cc9f20SBram Moolenaar */
2848f9cc9f20SBram Moolenaar int
syn_attr2attr(int attr)2849f9cc9f20SBram Moolenaar syn_attr2attr(int attr)
2850f9cc9f20SBram Moolenaar {
2851f9cc9f20SBram Moolenaar attrentry_T *aep;
2852f9cc9f20SBram Moolenaar
2853f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2854f9cc9f20SBram Moolenaar if (gui.in_use)
2855f9cc9f20SBram Moolenaar aep = syn_gui_attr2entry(attr);
2856f9cc9f20SBram Moolenaar else
2857f9cc9f20SBram Moolenaar #endif
2858f9cc9f20SBram Moolenaar if (IS_CTERM)
2859f9cc9f20SBram Moolenaar aep = syn_cterm_attr2entry(attr);
2860f9cc9f20SBram Moolenaar else
2861f9cc9f20SBram Moolenaar aep = syn_term_attr2entry(attr);
2862f9cc9f20SBram Moolenaar
2863f9cc9f20SBram Moolenaar if (aep == NULL) // highlighting not set
2864f9cc9f20SBram Moolenaar return 0;
2865f9cc9f20SBram Moolenaar return aep->ae_attr;
2866f9cc9f20SBram Moolenaar }
2867f9cc9f20SBram Moolenaar
2868f9cc9f20SBram Moolenaar
2869f9cc9f20SBram Moolenaar attrentry_T *
syn_term_attr2entry(int attr)2870f9cc9f20SBram Moolenaar syn_term_attr2entry(int attr)
2871f9cc9f20SBram Moolenaar {
2872f9cc9f20SBram Moolenaar attr -= ATTR_OFF;
2873f9cc9f20SBram Moolenaar if (attr >= term_attr_table.ga_len) // did ":syntax clear"
2874f9cc9f20SBram Moolenaar return NULL;
2875f9cc9f20SBram Moolenaar return &(TERM_ATTR_ENTRY(attr));
2876f9cc9f20SBram Moolenaar }
2877f9cc9f20SBram Moolenaar
2878f9cc9f20SBram Moolenaar attrentry_T *
syn_cterm_attr2entry(int attr)2879f9cc9f20SBram Moolenaar syn_cterm_attr2entry(int attr)
2880f9cc9f20SBram Moolenaar {
2881f9cc9f20SBram Moolenaar attr -= ATTR_OFF;
2882f9cc9f20SBram Moolenaar if (attr >= cterm_attr_table.ga_len) // did ":syntax clear"
2883f9cc9f20SBram Moolenaar return NULL;
2884f9cc9f20SBram Moolenaar return &(CTERM_ATTR_ENTRY(attr));
2885f9cc9f20SBram Moolenaar }
2886f9cc9f20SBram Moolenaar
2887f9cc9f20SBram Moolenaar #define LIST_ATTR 1
2888f9cc9f20SBram Moolenaar #define LIST_STRING 2
2889f9cc9f20SBram Moolenaar #define LIST_INT 3
2890f9cc9f20SBram Moolenaar
2891f9cc9f20SBram Moolenaar static void
highlight_list_one(int id)2892f9cc9f20SBram Moolenaar highlight_list_one(int id)
2893f9cc9f20SBram Moolenaar {
2894f9cc9f20SBram Moolenaar hl_group_T *sgp;
2895f9cc9f20SBram Moolenaar int didh = FALSE;
2896f9cc9f20SBram Moolenaar
2897f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[id - 1]; // index is ID minus one
2898f9cc9f20SBram Moolenaar
2899f9cc9f20SBram Moolenaar if (message_filtered(sgp->sg_name))
2900f9cc9f20SBram Moolenaar return;
2901f9cc9f20SBram Moolenaar
2902f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR,
2903f9cc9f20SBram Moolenaar sgp->sg_term, NULL, "term");
2904f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING,
2905f9cc9f20SBram Moolenaar 0, sgp->sg_start, "start");
2906f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING,
2907f9cc9f20SBram Moolenaar 0, sgp->sg_stop, "stop");
2908f9cc9f20SBram Moolenaar
2909f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR,
2910f9cc9f20SBram Moolenaar sgp->sg_cterm, NULL, "cterm");
2911f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_INT,
2912f9cc9f20SBram Moolenaar sgp->sg_cterm_fg, NULL, "ctermfg");
2913f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_INT,
2914f9cc9f20SBram Moolenaar sgp->sg_cterm_bg, NULL, "ctermbg");
2915e023e88bSBram Moolenaar didh = highlight_list_arg(id, didh, LIST_INT,
2916e023e88bSBram Moolenaar sgp->sg_cterm_ul, NULL, "ctermul");
2917f9cc9f20SBram Moolenaar
2918f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL)
2919f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR,
2920f9cc9f20SBram Moolenaar sgp->sg_gui, NULL, "gui");
2921f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING,
2922f9cc9f20SBram Moolenaar 0, sgp->sg_gui_fg_name, "guifg");
2923f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING,
2924f9cc9f20SBram Moolenaar 0, sgp->sg_gui_bg_name, "guibg");
2925f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING,
2926f9cc9f20SBram Moolenaar 0, sgp->sg_gui_sp_name, "guisp");
2927f9cc9f20SBram Moolenaar #endif
2928f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
2929f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING,
2930f9cc9f20SBram Moolenaar 0, sgp->sg_font_name, "font");
2931f9cc9f20SBram Moolenaar #endif
2932f9cc9f20SBram Moolenaar
2933f9cc9f20SBram Moolenaar if (sgp->sg_link && !got_int)
2934f9cc9f20SBram Moolenaar {
2935f9cc9f20SBram Moolenaar (void)syn_list_header(didh, 9999, id);
2936f9cc9f20SBram Moolenaar didh = TRUE;
2937f9cc9f20SBram Moolenaar msg_puts_attr("links to", HL_ATTR(HLF_D));
2938f9cc9f20SBram Moolenaar msg_putchar(' ');
2939f9cc9f20SBram Moolenaar msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name);
2940f9cc9f20SBram Moolenaar }
2941f9cc9f20SBram Moolenaar
2942f9cc9f20SBram Moolenaar if (!didh)
2943f9cc9f20SBram Moolenaar highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", "");
2944f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL
2945f9cc9f20SBram Moolenaar if (p_verbose > 0)
2946f9cc9f20SBram Moolenaar last_set_msg(sgp->sg_script_ctx);
2947f9cc9f20SBram Moolenaar #endif
2948f9cc9f20SBram Moolenaar }
2949f9cc9f20SBram Moolenaar
2950f9cc9f20SBram Moolenaar static int
highlight_list_arg(int id,int didh,int type,int iarg,char_u * sarg,char * name)2951f9cc9f20SBram Moolenaar highlight_list_arg(
2952f9cc9f20SBram Moolenaar int id,
2953f9cc9f20SBram Moolenaar int didh,
2954f9cc9f20SBram Moolenaar int type,
2955f9cc9f20SBram Moolenaar int iarg,
2956f9cc9f20SBram Moolenaar char_u *sarg,
2957f9cc9f20SBram Moolenaar char *name)
2958f9cc9f20SBram Moolenaar {
2959f9cc9f20SBram Moolenaar char_u buf[100];
2960f9cc9f20SBram Moolenaar char_u *ts;
2961f9cc9f20SBram Moolenaar int i;
2962f9cc9f20SBram Moolenaar
2963f9cc9f20SBram Moolenaar if (got_int)
2964f9cc9f20SBram Moolenaar return FALSE;
2965f9cc9f20SBram Moolenaar if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0))
2966f9cc9f20SBram Moolenaar {
2967f9cc9f20SBram Moolenaar ts = buf;
2968f9cc9f20SBram Moolenaar if (type == LIST_INT)
2969f9cc9f20SBram Moolenaar sprintf((char *)buf, "%d", iarg - 1);
2970f9cc9f20SBram Moolenaar else if (type == LIST_STRING)
2971f9cc9f20SBram Moolenaar ts = sarg;
2972f9cc9f20SBram Moolenaar else // type == LIST_ATTR
2973f9cc9f20SBram Moolenaar {
2974f9cc9f20SBram Moolenaar buf[0] = NUL;
2975f9cc9f20SBram Moolenaar for (i = 0; hl_attr_table[i] != 0; ++i)
2976f9cc9f20SBram Moolenaar {
2977f9cc9f20SBram Moolenaar if (iarg & hl_attr_table[i])
2978f9cc9f20SBram Moolenaar {
2979f9cc9f20SBram Moolenaar if (buf[0] != NUL)
2980f9cc9f20SBram Moolenaar vim_strcat(buf, (char_u *)",", 100);
2981f9cc9f20SBram Moolenaar vim_strcat(buf, (char_u *)hl_name_table[i], 100);
2982f9cc9f20SBram Moolenaar iarg &= ~hl_attr_table[i]; // don't want "inverse"
2983f9cc9f20SBram Moolenaar }
2984f9cc9f20SBram Moolenaar }
2985f9cc9f20SBram Moolenaar }
2986f9cc9f20SBram Moolenaar
2987f9cc9f20SBram Moolenaar (void)syn_list_header(didh,
2988f9cc9f20SBram Moolenaar (int)(vim_strsize(ts) + STRLEN(name) + 1), id);
2989f9cc9f20SBram Moolenaar didh = TRUE;
2990f9cc9f20SBram Moolenaar if (!got_int)
2991f9cc9f20SBram Moolenaar {
2992f9cc9f20SBram Moolenaar if (*name != NUL)
2993f9cc9f20SBram Moolenaar {
2994f9cc9f20SBram Moolenaar msg_puts_attr(name, HL_ATTR(HLF_D));
2995f9cc9f20SBram Moolenaar msg_puts_attr("=", HL_ATTR(HLF_D));
2996f9cc9f20SBram Moolenaar }
2997f9cc9f20SBram Moolenaar msg_outtrans(ts);
2998f9cc9f20SBram Moolenaar }
2999f9cc9f20SBram Moolenaar }
3000f9cc9f20SBram Moolenaar return didh;
3001f9cc9f20SBram Moolenaar }
3002f9cc9f20SBram Moolenaar
3003f9cc9f20SBram Moolenaar #if (((defined(FEAT_EVAL) || defined(FEAT_PRINTER))) && defined(FEAT_SYN_HL)) || defined(PROTO)
3004f9cc9f20SBram Moolenaar /*
3005f9cc9f20SBram Moolenaar * Return "1" if highlight group "id" has attribute "flag".
3006f9cc9f20SBram Moolenaar * Return NULL otherwise.
3007f9cc9f20SBram Moolenaar */
3008f9cc9f20SBram Moolenaar char_u *
highlight_has_attr(int id,int flag,int modec)3009f9cc9f20SBram Moolenaar highlight_has_attr(
3010f9cc9f20SBram Moolenaar int id,
3011f9cc9f20SBram Moolenaar int flag,
3012f9cc9f20SBram Moolenaar int modec) // 'g' for GUI, 'c' for cterm, 't' for term
3013f9cc9f20SBram Moolenaar {
3014f9cc9f20SBram Moolenaar int attr;
3015f9cc9f20SBram Moolenaar
3016f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len)
3017f9cc9f20SBram Moolenaar return NULL;
3018f9cc9f20SBram Moolenaar
3019f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL)
3020f9cc9f20SBram Moolenaar if (modec == 'g')
3021f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_gui;
3022f9cc9f20SBram Moolenaar else
3023f9cc9f20SBram Moolenaar #endif
3024d43d8e28SYegappan Lakshmanan {
3025f9cc9f20SBram Moolenaar if (modec == 'c')
3026f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_cterm;
3027f9cc9f20SBram Moolenaar else
3028f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_term;
3029d43d8e28SYegappan Lakshmanan }
3030f9cc9f20SBram Moolenaar
3031f9cc9f20SBram Moolenaar if (attr & flag)
3032f9cc9f20SBram Moolenaar return (char_u *)"1";
3033f9cc9f20SBram Moolenaar return NULL;
3034f9cc9f20SBram Moolenaar }
3035f9cc9f20SBram Moolenaar #endif
3036f9cc9f20SBram Moolenaar
3037f9cc9f20SBram Moolenaar #if (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) || defined(PROTO)
3038f9cc9f20SBram Moolenaar /*
3039f9cc9f20SBram Moolenaar * Return color name of highlight group "id".
3040f9cc9f20SBram Moolenaar */
3041f9cc9f20SBram Moolenaar char_u *
highlight_color(int id,char_u * what,int modec)3042f9cc9f20SBram Moolenaar highlight_color(
3043f9cc9f20SBram Moolenaar int id,
3044391c3627SBram Moolenaar char_u *what, // "font", "fg", "bg", "sp", "ul", "fg#", "bg#" or "sp#"
3045f9cc9f20SBram Moolenaar int modec) // 'g' for GUI, 'c' for cterm, 't' for term
3046f9cc9f20SBram Moolenaar {
3047f9cc9f20SBram Moolenaar static char_u name[20];
3048f9cc9f20SBram Moolenaar int n;
3049f9cc9f20SBram Moolenaar int fg = FALSE;
3050f9cc9f20SBram Moolenaar int sp = FALSE;
3051391c3627SBram Moolenaar int ul = FALSE;
3052f9cc9f20SBram Moolenaar int font = FALSE;
3053f9cc9f20SBram Moolenaar
3054f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len)
3055f9cc9f20SBram Moolenaar return NULL;
3056f9cc9f20SBram Moolenaar
3057f9cc9f20SBram Moolenaar if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g')
3058f9cc9f20SBram Moolenaar fg = TRUE;
3059f9cc9f20SBram Moolenaar else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o'
3060f9cc9f20SBram Moolenaar && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't')
3061f9cc9f20SBram Moolenaar font = TRUE;
3062f9cc9f20SBram Moolenaar else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p')
3063f9cc9f20SBram Moolenaar sp = TRUE;
3064391c3627SBram Moolenaar else if (TOLOWER_ASC(what[0]) == 'u' && TOLOWER_ASC(what[1]) == 'l')
3065391c3627SBram Moolenaar ul = TRUE;
3066f9cc9f20SBram Moolenaar else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g'))
3067f9cc9f20SBram Moolenaar return NULL;
3068f9cc9f20SBram Moolenaar if (modec == 'g')
3069f9cc9f20SBram Moolenaar {
3070f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
3071f9cc9f20SBram Moolenaar # ifdef FEAT_GUI
3072f9cc9f20SBram Moolenaar // return font name
3073f9cc9f20SBram Moolenaar if (font)
3074f9cc9f20SBram Moolenaar return HL_TABLE()[id - 1].sg_font_name;
3075f9cc9f20SBram Moolenaar # endif
3076f9cc9f20SBram Moolenaar
3077f9cc9f20SBram Moolenaar // return #RRGGBB form (only possible when GUI is running)
3078f9cc9f20SBram Moolenaar if ((USE_24BIT) && what[2] == '#')
3079f9cc9f20SBram Moolenaar {
3080f9cc9f20SBram Moolenaar guicolor_T color;
3081f9cc9f20SBram Moolenaar long_u rgb;
3082f9cc9f20SBram Moolenaar static char_u buf[10];
3083f9cc9f20SBram Moolenaar
3084f9cc9f20SBram Moolenaar if (fg)
3085f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_fg;
3086f9cc9f20SBram Moolenaar else if (sp)
3087f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_sp;
3088f9cc9f20SBram Moolenaar else
3089f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_bg;
3090f9cc9f20SBram Moolenaar if (color == INVALCOLOR)
3091f9cc9f20SBram Moolenaar return NULL;
3092f9cc9f20SBram Moolenaar rgb = (long_u)GUI_MCH_GET_RGB(color);
3093f9cc9f20SBram Moolenaar sprintf((char *)buf, "#%02x%02x%02x",
3094f9cc9f20SBram Moolenaar (unsigned)(rgb >> 16),
3095f9cc9f20SBram Moolenaar (unsigned)(rgb >> 8) & 255,
3096f9cc9f20SBram Moolenaar (unsigned)rgb & 255);
3097f9cc9f20SBram Moolenaar return buf;
3098f9cc9f20SBram Moolenaar }
3099f9cc9f20SBram Moolenaar # endif
3100f9cc9f20SBram Moolenaar if (fg)
3101f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_fg_name);
3102f9cc9f20SBram Moolenaar if (sp)
3103f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_sp_name);
3104f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_bg_name);
3105f9cc9f20SBram Moolenaar }
3106f9cc9f20SBram Moolenaar if (font || sp)
3107f9cc9f20SBram Moolenaar return NULL;
3108f9cc9f20SBram Moolenaar if (modec == 'c')
3109f9cc9f20SBram Moolenaar {
3110f9cc9f20SBram Moolenaar if (fg)
3111f9cc9f20SBram Moolenaar n = HL_TABLE()[id - 1].sg_cterm_fg - 1;
3112391c3627SBram Moolenaar else if (ul)
3113391c3627SBram Moolenaar n = HL_TABLE()[id - 1].sg_cterm_ul - 1;
3114f9cc9f20SBram Moolenaar else
3115f9cc9f20SBram Moolenaar n = HL_TABLE()[id - 1].sg_cterm_bg - 1;
3116f9cc9f20SBram Moolenaar if (n < 0)
3117f9cc9f20SBram Moolenaar return NULL;
3118f9cc9f20SBram Moolenaar sprintf((char *)name, "%d", n);
3119f9cc9f20SBram Moolenaar return name;
3120f9cc9f20SBram Moolenaar }
3121f9cc9f20SBram Moolenaar // term doesn't have color
3122f9cc9f20SBram Moolenaar return NULL;
3123f9cc9f20SBram Moolenaar }
3124f9cc9f20SBram Moolenaar #endif
3125f9cc9f20SBram Moolenaar
3126f9cc9f20SBram Moolenaar #if (defined(FEAT_SYN_HL) \
3127f9cc9f20SBram Moolenaar && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) \
3128f9cc9f20SBram Moolenaar && defined(FEAT_PRINTER)) || defined(PROTO)
3129f9cc9f20SBram Moolenaar /*
3130f9cc9f20SBram Moolenaar * Return color name of highlight group "id" as RGB value.
3131f9cc9f20SBram Moolenaar */
3132f9cc9f20SBram Moolenaar long_u
highlight_gui_color_rgb(int id,int fg)3133f9cc9f20SBram Moolenaar highlight_gui_color_rgb(
3134f9cc9f20SBram Moolenaar int id,
3135f9cc9f20SBram Moolenaar int fg) // TRUE = fg, FALSE = bg
3136f9cc9f20SBram Moolenaar {
3137f9cc9f20SBram Moolenaar guicolor_T color;
3138f9cc9f20SBram Moolenaar
3139f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len)
3140f9cc9f20SBram Moolenaar return 0L;
3141f9cc9f20SBram Moolenaar
3142f9cc9f20SBram Moolenaar if (fg)
3143f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_fg;
3144f9cc9f20SBram Moolenaar else
3145f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_bg;
3146f9cc9f20SBram Moolenaar
3147f9cc9f20SBram Moolenaar if (color == INVALCOLOR)
3148f9cc9f20SBram Moolenaar return 0L;
3149f9cc9f20SBram Moolenaar
3150f9cc9f20SBram Moolenaar return GUI_MCH_GET_RGB(color);
3151f9cc9f20SBram Moolenaar }
3152f9cc9f20SBram Moolenaar #endif
3153f9cc9f20SBram Moolenaar
3154f9cc9f20SBram Moolenaar /*
3155f9cc9f20SBram Moolenaar * Output the syntax list header.
3156f9cc9f20SBram Moolenaar * Return TRUE when started a new line.
3157f9cc9f20SBram Moolenaar */
3158f9cc9f20SBram Moolenaar int
syn_list_header(int did_header,int outlen,int id)3159f9cc9f20SBram Moolenaar syn_list_header(
3160f9cc9f20SBram Moolenaar int did_header, // did header already
3161f9cc9f20SBram Moolenaar int outlen, // length of string that comes
3162f9cc9f20SBram Moolenaar int id) // highlight group id
3163f9cc9f20SBram Moolenaar {
3164f9cc9f20SBram Moolenaar int endcol = 19;
3165f9cc9f20SBram Moolenaar int newline = TRUE;
3166f9cc9f20SBram Moolenaar int name_col = 0;
3167f9cc9f20SBram Moolenaar
3168f9cc9f20SBram Moolenaar if (!did_header)
3169f9cc9f20SBram Moolenaar {
3170f9cc9f20SBram Moolenaar msg_putchar('\n');
3171f9cc9f20SBram Moolenaar if (got_int)
3172f9cc9f20SBram Moolenaar return TRUE;
3173f9cc9f20SBram Moolenaar msg_outtrans(HL_TABLE()[id - 1].sg_name);
3174f9cc9f20SBram Moolenaar name_col = msg_col;
3175f9cc9f20SBram Moolenaar endcol = 15;
3176f9cc9f20SBram Moolenaar }
3177f9cc9f20SBram Moolenaar else if (msg_col + outlen + 1 >= Columns)
3178f9cc9f20SBram Moolenaar {
3179f9cc9f20SBram Moolenaar msg_putchar('\n');
3180f9cc9f20SBram Moolenaar if (got_int)
3181f9cc9f20SBram Moolenaar return TRUE;
3182f9cc9f20SBram Moolenaar }
3183f9cc9f20SBram Moolenaar else
3184f9cc9f20SBram Moolenaar {
3185f9cc9f20SBram Moolenaar if (msg_col >= endcol) // wrap around is like starting a new line
3186f9cc9f20SBram Moolenaar newline = FALSE;
3187f9cc9f20SBram Moolenaar }
3188f9cc9f20SBram Moolenaar
3189f9cc9f20SBram Moolenaar if (msg_col >= endcol) // output at least one space
3190f9cc9f20SBram Moolenaar endcol = msg_col + 1;
3191f9cc9f20SBram Moolenaar if (Columns <= endcol) // avoid hang for tiny window
3192f9cc9f20SBram Moolenaar endcol = Columns - 1;
3193f9cc9f20SBram Moolenaar
3194f9cc9f20SBram Moolenaar msg_advance(endcol);
3195f9cc9f20SBram Moolenaar
3196f9cc9f20SBram Moolenaar // Show "xxx" with the attributes.
3197f9cc9f20SBram Moolenaar if (!did_header)
3198f9cc9f20SBram Moolenaar {
3199f9cc9f20SBram Moolenaar if (endcol == Columns - 1 && endcol <= name_col)
3200f9cc9f20SBram Moolenaar msg_putchar(' ');
3201f9cc9f20SBram Moolenaar msg_puts_attr("xxx", syn_id2attr(id));
3202f9cc9f20SBram Moolenaar msg_putchar(' ');
3203f9cc9f20SBram Moolenaar }
3204f9cc9f20SBram Moolenaar
3205f9cc9f20SBram Moolenaar return newline;
3206f9cc9f20SBram Moolenaar }
3207f9cc9f20SBram Moolenaar
3208f9cc9f20SBram Moolenaar /*
3209f9cc9f20SBram Moolenaar * Set the attribute numbers for a highlight group.
3210f9cc9f20SBram Moolenaar * Called after one of the attributes has changed.
3211f9cc9f20SBram Moolenaar */
3212f9cc9f20SBram Moolenaar static void
set_hl_attr(int idx)3213f9cc9f20SBram Moolenaar set_hl_attr(
3214f9cc9f20SBram Moolenaar int idx) // index in array
3215f9cc9f20SBram Moolenaar {
3216f9cc9f20SBram Moolenaar attrentry_T at_en;
3217f9cc9f20SBram Moolenaar hl_group_T *sgp = HL_TABLE() + idx;
3218f9cc9f20SBram Moolenaar
3219f9cc9f20SBram Moolenaar // The "Normal" group doesn't need an attribute number
3220f9cc9f20SBram Moolenaar if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0)
3221f9cc9f20SBram Moolenaar return;
3222f9cc9f20SBram Moolenaar
3223f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
3224ad6b90c3SYegappan Lakshmanan // For the GUI mode: If there are other than "normal" highlighting
3225ad6b90c3SYegappan Lakshmanan // attributes, need to allocate an attr number.
3226f9cc9f20SBram Moolenaar if (sgp->sg_gui_fg == INVALCOLOR
3227f9cc9f20SBram Moolenaar && sgp->sg_gui_bg == INVALCOLOR
3228f9cc9f20SBram Moolenaar && sgp->sg_gui_sp == INVALCOLOR
3229f9cc9f20SBram Moolenaar && sgp->sg_font == NOFONT
3230f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
3231f9cc9f20SBram Moolenaar && sgp->sg_fontset == NOFONTSET
3232f9cc9f20SBram Moolenaar # endif
3233f9cc9f20SBram Moolenaar )
3234f9cc9f20SBram Moolenaar {
3235f9cc9f20SBram Moolenaar sgp->sg_gui_attr = sgp->sg_gui;
3236f9cc9f20SBram Moolenaar }
3237f9cc9f20SBram Moolenaar else
3238f9cc9f20SBram Moolenaar {
3239f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_gui;
3240f9cc9f20SBram Moolenaar at_en.ae_u.gui.fg_color = sgp->sg_gui_fg;
3241f9cc9f20SBram Moolenaar at_en.ae_u.gui.bg_color = sgp->sg_gui_bg;
3242f9cc9f20SBram Moolenaar at_en.ae_u.gui.sp_color = sgp->sg_gui_sp;
3243f9cc9f20SBram Moolenaar at_en.ae_u.gui.font = sgp->sg_font;
3244f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
3245f9cc9f20SBram Moolenaar at_en.ae_u.gui.fontset = sgp->sg_fontset;
3246f9cc9f20SBram Moolenaar # endif
3247f9cc9f20SBram Moolenaar sgp->sg_gui_attr = get_attr_entry(&gui_attr_table, &at_en);
3248f9cc9f20SBram Moolenaar }
3249f9cc9f20SBram Moolenaar #endif
3250ad6b90c3SYegappan Lakshmanan // For the term mode: If there are other than "normal" highlighting
3251ad6b90c3SYegappan Lakshmanan // attributes, need to allocate an attr number.
3252f9cc9f20SBram Moolenaar if (sgp->sg_start == NULL && sgp->sg_stop == NULL)
3253f9cc9f20SBram Moolenaar sgp->sg_term_attr = sgp->sg_term;
3254f9cc9f20SBram Moolenaar else
3255f9cc9f20SBram Moolenaar {
3256f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_term;
3257f9cc9f20SBram Moolenaar at_en.ae_u.term.start = sgp->sg_start;
3258f9cc9f20SBram Moolenaar at_en.ae_u.term.stop = sgp->sg_stop;
3259f9cc9f20SBram Moolenaar sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en);
3260f9cc9f20SBram Moolenaar }
3261f9cc9f20SBram Moolenaar
3262ad6b90c3SYegappan Lakshmanan // For the color term mode: If there are other than "normal"
3263ad6b90c3SYegappan Lakshmanan // highlighting attributes, need to allocate an attr number.
3264e023e88bSBram Moolenaar if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 && sgp->sg_cterm_ul == 0
3265f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS
3266f9cc9f20SBram Moolenaar && sgp->sg_gui_fg == INVALCOLOR
3267f9cc9f20SBram Moolenaar && sgp->sg_gui_bg == INVALCOLOR
3268e023e88bSBram Moolenaar && sgp->sg_gui_sp == INVALCOLOR
3269f9cc9f20SBram Moolenaar # endif
3270f9cc9f20SBram Moolenaar )
3271f9cc9f20SBram Moolenaar sgp->sg_cterm_attr = sgp->sg_cterm;
3272f9cc9f20SBram Moolenaar else
3273f9cc9f20SBram Moolenaar {
3274f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_cterm;
3275f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg;
3276f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg;
3277e023e88bSBram Moolenaar at_en.ae_u.cterm.ul_color = sgp->sg_cterm_ul;
3278f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS
3279f9cc9f20SBram Moolenaar # ifdef MSWIN
3280f9cc9f20SBram Moolenaar # ifdef VIMDLL
3281f9cc9f20SBram Moolenaar // Only when not using the GUI.
3282f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting)
3283f9cc9f20SBram Moolenaar # endif
3284f9cc9f20SBram Moolenaar {
3285f9cc9f20SBram Moolenaar int id;
3286f9cc9f20SBram Moolenaar guicolor_T fg, bg;
3287f9cc9f20SBram Moolenaar
3288f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal");
3289f9cc9f20SBram Moolenaar if (id > 0)
3290f9cc9f20SBram Moolenaar {
3291f9cc9f20SBram Moolenaar syn_id2colors(id, &fg, &bg);
3292f9cc9f20SBram Moolenaar if (sgp->sg_gui_fg == INVALCOLOR)
3293f9cc9f20SBram Moolenaar sgp->sg_gui_fg = fg;
3294f9cc9f20SBram Moolenaar if (sgp->sg_gui_bg == INVALCOLOR)
3295f9cc9f20SBram Moolenaar sgp->sg_gui_bg = bg;
3296f9cc9f20SBram Moolenaar }
3297f9cc9f20SBram Moolenaar
3298f9cc9f20SBram Moolenaar }
3299f9cc9f20SBram Moolenaar # endif
3300f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_fg);
3301f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_bg);
3302ea563cc2SBram Moolenaar // Only use the underline/undercurl color when used, it may clear the
3303ea563cc2SBram Moolenaar // background color if not supported.
3304ea563cc2SBram Moolenaar if (sgp->sg_cterm & (HL_UNDERLINE | HL_UNDERCURL))
3305e023e88bSBram Moolenaar at_en.ae_u.cterm.ul_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_sp);
3306ea563cc2SBram Moolenaar else
3307ea563cc2SBram Moolenaar at_en.ae_u.cterm.ul_rgb = INVALCOLOR;
3308f9cc9f20SBram Moolenaar if (at_en.ae_u.cterm.fg_rgb == INVALCOLOR
3309f9cc9f20SBram Moolenaar && at_en.ae_u.cterm.bg_rgb == INVALCOLOR)
3310f9cc9f20SBram Moolenaar {
3311f9cc9f20SBram Moolenaar // If both fg and bg are invalid fall back to the cterm colors.
3312f9cc9f20SBram Moolenaar // Helps when the GUI only uses an attribute, e.g. undercurl.
3313f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = CTERMCOLOR;
3314f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = CTERMCOLOR;
3315f9cc9f20SBram Moolenaar }
3316f9cc9f20SBram Moolenaar # endif
3317f9cc9f20SBram Moolenaar sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en);
3318f9cc9f20SBram Moolenaar }
3319f9cc9f20SBram Moolenaar }
3320f9cc9f20SBram Moolenaar
3321f9cc9f20SBram Moolenaar /*
3322f9cc9f20SBram Moolenaar * Lookup a highlight group name and return its ID.
3323f9cc9f20SBram Moolenaar * If it is not found, 0 is returned.
3324f9cc9f20SBram Moolenaar */
3325f9cc9f20SBram Moolenaar int
syn_name2id(char_u * name)3326f9cc9f20SBram Moolenaar syn_name2id(char_u *name)
3327f9cc9f20SBram Moolenaar {
3328f9cc9f20SBram Moolenaar int i;
3329f9cc9f20SBram Moolenaar char_u name_u[200];
3330f9cc9f20SBram Moolenaar
3331f9cc9f20SBram Moolenaar // Avoid using stricmp() too much, it's slow on some systems
3332f9cc9f20SBram Moolenaar // Avoid alloc()/free(), these are slow too. ID names over 200 chars
3333f9cc9f20SBram Moolenaar // don't deserve to be found!
3334f9cc9f20SBram Moolenaar vim_strncpy(name_u, name, 199);
3335f9cc9f20SBram Moolenaar vim_strup(name_u);
3336f9cc9f20SBram Moolenaar for (i = highlight_ga.ga_len; --i >= 0; )
3337f9cc9f20SBram Moolenaar if (HL_TABLE()[i].sg_name_u != NULL
3338f9cc9f20SBram Moolenaar && STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0)
3339f9cc9f20SBram Moolenaar break;
3340f9cc9f20SBram Moolenaar return i + 1;
3341f9cc9f20SBram Moolenaar }
3342f9cc9f20SBram Moolenaar
3343f9cc9f20SBram Moolenaar /*
3344f9cc9f20SBram Moolenaar * Lookup a highlight group name and return its attributes.
3345f9cc9f20SBram Moolenaar * Return zero if not found.
3346f9cc9f20SBram Moolenaar */
3347f9cc9f20SBram Moolenaar int
syn_name2attr(char_u * name)3348f9cc9f20SBram Moolenaar syn_name2attr(char_u *name)
3349f9cc9f20SBram Moolenaar {
3350f9cc9f20SBram Moolenaar int id = syn_name2id(name);
3351f9cc9f20SBram Moolenaar
3352f9cc9f20SBram Moolenaar if (id != 0)
3353f9cc9f20SBram Moolenaar return syn_id2attr(id);
3354f9cc9f20SBram Moolenaar return 0;
3355f9cc9f20SBram Moolenaar }
3356f9cc9f20SBram Moolenaar
3357f9cc9f20SBram Moolenaar #if defined(FEAT_EVAL) || defined(PROTO)
3358f9cc9f20SBram Moolenaar /*
3359f9cc9f20SBram Moolenaar * Return TRUE if highlight group "name" exists.
3360f9cc9f20SBram Moolenaar */
3361f9cc9f20SBram Moolenaar int
highlight_exists(char_u * name)3362f9cc9f20SBram Moolenaar highlight_exists(char_u *name)
3363f9cc9f20SBram Moolenaar {
3364f9cc9f20SBram Moolenaar return (syn_name2id(name) > 0);
3365f9cc9f20SBram Moolenaar }
3366f9cc9f20SBram Moolenaar
3367f9cc9f20SBram Moolenaar # if defined(FEAT_SEARCH_EXTRA) || defined(PROTO)
3368f9cc9f20SBram Moolenaar /*
3369f9cc9f20SBram Moolenaar * Return the name of highlight group "id".
3370f9cc9f20SBram Moolenaar * When not a valid ID return an empty string.
3371f9cc9f20SBram Moolenaar */
3372f9cc9f20SBram Moolenaar char_u *
syn_id2name(int id)3373f9cc9f20SBram Moolenaar syn_id2name(int id)
3374f9cc9f20SBram Moolenaar {
3375f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len)
3376f9cc9f20SBram Moolenaar return (char_u *)"";
3377f9cc9f20SBram Moolenaar return HL_TABLE()[id - 1].sg_name;
3378f9cc9f20SBram Moolenaar }
3379f9cc9f20SBram Moolenaar # endif
3380f9cc9f20SBram Moolenaar #endif
3381f9cc9f20SBram Moolenaar
3382f9cc9f20SBram Moolenaar /*
3383f9cc9f20SBram Moolenaar * Like syn_name2id(), but take a pointer + length argument.
3384f9cc9f20SBram Moolenaar */
3385f9cc9f20SBram Moolenaar int
syn_namen2id(char_u * linep,int len)3386f9cc9f20SBram Moolenaar syn_namen2id(char_u *linep, int len)
3387f9cc9f20SBram Moolenaar {
3388f9cc9f20SBram Moolenaar char_u *name;
3389f9cc9f20SBram Moolenaar int id = 0;
3390f9cc9f20SBram Moolenaar
3391f9cc9f20SBram Moolenaar name = vim_strnsave(linep, len);
3392f9cc9f20SBram Moolenaar if (name != NULL)
3393f9cc9f20SBram Moolenaar {
3394f9cc9f20SBram Moolenaar id = syn_name2id(name);
3395f9cc9f20SBram Moolenaar vim_free(name);
3396f9cc9f20SBram Moolenaar }
3397f9cc9f20SBram Moolenaar return id;
3398f9cc9f20SBram Moolenaar }
3399f9cc9f20SBram Moolenaar
3400f9cc9f20SBram Moolenaar /*
3401f9cc9f20SBram Moolenaar * Find highlight group name in the table and return its ID.
3402f9cc9f20SBram Moolenaar * The argument is a pointer to the name and the length of the name.
3403f9cc9f20SBram Moolenaar * If it doesn't exist yet, a new entry is created.
3404f9cc9f20SBram Moolenaar * Return 0 for failure.
3405f9cc9f20SBram Moolenaar */
3406f9cc9f20SBram Moolenaar int
syn_check_group(char_u * pp,int len)3407f9cc9f20SBram Moolenaar syn_check_group(char_u *pp, int len)
3408f9cc9f20SBram Moolenaar {
3409f9cc9f20SBram Moolenaar int id;
3410f9cc9f20SBram Moolenaar char_u *name;
3411f9cc9f20SBram Moolenaar
3412f9cc9f20SBram Moolenaar name = vim_strnsave(pp, len);
3413f9cc9f20SBram Moolenaar if (name == NULL)
3414f9cc9f20SBram Moolenaar return 0;
3415f9cc9f20SBram Moolenaar
3416f9cc9f20SBram Moolenaar id = syn_name2id(name);
3417f9cc9f20SBram Moolenaar if (id == 0) // doesn't exist yet
3418f9cc9f20SBram Moolenaar id = syn_add_group(name);
3419f9cc9f20SBram Moolenaar else
3420f9cc9f20SBram Moolenaar vim_free(name);
3421f9cc9f20SBram Moolenaar return id;
3422f9cc9f20SBram Moolenaar }
3423f9cc9f20SBram Moolenaar
3424f9cc9f20SBram Moolenaar /*
3425f9cc9f20SBram Moolenaar * Add new highlight group and return its ID.
3426f9cc9f20SBram Moolenaar * "name" must be an allocated string, it will be consumed.
3427f9cc9f20SBram Moolenaar * Return 0 for failure.
3428f9cc9f20SBram Moolenaar */
3429f9cc9f20SBram Moolenaar static int
syn_add_group(char_u * name)3430f9cc9f20SBram Moolenaar syn_add_group(char_u *name)
3431f9cc9f20SBram Moolenaar {
3432f9cc9f20SBram Moolenaar char_u *p;
34336f10c70bSBram Moolenaar char_u *name_up;
3434f9cc9f20SBram Moolenaar
3435f9cc9f20SBram Moolenaar // Check that the name is ASCII letters, digits and underscore.
3436f9cc9f20SBram Moolenaar for (p = name; *p != NUL; ++p)
3437f9cc9f20SBram Moolenaar {
3438f9cc9f20SBram Moolenaar if (!vim_isprintc(*p))
3439f9cc9f20SBram Moolenaar {
3440f9cc9f20SBram Moolenaar emsg(_("E669: Unprintable character in group name"));
3441f9cc9f20SBram Moolenaar vim_free(name);
3442f9cc9f20SBram Moolenaar return 0;
3443f9cc9f20SBram Moolenaar }
3444f9cc9f20SBram Moolenaar else if (!ASCII_ISALNUM(*p) && *p != '_')
3445f9cc9f20SBram Moolenaar {
3446f9cc9f20SBram Moolenaar // This is an error, but since there previously was no check only
3447f9cc9f20SBram Moolenaar // give a warning.
3448f9cc9f20SBram Moolenaar msg_source(HL_ATTR(HLF_W));
3449f9cc9f20SBram Moolenaar msg(_("W18: Invalid character in group name"));
3450f9cc9f20SBram Moolenaar break;
3451f9cc9f20SBram Moolenaar }
3452f9cc9f20SBram Moolenaar }
3453f9cc9f20SBram Moolenaar
3454ad6b90c3SYegappan Lakshmanan // First call for this growarray: init growing array.
3455f9cc9f20SBram Moolenaar if (highlight_ga.ga_data == NULL)
3456f9cc9f20SBram Moolenaar {
3457f9cc9f20SBram Moolenaar highlight_ga.ga_itemsize = sizeof(hl_group_T);
3458f9cc9f20SBram Moolenaar highlight_ga.ga_growsize = 10;
3459f9cc9f20SBram Moolenaar }
3460f9cc9f20SBram Moolenaar
3461f9cc9f20SBram Moolenaar if (highlight_ga.ga_len >= MAX_HL_ID)
3462f9cc9f20SBram Moolenaar {
3463f9cc9f20SBram Moolenaar emsg(_("E849: Too many highlight and syntax groups"));
3464f9cc9f20SBram Moolenaar vim_free(name);
3465f9cc9f20SBram Moolenaar return 0;
3466f9cc9f20SBram Moolenaar }
3467f9cc9f20SBram Moolenaar
3468ad6b90c3SYegappan Lakshmanan // Make room for at least one other syntax_highlight entry.
3469f9cc9f20SBram Moolenaar if (ga_grow(&highlight_ga, 1) == FAIL)
3470f9cc9f20SBram Moolenaar {
3471f9cc9f20SBram Moolenaar vim_free(name);
3472f9cc9f20SBram Moolenaar return 0;
3473f9cc9f20SBram Moolenaar }
3474f9cc9f20SBram Moolenaar
34756f10c70bSBram Moolenaar name_up = vim_strsave_up(name);
34766f10c70bSBram Moolenaar if (name_up == NULL)
34776f10c70bSBram Moolenaar {
34786f10c70bSBram Moolenaar vim_free(name);
34796f10c70bSBram Moolenaar return 0;
34806f10c70bSBram Moolenaar }
34816f10c70bSBram Moolenaar
3482a80faa89SBram Moolenaar CLEAR_POINTER(&(HL_TABLE()[highlight_ga.ga_len]));
3483f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_name = name;
34846f10c70bSBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_name_u = name_up;
3485f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
3486f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_bg = INVALCOLOR;
3487f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR;
3488f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_sp = INVALCOLOR;
3489f9cc9f20SBram Moolenaar #endif
3490f9cc9f20SBram Moolenaar ++highlight_ga.ga_len;
3491f9cc9f20SBram Moolenaar
3492f9cc9f20SBram Moolenaar return highlight_ga.ga_len; // ID is index plus one
3493f9cc9f20SBram Moolenaar }
3494f9cc9f20SBram Moolenaar
3495f9cc9f20SBram Moolenaar /*
3496f9cc9f20SBram Moolenaar * When, just after calling syn_add_group(), an error is discovered, this
3497f9cc9f20SBram Moolenaar * function deletes the new name.
3498f9cc9f20SBram Moolenaar */
3499f9cc9f20SBram Moolenaar static void
syn_unadd_group(void)3500f9cc9f20SBram Moolenaar syn_unadd_group(void)
3501f9cc9f20SBram Moolenaar {
3502f9cc9f20SBram Moolenaar --highlight_ga.ga_len;
3503f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name);
3504f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u);
3505f9cc9f20SBram Moolenaar }
3506f9cc9f20SBram Moolenaar
3507f9cc9f20SBram Moolenaar /*
3508f9cc9f20SBram Moolenaar * Translate a group ID to highlight attributes.
3509f9cc9f20SBram Moolenaar */
3510f9cc9f20SBram Moolenaar int
syn_id2attr(int hl_id)3511f9cc9f20SBram Moolenaar syn_id2attr(int hl_id)
3512f9cc9f20SBram Moolenaar {
3513f9cc9f20SBram Moolenaar int attr;
3514f9cc9f20SBram Moolenaar hl_group_T *sgp;
3515f9cc9f20SBram Moolenaar
3516f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id);
3517f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one
3518f9cc9f20SBram Moolenaar
3519f9cc9f20SBram Moolenaar #ifdef FEAT_GUI
3520ad6b90c3SYegappan Lakshmanan // Only use GUI attr when the GUI is being used.
3521f9cc9f20SBram Moolenaar if (gui.in_use)
3522f9cc9f20SBram Moolenaar attr = sgp->sg_gui_attr;
3523f9cc9f20SBram Moolenaar else
3524f9cc9f20SBram Moolenaar #endif
3525f9cc9f20SBram Moolenaar if (IS_CTERM)
3526f9cc9f20SBram Moolenaar attr = sgp->sg_cterm_attr;
3527f9cc9f20SBram Moolenaar else
3528f9cc9f20SBram Moolenaar attr = sgp->sg_term_attr;
3529f9cc9f20SBram Moolenaar
3530f9cc9f20SBram Moolenaar return attr;
3531f9cc9f20SBram Moolenaar }
3532f9cc9f20SBram Moolenaar
3533f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO)
3534f9cc9f20SBram Moolenaar /*
3535f9cc9f20SBram Moolenaar * Get the GUI colors and attributes for a group ID.
3536f9cc9f20SBram Moolenaar * NOTE: the colors will be INVALCOLOR when not set, the color otherwise.
3537f9cc9f20SBram Moolenaar */
3538f9cc9f20SBram Moolenaar int
syn_id2colors(int hl_id,guicolor_T * fgp,guicolor_T * bgp)3539f9cc9f20SBram Moolenaar syn_id2colors(int hl_id, guicolor_T *fgp, guicolor_T *bgp)
3540f9cc9f20SBram Moolenaar {
3541f9cc9f20SBram Moolenaar hl_group_T *sgp;
3542f9cc9f20SBram Moolenaar
3543f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id);
3544f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one
3545f9cc9f20SBram Moolenaar
3546f9cc9f20SBram Moolenaar *fgp = sgp->sg_gui_fg;
3547f9cc9f20SBram Moolenaar *bgp = sgp->sg_gui_bg;
3548f9cc9f20SBram Moolenaar return sgp->sg_gui;
3549f9cc9f20SBram Moolenaar }
3550f9cc9f20SBram Moolenaar #endif
3551f9cc9f20SBram Moolenaar
3552f9cc9f20SBram Moolenaar #if (defined(MSWIN) \
3553f9cc9f20SBram Moolenaar && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \
3554219c7d06SBram Moolenaar && defined(FEAT_TERMGUICOLORS)) \
3555219c7d06SBram Moolenaar || defined(FEAT_TERMINAL) || defined(PROTO)
3556f9cc9f20SBram Moolenaar void
syn_id2cterm_bg(int hl_id,int * fgp,int * bgp)3557f9cc9f20SBram Moolenaar syn_id2cterm_bg(int hl_id, int *fgp, int *bgp)
3558f9cc9f20SBram Moolenaar {
3559f9cc9f20SBram Moolenaar hl_group_T *sgp;
3560f9cc9f20SBram Moolenaar
3561f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id);
3562f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one
3563f9cc9f20SBram Moolenaar *fgp = sgp->sg_cterm_fg - 1;
3564f9cc9f20SBram Moolenaar *bgp = sgp->sg_cterm_bg - 1;
3565f9cc9f20SBram Moolenaar }
3566f9cc9f20SBram Moolenaar #endif
3567f9cc9f20SBram Moolenaar
3568f9cc9f20SBram Moolenaar /*
3569f9cc9f20SBram Moolenaar * Translate a group ID to the final group ID (following links).
3570f9cc9f20SBram Moolenaar */
3571f9cc9f20SBram Moolenaar int
syn_get_final_id(int hl_id)3572f9cc9f20SBram Moolenaar syn_get_final_id(int hl_id)
3573f9cc9f20SBram Moolenaar {
3574f9cc9f20SBram Moolenaar int count;
3575f9cc9f20SBram Moolenaar hl_group_T *sgp;
3576f9cc9f20SBram Moolenaar
3577f9cc9f20SBram Moolenaar if (hl_id > highlight_ga.ga_len || hl_id < 1)
3578f9cc9f20SBram Moolenaar return 0; // Can be called from eval!!
3579f9cc9f20SBram Moolenaar
3580ad6b90c3SYegappan Lakshmanan // Follow links until there is no more.
3581ad6b90c3SYegappan Lakshmanan // Look out for loops! Break after 100 links.
3582f9cc9f20SBram Moolenaar for (count = 100; --count >= 0; )
3583f9cc9f20SBram Moolenaar {
3584f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one
3585f9cc9f20SBram Moolenaar if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len)
3586f9cc9f20SBram Moolenaar break;
3587f9cc9f20SBram Moolenaar hl_id = sgp->sg_link;
3588f9cc9f20SBram Moolenaar }
3589f9cc9f20SBram Moolenaar
3590f9cc9f20SBram Moolenaar return hl_id;
3591f9cc9f20SBram Moolenaar }
3592f9cc9f20SBram Moolenaar
3593f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO)
3594f9cc9f20SBram Moolenaar /*
3595f9cc9f20SBram Moolenaar * Call this function just after the GUI has started.
3596f9cc9f20SBram Moolenaar * Also called when 'termguicolors' was set, gui.in_use will be FALSE then.
3597f9cc9f20SBram Moolenaar * It finds the font and color handles for the highlighting groups.
3598f9cc9f20SBram Moolenaar */
3599f9cc9f20SBram Moolenaar void
highlight_gui_started(void)3600f9cc9f20SBram Moolenaar highlight_gui_started(void)
3601f9cc9f20SBram Moolenaar {
3602f9cc9f20SBram Moolenaar int idx;
3603f9cc9f20SBram Moolenaar
3604f9cc9f20SBram Moolenaar // First get the colors from the "Normal" and "Menu" group, if set
3605f9cc9f20SBram Moolenaar if (USE_24BIT)
3606f9cc9f20SBram Moolenaar set_normal_colors();
3607f9cc9f20SBram Moolenaar
3608f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx)
3609f9cc9f20SBram Moolenaar gui_do_one_color(idx, FALSE, FALSE);
3610f9cc9f20SBram Moolenaar
3611f9cc9f20SBram Moolenaar highlight_changed();
3612f9cc9f20SBram Moolenaar }
3613f9cc9f20SBram Moolenaar
3614f9cc9f20SBram Moolenaar static void
gui_do_one_color(int idx,int do_menu UNUSED,int do_tooltip UNUSED)3615f9cc9f20SBram Moolenaar gui_do_one_color(
3616f9cc9f20SBram Moolenaar int idx,
3617f9cc9f20SBram Moolenaar int do_menu UNUSED, // TRUE: might set the menu font
3618f9cc9f20SBram Moolenaar int do_tooltip UNUSED) // TRUE: might set the tooltip font
3619f9cc9f20SBram Moolenaar {
3620f9cc9f20SBram Moolenaar int didit = FALSE;
3621f9cc9f20SBram Moolenaar
3622f9cc9f20SBram Moolenaar # ifdef FEAT_GUI
3623f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS
3624f9cc9f20SBram Moolenaar if (gui.in_use)
3625f9cc9f20SBram Moolenaar # endif
3626f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font_name != NULL)
3627f9cc9f20SBram Moolenaar {
3628f9cc9f20SBram Moolenaar hl_do_font(idx, HL_TABLE()[idx].sg_font_name, FALSE, do_menu,
3629f9cc9f20SBram Moolenaar do_tooltip, TRUE);
3630f9cc9f20SBram Moolenaar didit = TRUE;
3631f9cc9f20SBram Moolenaar }
3632f9cc9f20SBram Moolenaar # endif
3633f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_fg_name != NULL)
3634f9cc9f20SBram Moolenaar {
3635f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg =
3636f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_fg_name);
3637f9cc9f20SBram Moolenaar didit = TRUE;
3638f9cc9f20SBram Moolenaar }
3639f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_bg_name != NULL)
3640f9cc9f20SBram Moolenaar {
3641f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg =
3642f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_bg_name);
3643f9cc9f20SBram Moolenaar didit = TRUE;
3644f9cc9f20SBram Moolenaar }
3645f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_sp_name != NULL)
3646f9cc9f20SBram Moolenaar {
3647f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_sp =
3648f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_sp_name);
3649f9cc9f20SBram Moolenaar didit = TRUE;
3650f9cc9f20SBram Moolenaar }
3651f9cc9f20SBram Moolenaar if (didit) // need to get a new attr number
3652f9cc9f20SBram Moolenaar set_hl_attr(idx);
3653f9cc9f20SBram Moolenaar }
3654f9cc9f20SBram Moolenaar #endif
3655f9cc9f20SBram Moolenaar
3656f9cc9f20SBram Moolenaar #if defined(USER_HIGHLIGHT) && defined(FEAT_STL_OPT)
3657f9cc9f20SBram Moolenaar /*
3658f9cc9f20SBram Moolenaar * Apply difference between User[1-9] and HLF_S to HLF_SNC, HLF_ST or HLF_STNC.
3659f9cc9f20SBram Moolenaar */
3660f9cc9f20SBram Moolenaar static void
combine_stl_hlt(int id,int id_S,int id_alt,int hlcnt,int i,int hlf,int * table)3661f9cc9f20SBram Moolenaar combine_stl_hlt(
3662f9cc9f20SBram Moolenaar int id,
3663f9cc9f20SBram Moolenaar int id_S,
3664f9cc9f20SBram Moolenaar int id_alt,
3665f9cc9f20SBram Moolenaar int hlcnt,
3666f9cc9f20SBram Moolenaar int i,
3667f9cc9f20SBram Moolenaar int hlf,
3668f9cc9f20SBram Moolenaar int *table)
3669f9cc9f20SBram Moolenaar {
3670f9cc9f20SBram Moolenaar hl_group_T *hlt = HL_TABLE();
3671f9cc9f20SBram Moolenaar
3672f9cc9f20SBram Moolenaar if (id_alt == 0)
3673f9cc9f20SBram Moolenaar {
3674a80faa89SBram Moolenaar CLEAR_POINTER(&hlt[hlcnt + i]);
3675f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_term = highlight_attr[hlf];
3676f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm = highlight_attr[hlf];
3677f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_EVAL)
3678f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui = highlight_attr[hlf];
3679f9cc9f20SBram Moolenaar # endif
3680f9cc9f20SBram Moolenaar }
3681f9cc9f20SBram Moolenaar else
3682f9cc9f20SBram Moolenaar mch_memmove(&hlt[hlcnt + i],
3683f9cc9f20SBram Moolenaar &hlt[id_alt - 1],
3684f9cc9f20SBram Moolenaar sizeof(hl_group_T));
3685f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_link = 0;
3686f9cc9f20SBram Moolenaar
3687f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_term ^=
3688f9cc9f20SBram Moolenaar hlt[id - 1].sg_term ^ hlt[id_S - 1].sg_term;
3689f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_start != hlt[id_S - 1].sg_start)
3690f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_start = hlt[id - 1].sg_start;
3691f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_stop != hlt[id_S - 1].sg_stop)
3692f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_stop = hlt[id - 1].sg_stop;
3693f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm ^=
3694f9cc9f20SBram Moolenaar hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm;
3695f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg)
3696f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg;
3697f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg)
3698f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg;
3699f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_EVAL)
3700f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui ^=
3701f9cc9f20SBram Moolenaar hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui;
3702f9cc9f20SBram Moolenaar # endif
3703f9cc9f20SBram Moolenaar # ifdef FEAT_GUI
3704f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_fg != hlt[id_S - 1].sg_gui_fg)
3705f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_fg = hlt[id - 1].sg_gui_fg;
3706f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_bg != hlt[id_S - 1].sg_gui_bg)
3707f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_bg = hlt[id - 1].sg_gui_bg;
3708f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_sp != hlt[id_S - 1].sg_gui_sp)
3709f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_sp = hlt[id - 1].sg_gui_sp;
3710f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_font != hlt[id_S - 1].sg_font)
3711f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_font = hlt[id - 1].sg_font;
3712f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
3713f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_fontset != hlt[id_S - 1].sg_fontset)
3714f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_fontset = hlt[id - 1].sg_fontset;
3715f9cc9f20SBram Moolenaar # endif
3716f9cc9f20SBram Moolenaar # endif
3717f9cc9f20SBram Moolenaar highlight_ga.ga_len = hlcnt + i + 1;
3718f9cc9f20SBram Moolenaar set_hl_attr(hlcnt + i); // At long last we can apply
3719f9cc9f20SBram Moolenaar table[i] = syn_id2attr(hlcnt + i + 1);
3720f9cc9f20SBram Moolenaar }
3721f9cc9f20SBram Moolenaar #endif
3722f9cc9f20SBram Moolenaar
3723f9cc9f20SBram Moolenaar /*
3724f9cc9f20SBram Moolenaar * Translate the 'highlight' option into attributes in highlight_attr[] and
3725f9cc9f20SBram Moolenaar * set up the user highlights User1..9. If FEAT_STL_OPT is in use, a set of
3726f9cc9f20SBram Moolenaar * corresponding highlights to use on top of HLF_SNC is computed.
3727f9cc9f20SBram Moolenaar * Called only when the 'highlight' option has been changed and upon first
3728f9cc9f20SBram Moolenaar * screen redraw after any :highlight command.
3729f9cc9f20SBram Moolenaar * Return FAIL when an invalid flag is found in 'highlight'. OK otherwise.
3730f9cc9f20SBram Moolenaar */
3731f9cc9f20SBram Moolenaar int
highlight_changed(void)3732f9cc9f20SBram Moolenaar highlight_changed(void)
3733f9cc9f20SBram Moolenaar {
3734f9cc9f20SBram Moolenaar int hlf;
3735f9cc9f20SBram Moolenaar int i;
3736f9cc9f20SBram Moolenaar char_u *p;
3737f9cc9f20SBram Moolenaar int attr;
3738f9cc9f20SBram Moolenaar char_u *end;
3739f9cc9f20SBram Moolenaar int id;
3740f9cc9f20SBram Moolenaar #ifdef USER_HIGHLIGHT
3741f9cc9f20SBram Moolenaar char_u userhl[30]; // use 30 to avoid compiler warning
3742f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT
3743f9cc9f20SBram Moolenaar int id_S = -1;
3744f9cc9f20SBram Moolenaar int id_SNC = 0;
3745f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL
3746f9cc9f20SBram Moolenaar int id_ST = 0;
3747f9cc9f20SBram Moolenaar int id_STNC = 0;
3748f9cc9f20SBram Moolenaar # endif
3749f9cc9f20SBram Moolenaar int hlcnt;
3750f9cc9f20SBram Moolenaar # endif
3751f9cc9f20SBram Moolenaar #endif
3752f9cc9f20SBram Moolenaar static int hl_flags[HLF_COUNT] = HL_FLAGS;
3753f9cc9f20SBram Moolenaar
3754f9cc9f20SBram Moolenaar need_highlight_changed = FALSE;
3755f9cc9f20SBram Moolenaar
3756*87fd0924SBram Moolenaar #ifdef FEAT_TERMINAL
3757*87fd0924SBram Moolenaar term_update_colors_all();
3758*87fd0924SBram Moolenaar term_update_wincolor_all();
3759*87fd0924SBram Moolenaar #endif
3760*87fd0924SBram Moolenaar
3761ad6b90c3SYegappan Lakshmanan // Clear all attributes.
3762f9cc9f20SBram Moolenaar for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
3763f9cc9f20SBram Moolenaar highlight_attr[hlf] = 0;
3764f9cc9f20SBram Moolenaar
3765ad6b90c3SYegappan Lakshmanan // First set all attributes to their default value.
3766ad6b90c3SYegappan Lakshmanan // Then use the attributes from the 'highlight' option.
3767f9cc9f20SBram Moolenaar for (i = 0; i < 2; ++i)
3768f9cc9f20SBram Moolenaar {
3769f9cc9f20SBram Moolenaar if (i)
3770f9cc9f20SBram Moolenaar p = p_hl;
3771f9cc9f20SBram Moolenaar else
3772f9cc9f20SBram Moolenaar p = get_highlight_default();
3773f9cc9f20SBram Moolenaar if (p == NULL) // just in case
3774f9cc9f20SBram Moolenaar continue;
3775f9cc9f20SBram Moolenaar
3776f9cc9f20SBram Moolenaar while (*p)
3777f9cc9f20SBram Moolenaar {
3778f9cc9f20SBram Moolenaar for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
3779f9cc9f20SBram Moolenaar if (hl_flags[hlf] == *p)
3780f9cc9f20SBram Moolenaar break;
3781f9cc9f20SBram Moolenaar ++p;
3782f9cc9f20SBram Moolenaar if (hlf == (int)HLF_COUNT || *p == NUL)
3783f9cc9f20SBram Moolenaar return FAIL;
3784f9cc9f20SBram Moolenaar
3785ad6b90c3SYegappan Lakshmanan // Allow several hl_flags to be combined, like "bu" for
3786ad6b90c3SYegappan Lakshmanan // bold-underlined.
3787f9cc9f20SBram Moolenaar attr = 0;
3788f9cc9f20SBram Moolenaar for ( ; *p && *p != ','; ++p) // parse up to comma
3789f9cc9f20SBram Moolenaar {
3790f9cc9f20SBram Moolenaar if (VIM_ISWHITE(*p)) // ignore white space
3791f9cc9f20SBram Moolenaar continue;
3792f9cc9f20SBram Moolenaar
3793f9cc9f20SBram Moolenaar if (attr > HL_ALL) // Combination with ':' is not allowed.
3794f9cc9f20SBram Moolenaar return FAIL;
3795f9cc9f20SBram Moolenaar
3796f9cc9f20SBram Moolenaar switch (*p)
3797f9cc9f20SBram Moolenaar {
3798f9cc9f20SBram Moolenaar case 'b': attr |= HL_BOLD;
3799f9cc9f20SBram Moolenaar break;
3800f9cc9f20SBram Moolenaar case 'i': attr |= HL_ITALIC;
3801f9cc9f20SBram Moolenaar break;
3802f9cc9f20SBram Moolenaar case '-':
3803f9cc9f20SBram Moolenaar case 'n': // no highlighting
3804f9cc9f20SBram Moolenaar break;
3805f9cc9f20SBram Moolenaar case 'r': attr |= HL_INVERSE;
3806f9cc9f20SBram Moolenaar break;
3807f9cc9f20SBram Moolenaar case 's': attr |= HL_STANDOUT;
3808f9cc9f20SBram Moolenaar break;
3809f9cc9f20SBram Moolenaar case 'u': attr |= HL_UNDERLINE;
3810f9cc9f20SBram Moolenaar break;
3811f9cc9f20SBram Moolenaar case 'c': attr |= HL_UNDERCURL;
3812f9cc9f20SBram Moolenaar break;
3813f9cc9f20SBram Moolenaar case 't': attr |= HL_STRIKETHROUGH;
3814f9cc9f20SBram Moolenaar break;
3815f9cc9f20SBram Moolenaar case ':': ++p; // highlight group name
3816f9cc9f20SBram Moolenaar if (attr || *p == NUL) // no combinations
3817f9cc9f20SBram Moolenaar return FAIL;
3818f9cc9f20SBram Moolenaar end = vim_strchr(p, ',');
3819f9cc9f20SBram Moolenaar if (end == NULL)
3820f9cc9f20SBram Moolenaar end = p + STRLEN(p);
3821f9cc9f20SBram Moolenaar id = syn_check_group(p, (int)(end - p));
3822f9cc9f20SBram Moolenaar if (id == 0)
3823f9cc9f20SBram Moolenaar return FAIL;
3824f9cc9f20SBram Moolenaar attr = syn_id2attr(id);
3825f9cc9f20SBram Moolenaar p = end - 1;
3826f9cc9f20SBram Moolenaar #if defined(FEAT_STL_OPT) && defined(USER_HIGHLIGHT)
3827f9cc9f20SBram Moolenaar if (hlf == (int)HLF_SNC)
3828f9cc9f20SBram Moolenaar id_SNC = syn_get_final_id(id);
3829f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL
3830f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_ST)
3831f9cc9f20SBram Moolenaar id_ST = syn_get_final_id(id);
3832f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_STNC)
3833f9cc9f20SBram Moolenaar id_STNC = syn_get_final_id(id);
3834f9cc9f20SBram Moolenaar # endif
3835f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_S)
3836f9cc9f20SBram Moolenaar id_S = syn_get_final_id(id);
3837f9cc9f20SBram Moolenaar #endif
3838f9cc9f20SBram Moolenaar break;
3839f9cc9f20SBram Moolenaar default: return FAIL;
3840f9cc9f20SBram Moolenaar }
3841f9cc9f20SBram Moolenaar }
3842f9cc9f20SBram Moolenaar highlight_attr[hlf] = attr;
3843f9cc9f20SBram Moolenaar
3844f9cc9f20SBram Moolenaar p = skip_to_option_part(p); // skip comma and spaces
3845f9cc9f20SBram Moolenaar }
3846f9cc9f20SBram Moolenaar }
3847f9cc9f20SBram Moolenaar
3848f9cc9f20SBram Moolenaar #ifdef USER_HIGHLIGHT
3849ad6b90c3SYegappan Lakshmanan // Setup the user highlights
3850ad6b90c3SYegappan Lakshmanan //
3851ad6b90c3SYegappan Lakshmanan // Temporarily utilize 28 more hl entries:
3852ad6b90c3SYegappan Lakshmanan // 9 for User1-User9 combined with StatusLineNC
3853ad6b90c3SYegappan Lakshmanan // 9 for User1-User9 combined with StatusLineTerm
3854ad6b90c3SYegappan Lakshmanan // 9 for User1-User9 combined with StatusLineTermNC
3855ad6b90c3SYegappan Lakshmanan // 1 for StatusLine default
3856ad6b90c3SYegappan Lakshmanan // Have to be in there simultaneously in case of table overflows in
3857ad6b90c3SYegappan Lakshmanan // get_attr_entry()
3858f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT
3859f9cc9f20SBram Moolenaar if (ga_grow(&highlight_ga, 28) == FAIL)
3860f9cc9f20SBram Moolenaar return FAIL;
3861f9cc9f20SBram Moolenaar hlcnt = highlight_ga.ga_len;
3862f9cc9f20SBram Moolenaar if (id_S == -1)
3863f9cc9f20SBram Moolenaar {
3864f9cc9f20SBram Moolenaar // Make sure id_S is always valid to simplify code below. Use the last
3865f9cc9f20SBram Moolenaar // entry.
3866a80faa89SBram Moolenaar CLEAR_POINTER(&HL_TABLE()[hlcnt + 27]);
3867f9cc9f20SBram Moolenaar HL_TABLE()[hlcnt + 18].sg_term = highlight_attr[HLF_S];
3868f9cc9f20SBram Moolenaar id_S = hlcnt + 19;
3869f9cc9f20SBram Moolenaar }
3870f9cc9f20SBram Moolenaar # endif
3871f9cc9f20SBram Moolenaar for (i = 0; i < 9; i++)
3872f9cc9f20SBram Moolenaar {
3873f9cc9f20SBram Moolenaar sprintf((char *)userhl, "User%d", i + 1);
3874f9cc9f20SBram Moolenaar id = syn_name2id(userhl);
3875f9cc9f20SBram Moolenaar if (id == 0)
3876f9cc9f20SBram Moolenaar {
3877f9cc9f20SBram Moolenaar highlight_user[i] = 0;
3878f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT
3879f9cc9f20SBram Moolenaar highlight_stlnc[i] = 0;
3880f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL
3881f9cc9f20SBram Moolenaar highlight_stlterm[i] = 0;
3882f9cc9f20SBram Moolenaar highlight_stltermnc[i] = 0;
3883f9cc9f20SBram Moolenaar # endif
3884f9cc9f20SBram Moolenaar # endif
3885f9cc9f20SBram Moolenaar }
3886f9cc9f20SBram Moolenaar else
3887f9cc9f20SBram Moolenaar {
3888f9cc9f20SBram Moolenaar highlight_user[i] = syn_id2attr(id);
3889f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT
3890f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_SNC, hlcnt, i,
3891f9cc9f20SBram Moolenaar HLF_SNC, highlight_stlnc);
3892f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL
3893f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_ST, hlcnt + 9, i,
3894f9cc9f20SBram Moolenaar HLF_ST, highlight_stlterm);
3895f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_STNC, hlcnt + 18, i,
3896f9cc9f20SBram Moolenaar HLF_STNC, highlight_stltermnc);
3897f9cc9f20SBram Moolenaar # endif
3898f9cc9f20SBram Moolenaar # endif
3899f9cc9f20SBram Moolenaar }
3900f9cc9f20SBram Moolenaar }
3901f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT
3902f9cc9f20SBram Moolenaar highlight_ga.ga_len = hlcnt;
3903f9cc9f20SBram Moolenaar # endif
3904f9cc9f20SBram Moolenaar
3905f9cc9f20SBram Moolenaar #endif // USER_HIGHLIGHT
3906f9cc9f20SBram Moolenaar
3907f9cc9f20SBram Moolenaar return OK;
3908f9cc9f20SBram Moolenaar }
3909f9cc9f20SBram Moolenaar
3910f9cc9f20SBram Moolenaar static void highlight_list(void);
3911f9cc9f20SBram Moolenaar static void highlight_list_two(int cnt, int attr);
3912f9cc9f20SBram Moolenaar
3913f9cc9f20SBram Moolenaar /*
3914f9cc9f20SBram Moolenaar * Handle command line completion for :highlight command.
3915f9cc9f20SBram Moolenaar */
3916f9cc9f20SBram Moolenaar void
set_context_in_highlight_cmd(expand_T * xp,char_u * arg)3917f9cc9f20SBram Moolenaar set_context_in_highlight_cmd(expand_T *xp, char_u *arg)
3918f9cc9f20SBram Moolenaar {
3919f9cc9f20SBram Moolenaar char_u *p;
3920f9cc9f20SBram Moolenaar
3921f9cc9f20SBram Moolenaar // Default: expand group names
3922f9cc9f20SBram Moolenaar xp->xp_context = EXPAND_HIGHLIGHT;
3923f9cc9f20SBram Moolenaar xp->xp_pattern = arg;
3924f9cc9f20SBram Moolenaar include_link = 2;
3925f9cc9f20SBram Moolenaar include_default = 1;
3926f9cc9f20SBram Moolenaar
3927f9cc9f20SBram Moolenaar // (part of) subcommand already typed
3928f9cc9f20SBram Moolenaar if (*arg != NUL)
3929f9cc9f20SBram Moolenaar {
3930f9cc9f20SBram Moolenaar p = skiptowhite(arg);
3931f9cc9f20SBram Moolenaar if (*p != NUL) // past "default" or group name
3932f9cc9f20SBram Moolenaar {
3933f9cc9f20SBram Moolenaar include_default = 0;
3934f9cc9f20SBram Moolenaar if (STRNCMP("default", arg, p - arg) == 0)
3935f9cc9f20SBram Moolenaar {
3936f9cc9f20SBram Moolenaar arg = skipwhite(p);
3937f9cc9f20SBram Moolenaar xp->xp_pattern = arg;
3938f9cc9f20SBram Moolenaar p = skiptowhite(arg);
3939f9cc9f20SBram Moolenaar }
3940f9cc9f20SBram Moolenaar if (*p != NUL) // past group name
3941f9cc9f20SBram Moolenaar {
3942f9cc9f20SBram Moolenaar include_link = 0;
3943f9cc9f20SBram Moolenaar if (arg[1] == 'i' && arg[0] == 'N')
3944f9cc9f20SBram Moolenaar highlight_list();
3945f9cc9f20SBram Moolenaar if (STRNCMP("link", arg, p - arg) == 0
3946f9cc9f20SBram Moolenaar || STRNCMP("clear", arg, p - arg) == 0)
3947f9cc9f20SBram Moolenaar {
3948f9cc9f20SBram Moolenaar xp->xp_pattern = skipwhite(p);
3949f9cc9f20SBram Moolenaar p = skiptowhite(xp->xp_pattern);
3950f9cc9f20SBram Moolenaar if (*p != NUL) // past first group name
3951f9cc9f20SBram Moolenaar {
3952f9cc9f20SBram Moolenaar xp->xp_pattern = skipwhite(p);
3953f9cc9f20SBram Moolenaar p = skiptowhite(xp->xp_pattern);
3954f9cc9f20SBram Moolenaar }
3955f9cc9f20SBram Moolenaar }
3956f9cc9f20SBram Moolenaar if (*p != NUL) // past group name(s)
3957f9cc9f20SBram Moolenaar xp->xp_context = EXPAND_NOTHING;
3958f9cc9f20SBram Moolenaar }
3959f9cc9f20SBram Moolenaar }
3960f9cc9f20SBram Moolenaar }
3961f9cc9f20SBram Moolenaar }
3962f9cc9f20SBram Moolenaar
3963f9cc9f20SBram Moolenaar /*
3964f9cc9f20SBram Moolenaar * List highlighting matches in a nice way.
3965f9cc9f20SBram Moolenaar */
3966f9cc9f20SBram Moolenaar static void
highlight_list(void)3967f9cc9f20SBram Moolenaar highlight_list(void)
3968f9cc9f20SBram Moolenaar {
3969f9cc9f20SBram Moolenaar int i;
3970f9cc9f20SBram Moolenaar
3971f9cc9f20SBram Moolenaar for (i = 10; --i >= 0; )
3972f9cc9f20SBram Moolenaar highlight_list_two(i, HL_ATTR(HLF_D));
3973f9cc9f20SBram Moolenaar for (i = 40; --i >= 0; )
3974f9cc9f20SBram Moolenaar highlight_list_two(99, 0);
3975f9cc9f20SBram Moolenaar }
3976f9cc9f20SBram Moolenaar
3977f9cc9f20SBram Moolenaar static void
highlight_list_two(int cnt,int attr)3978f9cc9f20SBram Moolenaar highlight_list_two(int cnt, int attr)
3979f9cc9f20SBram Moolenaar {
3980f9cc9f20SBram Moolenaar msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr);
3981f9cc9f20SBram Moolenaar msg_clr_eos();
3982f9cc9f20SBram Moolenaar out_flush();
3983f9cc9f20SBram Moolenaar ui_delay(cnt == 99 ? 40L : (long)cnt * 50L, FALSE);
3984f9cc9f20SBram Moolenaar }
3985f9cc9f20SBram Moolenaar
3986f9cc9f20SBram Moolenaar /*
3987f9cc9f20SBram Moolenaar * Function given to ExpandGeneric() to obtain the list of group names.
3988f9cc9f20SBram Moolenaar */
3989f9cc9f20SBram Moolenaar char_u *
get_highlight_name(expand_T * xp UNUSED,int idx)3990f9cc9f20SBram Moolenaar get_highlight_name(expand_T *xp UNUSED, int idx)
3991f9cc9f20SBram Moolenaar {
3992f9cc9f20SBram Moolenaar return get_highlight_name_ext(xp, idx, TRUE);
3993f9cc9f20SBram Moolenaar }
3994f9cc9f20SBram Moolenaar
3995f9cc9f20SBram Moolenaar /*
3996f9cc9f20SBram Moolenaar * Obtain a highlight group name.
3997f9cc9f20SBram Moolenaar * When "skip_cleared" is TRUE don't return a cleared entry.
3998f9cc9f20SBram Moolenaar */
3999f9cc9f20SBram Moolenaar char_u *
get_highlight_name_ext(expand_T * xp UNUSED,int idx,int skip_cleared)4000f9cc9f20SBram Moolenaar get_highlight_name_ext(expand_T *xp UNUSED, int idx, int skip_cleared)
4001f9cc9f20SBram Moolenaar {
4002f9cc9f20SBram Moolenaar if (idx < 0)
4003f9cc9f20SBram Moolenaar return NULL;
4004f9cc9f20SBram Moolenaar
4005f9cc9f20SBram Moolenaar // Items are never removed from the table, skip the ones that were
4006f9cc9f20SBram Moolenaar // cleared.
4007f9cc9f20SBram Moolenaar if (skip_cleared && idx < highlight_ga.ga_len && HL_TABLE()[idx].sg_cleared)
4008f9cc9f20SBram Moolenaar return (char_u *)"";
4009f9cc9f20SBram Moolenaar
4010f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len && include_none != 0)
4011f9cc9f20SBram Moolenaar return (char_u *)"none";
4012f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none && include_default != 0)
4013f9cc9f20SBram Moolenaar return (char_u *)"default";
4014f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none + include_default
4015f9cc9f20SBram Moolenaar && include_link != 0)
4016f9cc9f20SBram Moolenaar return (char_u *)"link";
4017f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none + include_default + 1
4018f9cc9f20SBram Moolenaar && include_link != 0)
4019f9cc9f20SBram Moolenaar return (char_u *)"clear";
4020f9cc9f20SBram Moolenaar if (idx >= highlight_ga.ga_len)
4021f9cc9f20SBram Moolenaar return NULL;
4022f9cc9f20SBram Moolenaar return HL_TABLE()[idx].sg_name;
4023f9cc9f20SBram Moolenaar }
4024f9cc9f20SBram Moolenaar
4025f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(PROTO)
4026f9cc9f20SBram Moolenaar /*
4027f9cc9f20SBram Moolenaar * Free all the highlight group fonts.
4028f9cc9f20SBram Moolenaar * Used when quitting for systems which need it.
4029f9cc9f20SBram Moolenaar */
4030f9cc9f20SBram Moolenaar void
free_highlight_fonts(void)4031f9cc9f20SBram Moolenaar free_highlight_fonts(void)
4032f9cc9f20SBram Moolenaar {
4033f9cc9f20SBram Moolenaar int idx;
4034f9cc9f20SBram Moolenaar
4035f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx)
4036f9cc9f20SBram Moolenaar {
4037f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font);
4038f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT;
4039f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
4040f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset);
4041f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET;
4042f9cc9f20SBram Moolenaar # endif
4043f9cc9f20SBram Moolenaar }
4044f9cc9f20SBram Moolenaar
4045f9cc9f20SBram Moolenaar gui_mch_free_font(gui.norm_font);
4046f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET
4047f9cc9f20SBram Moolenaar gui_mch_free_fontset(gui.fontset);
4048f9cc9f20SBram Moolenaar # endif
4049f9cc9f20SBram Moolenaar # ifndef FEAT_GUI_GTK
4050f9cc9f20SBram Moolenaar gui_mch_free_font(gui.bold_font);
4051f9cc9f20SBram Moolenaar gui_mch_free_font(gui.ital_font);
4052f9cc9f20SBram Moolenaar gui_mch_free_font(gui.boldital_font);
4053f9cc9f20SBram Moolenaar # endif
4054f9cc9f20SBram Moolenaar }
4055f9cc9f20SBram Moolenaar #endif
4056d1a8d658SYegappan Lakshmanan
4057d1a8d658SYegappan Lakshmanan #if defined(FEAT_EVAL) || defined(PROTO)
4058d1a8d658SYegappan Lakshmanan /*
4059d1a8d658SYegappan Lakshmanan * Convert each of the highlight attribute bits (bold, standout, underline,
4060d1a8d658SYegappan Lakshmanan * etc.) set in 'hlattr' into a separate boolean item in a Dictionary with
4061d1a8d658SYegappan Lakshmanan * the attribute name as the key.
4062d1a8d658SYegappan Lakshmanan */
4063d1a8d658SYegappan Lakshmanan static dict_T *
highlight_get_attr_dict(int hlattr)4064d1a8d658SYegappan Lakshmanan highlight_get_attr_dict(int hlattr)
4065d1a8d658SYegappan Lakshmanan {
4066d1a8d658SYegappan Lakshmanan dict_T *dict;
4067d1a8d658SYegappan Lakshmanan int i;
4068d1a8d658SYegappan Lakshmanan
4069d1a8d658SYegappan Lakshmanan dict = dict_alloc();
4070d1a8d658SYegappan Lakshmanan if (dict == NULL)
4071d1a8d658SYegappan Lakshmanan return NULL;
4072d1a8d658SYegappan Lakshmanan
4073d1a8d658SYegappan Lakshmanan for (i = 0; hl_attr_table[i] != 0; ++i)
4074d1a8d658SYegappan Lakshmanan {
4075d1a8d658SYegappan Lakshmanan if (hlattr & hl_attr_table[i])
4076d1a8d658SYegappan Lakshmanan {
4077d1a8d658SYegappan Lakshmanan dict_add_bool(dict, hl_name_table[i], VVAL_TRUE);
4078d1a8d658SYegappan Lakshmanan hlattr &= ~hl_attr_table[i]; // don't want "inverse"
4079d1a8d658SYegappan Lakshmanan }
4080d1a8d658SYegappan Lakshmanan }
4081d1a8d658SYegappan Lakshmanan
4082d1a8d658SYegappan Lakshmanan return dict;
4083d1a8d658SYegappan Lakshmanan }
4084d1a8d658SYegappan Lakshmanan
4085d1a8d658SYegappan Lakshmanan /*
4086d1a8d658SYegappan Lakshmanan * Return the attributes of the highlight group at index 'hl_idx' as a
4087d1a8d658SYegappan Lakshmanan * Dictionary. If 'resolve_link' is TRUE, then resolves the highlight group
4088d1a8d658SYegappan Lakshmanan * links recursively.
4089d1a8d658SYegappan Lakshmanan */
4090d1a8d658SYegappan Lakshmanan static dict_T *
highlight_get_info(int hl_idx,int resolve_link)4091d1a8d658SYegappan Lakshmanan highlight_get_info(int hl_idx, int resolve_link)
4092d1a8d658SYegappan Lakshmanan {
4093d1a8d658SYegappan Lakshmanan dict_T *dict;
4094d1a8d658SYegappan Lakshmanan hl_group_T *sgp;
4095d1a8d658SYegappan Lakshmanan dict_T *attr_dict;
4096d1a8d658SYegappan Lakshmanan int hlgid;
4097d1a8d658SYegappan Lakshmanan
4098d1a8d658SYegappan Lakshmanan dict = dict_alloc();
4099d1a8d658SYegappan Lakshmanan if (dict == NULL)
4100d1a8d658SYegappan Lakshmanan return dict;
4101d1a8d658SYegappan Lakshmanan
4102d1a8d658SYegappan Lakshmanan sgp = &HL_TABLE()[hl_idx];
4103d1a8d658SYegappan Lakshmanan // highlight group id is 1-based
4104d1a8d658SYegappan Lakshmanan hlgid = hl_idx + 1;
4105d1a8d658SYegappan Lakshmanan
4106d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "name", sgp->sg_name) == FAIL)
4107d1a8d658SYegappan Lakshmanan goto error;
4108d1a8d658SYegappan Lakshmanan if (dict_add_number(dict, "id", hlgid) == FAIL)
4109d1a8d658SYegappan Lakshmanan goto error;
4110d1a8d658SYegappan Lakshmanan
4111d1a8d658SYegappan Lakshmanan if (sgp->sg_link && resolve_link)
4112d1a8d658SYegappan Lakshmanan {
4113d1a8d658SYegappan Lakshmanan // resolve the highlight group link recursively
4114d1a8d658SYegappan Lakshmanan while (sgp->sg_link)
4115d1a8d658SYegappan Lakshmanan {
4116d1a8d658SYegappan Lakshmanan hlgid = sgp->sg_link;
4117d1a8d658SYegappan Lakshmanan sgp = &HL_TABLE()[sgp->sg_link - 1];
4118d1a8d658SYegappan Lakshmanan }
4119d1a8d658SYegappan Lakshmanan }
4120d1a8d658SYegappan Lakshmanan
4121d1a8d658SYegappan Lakshmanan if (sgp->sg_term != 0)
4122d1a8d658SYegappan Lakshmanan {
4123d1a8d658SYegappan Lakshmanan attr_dict = highlight_get_attr_dict(sgp->sg_term);
4124d1a8d658SYegappan Lakshmanan if (attr_dict != NULL)
4125d1a8d658SYegappan Lakshmanan if (dict_add_dict(dict, "term", attr_dict) == FAIL)
4126d1a8d658SYegappan Lakshmanan goto error;
4127d1a8d658SYegappan Lakshmanan }
4128d1a8d658SYegappan Lakshmanan if (sgp->sg_start != NULL)
4129d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "start", sgp->sg_start) == FAIL)
4130d1a8d658SYegappan Lakshmanan goto error;
4131d1a8d658SYegappan Lakshmanan if (sgp->sg_stop != NULL)
4132d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "stop", sgp->sg_stop) == FAIL)
4133d1a8d658SYegappan Lakshmanan goto error;
4134d1a8d658SYegappan Lakshmanan if (sgp->sg_cterm != 0)
4135d1a8d658SYegappan Lakshmanan {
4136d1a8d658SYegappan Lakshmanan attr_dict = highlight_get_attr_dict(sgp->sg_cterm);
4137d1a8d658SYegappan Lakshmanan if (attr_dict != NULL)
4138d1a8d658SYegappan Lakshmanan if (dict_add_dict(dict, "cterm", attr_dict) == FAIL)
4139d1a8d658SYegappan Lakshmanan goto error;
4140d1a8d658SYegappan Lakshmanan }
4141d1a8d658SYegappan Lakshmanan if (sgp->sg_cterm_fg != 0)
4142d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "ctermfg",
4143d1a8d658SYegappan Lakshmanan highlight_color(hlgid, (char_u *)"fg", 'c')) == FAIL)
4144d1a8d658SYegappan Lakshmanan goto error;
4145d1a8d658SYegappan Lakshmanan if (sgp->sg_cterm_bg != 0)
4146d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "ctermbg",
4147d1a8d658SYegappan Lakshmanan highlight_color(hlgid, (char_u *)"bg", 'c')) == FAIL)
4148d1a8d658SYegappan Lakshmanan goto error;
4149d1a8d658SYegappan Lakshmanan if (sgp->sg_cterm_ul != 0)
4150d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "ctermul",
4151d1a8d658SYegappan Lakshmanan highlight_color(hlgid, (char_u *)"ul", 'c')) == FAIL)
4152d1a8d658SYegappan Lakshmanan goto error;
4153d1a8d658SYegappan Lakshmanan if (sgp->sg_gui != 0)
4154d1a8d658SYegappan Lakshmanan {
4155d1a8d658SYegappan Lakshmanan attr_dict = highlight_get_attr_dict(sgp->sg_gui);
4156d1a8d658SYegappan Lakshmanan if (attr_dict != NULL)
4157d1a8d658SYegappan Lakshmanan if (dict_add_dict(dict, "gui", attr_dict) == FAIL)
4158d1a8d658SYegappan Lakshmanan goto error;
4159d1a8d658SYegappan Lakshmanan }
4160d1a8d658SYegappan Lakshmanan if (sgp->sg_gui_fg_name != NULL)
4161d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "guifg",
4162d1a8d658SYegappan Lakshmanan highlight_color(hlgid, (char_u *)"fg", 'g')) == FAIL)
4163d1a8d658SYegappan Lakshmanan goto error;
4164d1a8d658SYegappan Lakshmanan if (sgp->sg_gui_bg_name != NULL)
4165d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "guibg",
4166d1a8d658SYegappan Lakshmanan highlight_color(hlgid, (char_u *)"bg", 'g')) == FAIL)
4167d1a8d658SYegappan Lakshmanan goto error;
4168d1a8d658SYegappan Lakshmanan if (sgp->sg_gui_sp_name != NULL)
4169d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "guisp",
4170d1a8d658SYegappan Lakshmanan highlight_color(hlgid, (char_u *)"sp", 'g')) == FAIL)
4171d1a8d658SYegappan Lakshmanan goto error;
4172d1a8d658SYegappan Lakshmanan # ifdef FEAT_GUI
4173d1a8d658SYegappan Lakshmanan if (sgp->sg_font_name != NULL)
4174d1a8d658SYegappan Lakshmanan if (dict_add_string(dict, "font", sgp->sg_font_name) == FAIL)
4175d1a8d658SYegappan Lakshmanan goto error;
4176d1a8d658SYegappan Lakshmanan # endif
4177d1a8d658SYegappan Lakshmanan if (sgp->sg_link)
4178d1a8d658SYegappan Lakshmanan {
4179d1a8d658SYegappan Lakshmanan char_u *link;
4180d1a8d658SYegappan Lakshmanan
4181d1a8d658SYegappan Lakshmanan link = HL_TABLE()[sgp->sg_link - 1].sg_name;
4182d1a8d658SYegappan Lakshmanan if (link != NULL && dict_add_string(dict, "linksto", link) == FAIL)
4183d1a8d658SYegappan Lakshmanan goto error;
41842a16dc66SYegappan Lakshmanan
41852a16dc66SYegappan Lakshmanan if (sgp->sg_deflink)
41862a16dc66SYegappan Lakshmanan dict_add_bool(dict, "default", VVAL_TRUE);
4187d1a8d658SYegappan Lakshmanan }
4188d1a8d658SYegappan Lakshmanan if (dict_len(dict) == 2)
4189d1a8d658SYegappan Lakshmanan // If only 'name' is present, then the highlight group is cleared.
4190d1a8d658SYegappan Lakshmanan dict_add_bool(dict, "cleared", VVAL_TRUE);
4191d1a8d658SYegappan Lakshmanan
4192d1a8d658SYegappan Lakshmanan return dict;
4193d1a8d658SYegappan Lakshmanan
4194d1a8d658SYegappan Lakshmanan error:
4195d1a8d658SYegappan Lakshmanan vim_free(dict);
4196d1a8d658SYegappan Lakshmanan return NULL;
4197d1a8d658SYegappan Lakshmanan }
4198d1a8d658SYegappan Lakshmanan
4199d1a8d658SYegappan Lakshmanan /*
4200d1a8d658SYegappan Lakshmanan * "hlget([name])" function
4201d1a8d658SYegappan Lakshmanan * Return the attributes of a specific highlight group (if specified) or all
4202d1a8d658SYegappan Lakshmanan * the highlight groups.
4203d1a8d658SYegappan Lakshmanan */
4204d1a8d658SYegappan Lakshmanan void
f_hlget(typval_T * argvars,typval_T * rettv)4205d1a8d658SYegappan Lakshmanan f_hlget(typval_T *argvars, typval_T *rettv)
4206d1a8d658SYegappan Lakshmanan {
4207d1a8d658SYegappan Lakshmanan list_T *list;
4208d1a8d658SYegappan Lakshmanan dict_T *dict;
4209d1a8d658SYegappan Lakshmanan int i;
4210d1a8d658SYegappan Lakshmanan char_u *hlarg = NULL;
4211d1a8d658SYegappan Lakshmanan int resolve_link = FALSE;
4212d1a8d658SYegappan Lakshmanan
4213d1a8d658SYegappan Lakshmanan if (rettv_list_alloc(rettv) == FAIL)
4214d1a8d658SYegappan Lakshmanan return;
4215d1a8d658SYegappan Lakshmanan
4216d1a8d658SYegappan Lakshmanan if (check_for_opt_string_arg(argvars, 0) == FAIL
4217d1a8d658SYegappan Lakshmanan || (argvars[0].v_type != VAR_UNKNOWN
4218d1a8d658SYegappan Lakshmanan && check_for_opt_bool_arg(argvars, 1) == FAIL))
4219d1a8d658SYegappan Lakshmanan return;
4220d1a8d658SYegappan Lakshmanan
4221d1a8d658SYegappan Lakshmanan if (argvars[0].v_type != VAR_UNKNOWN)
4222d1a8d658SYegappan Lakshmanan {
4223d1a8d658SYegappan Lakshmanan // highlight group name supplied
4224d1a8d658SYegappan Lakshmanan hlarg = tv_get_string_chk(&argvars[0]);
4225d1a8d658SYegappan Lakshmanan if (hlarg == NULL)
4226d1a8d658SYegappan Lakshmanan return;
4227d1a8d658SYegappan Lakshmanan
4228d1a8d658SYegappan Lakshmanan if (argvars[1].v_type != VAR_UNKNOWN)
4229d1a8d658SYegappan Lakshmanan {
4230d1a8d658SYegappan Lakshmanan int error = FALSE;
4231d1a8d658SYegappan Lakshmanan
4232d1a8d658SYegappan Lakshmanan resolve_link = tv_get_bool_chk(&argvars[1], &error);
4233d1a8d658SYegappan Lakshmanan if (error)
4234d1a8d658SYegappan Lakshmanan return;
4235d1a8d658SYegappan Lakshmanan }
4236d1a8d658SYegappan Lakshmanan }
4237d1a8d658SYegappan Lakshmanan
4238d1a8d658SYegappan Lakshmanan list = rettv->vval.v_list;
4239d1a8d658SYegappan Lakshmanan for (i = 0; i < highlight_ga.ga_len && !got_int; ++i)
4240d1a8d658SYegappan Lakshmanan {
4241d1a8d658SYegappan Lakshmanan if (hlarg == NULL || STRICMP(hlarg, HL_TABLE()[i].sg_name) == 0)
4242d1a8d658SYegappan Lakshmanan {
4243d1a8d658SYegappan Lakshmanan dict = highlight_get_info(i, resolve_link);
4244d1a8d658SYegappan Lakshmanan if (dict != NULL)
4245d1a8d658SYegappan Lakshmanan list_append_dict(list, dict);
4246d1a8d658SYegappan Lakshmanan }
4247d1a8d658SYegappan Lakshmanan }
4248d1a8d658SYegappan Lakshmanan }
4249d1a8d658SYegappan Lakshmanan
4250d1a8d658SYegappan Lakshmanan /*
4251d1a8d658SYegappan Lakshmanan * Returns the string value at 'dict[key]'. Returns NULL, if 'key' is not in
4252d1a8d658SYegappan Lakshmanan * 'dict' or the value is not a string type. If the value is not a string type
4253d1a8d658SYegappan Lakshmanan * or is NULL, then 'error' is set to TRUE.
4254d1a8d658SYegappan Lakshmanan */
4255d1a8d658SYegappan Lakshmanan static char_u *
hldict_get_string(dict_T * dict,char_u * key,int * error)4256d1a8d658SYegappan Lakshmanan hldict_get_string(dict_T *dict, char_u *key, int *error)
4257d1a8d658SYegappan Lakshmanan {
4258d1a8d658SYegappan Lakshmanan dictitem_T *di;
4259d1a8d658SYegappan Lakshmanan
4260d1a8d658SYegappan Lakshmanan *error = FALSE;
4261d1a8d658SYegappan Lakshmanan di = dict_find(dict, key, -1);
4262d1a8d658SYegappan Lakshmanan if (di == NULL)
4263d1a8d658SYegappan Lakshmanan return NULL;
4264d1a8d658SYegappan Lakshmanan
4265d1a8d658SYegappan Lakshmanan if (di->di_tv.v_type != VAR_STRING || di->di_tv.vval.v_string == NULL)
4266d1a8d658SYegappan Lakshmanan {
4267d1a8d658SYegappan Lakshmanan emsg(_(e_stringreq));
4268d1a8d658SYegappan Lakshmanan *error = TRUE;
4269d1a8d658SYegappan Lakshmanan return NULL;
4270d1a8d658SYegappan Lakshmanan }
4271d1a8d658SYegappan Lakshmanan
4272d1a8d658SYegappan Lakshmanan return di->di_tv.vval.v_string;
4273d1a8d658SYegappan Lakshmanan }
4274d1a8d658SYegappan Lakshmanan
4275d1a8d658SYegappan Lakshmanan /*
4276d1a8d658SYegappan Lakshmanan * Convert the highlight attribute Dictionary at 'dict[key]' into a string
4277d1a8d658SYegappan Lakshmanan * value in 'attr_str' of length 'len'. Returns FALSE if 'dict[key]' is not a
4278d1a8d658SYegappan Lakshmanan * Dictionary or is NULL.
4279d1a8d658SYegappan Lakshmanan */
4280d1a8d658SYegappan Lakshmanan static int
hldict_attr_to_str(dict_T * dict,char_u * key,char_u * attr_str,int len)4281d1a8d658SYegappan Lakshmanan hldict_attr_to_str(
4282d1a8d658SYegappan Lakshmanan dict_T *dict,
4283d1a8d658SYegappan Lakshmanan char_u *key,
4284d1a8d658SYegappan Lakshmanan char_u *attr_str,
4285d1a8d658SYegappan Lakshmanan int len)
4286d1a8d658SYegappan Lakshmanan {
4287d1a8d658SYegappan Lakshmanan dictitem_T *di;
4288d1a8d658SYegappan Lakshmanan dict_T *attrdict;
4289d1a8d658SYegappan Lakshmanan int i;
4290d1a8d658SYegappan Lakshmanan
4291d1a8d658SYegappan Lakshmanan attr_str[0] = NUL;
4292d1a8d658SYegappan Lakshmanan di = dict_find(dict, key, -1);
4293d1a8d658SYegappan Lakshmanan if (di == NULL)
4294d1a8d658SYegappan Lakshmanan return TRUE;
4295d1a8d658SYegappan Lakshmanan
4296d1a8d658SYegappan Lakshmanan if (di->di_tv.v_type != VAR_DICT || di->di_tv.vval.v_dict == NULL)
4297d1a8d658SYegappan Lakshmanan {
4298d1a8d658SYegappan Lakshmanan emsg(_(e_dictreq));
4299d1a8d658SYegappan Lakshmanan return FALSE;
4300d1a8d658SYegappan Lakshmanan }
4301d1a8d658SYegappan Lakshmanan
4302d1a8d658SYegappan Lakshmanan attrdict = di->di_tv.vval.v_dict;
4303d1a8d658SYegappan Lakshmanan
4304d1a8d658SYegappan Lakshmanan // If the attribute dict is empty, then return NONE to clear the attributes
4305d1a8d658SYegappan Lakshmanan if (dict_len(attrdict) == 0)
4306d1a8d658SYegappan Lakshmanan {
4307d1a8d658SYegappan Lakshmanan vim_strcat(attr_str, (char_u *)"NONE", len);
4308d1a8d658SYegappan Lakshmanan return TRUE;
4309d1a8d658SYegappan Lakshmanan }
4310d1a8d658SYegappan Lakshmanan
4311d1a8d658SYegappan Lakshmanan for (i = 0; i < (int)ARRAY_LENGTH(hl_name_table); i++)
4312d1a8d658SYegappan Lakshmanan {
4313d1a8d658SYegappan Lakshmanan if (dict_get_bool(attrdict, (char_u *)hl_name_table[i],
4314d1a8d658SYegappan Lakshmanan VVAL_FALSE) == VVAL_TRUE)
4315d1a8d658SYegappan Lakshmanan {
4316d1a8d658SYegappan Lakshmanan if (attr_str[0] != NUL)
4317d1a8d658SYegappan Lakshmanan vim_strcat(attr_str, (char_u *)",", len);
4318d1a8d658SYegappan Lakshmanan vim_strcat(attr_str, (char_u *)hl_name_table[i], len);
4319d1a8d658SYegappan Lakshmanan }
4320d1a8d658SYegappan Lakshmanan }
4321d1a8d658SYegappan Lakshmanan
4322d1a8d658SYegappan Lakshmanan return TRUE;
4323d1a8d658SYegappan Lakshmanan }
4324d1a8d658SYegappan Lakshmanan
4325d1a8d658SYegappan Lakshmanan /*
4326d1a8d658SYegappan Lakshmanan * Add or update a highlight group using 'dict' items. Returns TRUE if
4327d1a8d658SYegappan Lakshmanan * successfully updated the highlight group.
4328d1a8d658SYegappan Lakshmanan */
4329d1a8d658SYegappan Lakshmanan static int
hlg_add_or_update(dict_T * dict)4330d1a8d658SYegappan Lakshmanan hlg_add_or_update(dict_T *dict)
4331d1a8d658SYegappan Lakshmanan {
4332d1a8d658SYegappan Lakshmanan char_u *name;
4333d1a8d658SYegappan Lakshmanan int error;
4334d1a8d658SYegappan Lakshmanan char_u term_attr[80];
4335d1a8d658SYegappan Lakshmanan char_u cterm_attr[80];
4336d1a8d658SYegappan Lakshmanan char_u gui_attr[80];
4337d1a8d658SYegappan Lakshmanan char_u *start;
4338d1a8d658SYegappan Lakshmanan char_u *stop;
4339d1a8d658SYegappan Lakshmanan char_u *ctermfg;
4340d1a8d658SYegappan Lakshmanan char_u *ctermbg;
4341d1a8d658SYegappan Lakshmanan char_u *ctermul;
4342d1a8d658SYegappan Lakshmanan char_u *guifg;
4343d1a8d658SYegappan Lakshmanan char_u *guibg;
4344d1a8d658SYegappan Lakshmanan char_u *guisp;
4345d1a8d658SYegappan Lakshmanan # ifdef FEAT_GUI
4346d1a8d658SYegappan Lakshmanan char_u *font;
4347d1a8d658SYegappan Lakshmanan # endif
43482a16dc66SYegappan Lakshmanan int forceit = FALSE;
43492a16dc66SYegappan Lakshmanan int dodefault = FALSE;
43502a16dc66SYegappan Lakshmanan int done = FALSE;
4351d1a8d658SYegappan Lakshmanan
4352d1a8d658SYegappan Lakshmanan name = hldict_get_string(dict, (char_u *)"name", &error);
4353d1a8d658SYegappan Lakshmanan if (name == NULL || error)
4354d1a8d658SYegappan Lakshmanan return FALSE;
4355d1a8d658SYegappan Lakshmanan
43562a16dc66SYegappan Lakshmanan if (dict_get_bool(dict, (char_u *)"force", VVAL_FALSE) == VVAL_TRUE)
43572a16dc66SYegappan Lakshmanan forceit = TRUE;
4358d1a8d658SYegappan Lakshmanan
43592a16dc66SYegappan Lakshmanan if (dict_get_bool(dict, (char_u *)"default", VVAL_FALSE) == VVAL_TRUE)
43602a16dc66SYegappan Lakshmanan dodefault = TRUE;
4361d1a8d658SYegappan Lakshmanan
4362d1a8d658SYegappan Lakshmanan if (dict_find(dict, (char_u *)"cleared", -1) != NULL)
4363d1a8d658SYegappan Lakshmanan {
4364d1a8d658SYegappan Lakshmanan varnumber_T cleared;
4365d1a8d658SYegappan Lakshmanan
4366d1a8d658SYegappan Lakshmanan // clear a highlight group
4367d1a8d658SYegappan Lakshmanan cleared = dict_get_bool(dict, (char_u *)"cleared", FALSE);
4368d1a8d658SYegappan Lakshmanan if (cleared == TRUE)
4369d1a8d658SYegappan Lakshmanan {
4370d1a8d658SYegappan Lakshmanan vim_snprintf((char *)IObuff, IOSIZE, "clear %s", name);
43712a16dc66SYegappan Lakshmanan do_highlight(IObuff, forceit, FALSE);
43722a16dc66SYegappan Lakshmanan done = TRUE;
43732a16dc66SYegappan Lakshmanan }
4374d1a8d658SYegappan Lakshmanan }
4375d1a8d658SYegappan Lakshmanan
43762a16dc66SYegappan Lakshmanan if (dict_find(dict, (char_u *)"linksto", -1) != NULL)
43772a16dc66SYegappan Lakshmanan {
43782a16dc66SYegappan Lakshmanan char_u *linksto;
43792a16dc66SYegappan Lakshmanan
43802a16dc66SYegappan Lakshmanan // link highlight groups
43812a16dc66SYegappan Lakshmanan linksto = hldict_get_string(dict, (char_u *)"linksto", &error);
43822a16dc66SYegappan Lakshmanan if (linksto == NULL || error)
43832a16dc66SYegappan Lakshmanan return FALSE;
43842a16dc66SYegappan Lakshmanan
43852a16dc66SYegappan Lakshmanan vim_snprintf((char *)IObuff, IOSIZE, "%slink %s %s",
43862a16dc66SYegappan Lakshmanan dodefault ? "default " : "", name, linksto);
43872a16dc66SYegappan Lakshmanan do_highlight(IObuff, forceit, FALSE);
43882a16dc66SYegappan Lakshmanan
43892a16dc66SYegappan Lakshmanan done = TRUE;
4390d1a8d658SYegappan Lakshmanan }
4391d1a8d658SYegappan Lakshmanan
43922a16dc66SYegappan Lakshmanan // If 'cleared' or 'linksto' are specified, then don't process the other
43932a16dc66SYegappan Lakshmanan // attributes.
43942a16dc66SYegappan Lakshmanan if (done)
43952a16dc66SYegappan Lakshmanan return TRUE;
43962a16dc66SYegappan Lakshmanan
4397d1a8d658SYegappan Lakshmanan start = hldict_get_string(dict, (char_u *)"start", &error);
4398d1a8d658SYegappan Lakshmanan if (error)
4399d1a8d658SYegappan Lakshmanan return FALSE;
4400d1a8d658SYegappan Lakshmanan
4401d1a8d658SYegappan Lakshmanan stop = hldict_get_string(dict, (char_u *)"stop", &error);
4402d1a8d658SYegappan Lakshmanan if (error)
4403d1a8d658SYegappan Lakshmanan return FALSE;
4404d1a8d658SYegappan Lakshmanan
4405d1a8d658SYegappan Lakshmanan if (!hldict_attr_to_str(dict, (char_u *)"term", term_attr,
4406d1a8d658SYegappan Lakshmanan sizeof(term_attr)))
4407d1a8d658SYegappan Lakshmanan return FALSE;
4408d1a8d658SYegappan Lakshmanan
4409d1a8d658SYegappan Lakshmanan if (!hldict_attr_to_str(dict, (char_u *)"cterm", cterm_attr,
4410d1a8d658SYegappan Lakshmanan sizeof(cterm_attr)))
4411d1a8d658SYegappan Lakshmanan return FALSE;
4412d1a8d658SYegappan Lakshmanan
4413d1a8d658SYegappan Lakshmanan ctermfg = hldict_get_string(dict, (char_u *)"ctermfg", &error);
4414d1a8d658SYegappan Lakshmanan if (error)
4415d1a8d658SYegappan Lakshmanan return FALSE;
4416d1a8d658SYegappan Lakshmanan
4417d1a8d658SYegappan Lakshmanan ctermbg = hldict_get_string(dict, (char_u *)"ctermbg", &error);
4418d1a8d658SYegappan Lakshmanan if (error)
4419d1a8d658SYegappan Lakshmanan return FALSE;
4420d1a8d658SYegappan Lakshmanan
4421d1a8d658SYegappan Lakshmanan ctermul = hldict_get_string(dict, (char_u *)"ctermul", &error);
4422d1a8d658SYegappan Lakshmanan if (error)
4423d1a8d658SYegappan Lakshmanan return FALSE;
4424d1a8d658SYegappan Lakshmanan
4425d1a8d658SYegappan Lakshmanan if (!hldict_attr_to_str(dict, (char_u *)"gui", gui_attr,
4426d1a8d658SYegappan Lakshmanan sizeof(gui_attr)))
4427d1a8d658SYegappan Lakshmanan return FALSE;
4428d1a8d658SYegappan Lakshmanan
4429d1a8d658SYegappan Lakshmanan guifg = hldict_get_string(dict, (char_u *)"guifg", &error);
4430d1a8d658SYegappan Lakshmanan if (error)
4431d1a8d658SYegappan Lakshmanan return FALSE;
4432d1a8d658SYegappan Lakshmanan
4433d1a8d658SYegappan Lakshmanan guibg = hldict_get_string(dict, (char_u *)"guibg", &error);
4434d1a8d658SYegappan Lakshmanan if (error)
4435d1a8d658SYegappan Lakshmanan return FALSE;
4436d1a8d658SYegappan Lakshmanan
4437d1a8d658SYegappan Lakshmanan guisp = hldict_get_string(dict, (char_u *)"guisp", &error);
4438d1a8d658SYegappan Lakshmanan if (error)
4439d1a8d658SYegappan Lakshmanan return FALSE;
4440d1a8d658SYegappan Lakshmanan
4441d1a8d658SYegappan Lakshmanan # ifdef FEAT_GUI
4442d1a8d658SYegappan Lakshmanan font = hldict_get_string(dict, (char_u *)"font", &error);
4443d1a8d658SYegappan Lakshmanan if (error)
4444d1a8d658SYegappan Lakshmanan return FALSE;
4445d1a8d658SYegappan Lakshmanan # endif
4446d1a8d658SYegappan Lakshmanan
4447d1a8d658SYegappan Lakshmanan // If none of the attributes are specified, then do nothing.
4448d1a8d658SYegappan Lakshmanan if (term_attr[0] == NUL && start == NULL && stop == NULL
4449d1a8d658SYegappan Lakshmanan && cterm_attr[0] == NUL && ctermfg == NULL && ctermbg == NULL
4450d1a8d658SYegappan Lakshmanan && ctermul == NULL && gui_attr[0] == NUL
4451d1a8d658SYegappan Lakshmanan # ifdef FEAT_GUI
4452d1a8d658SYegappan Lakshmanan && font == NULL
4453d1a8d658SYegappan Lakshmanan # endif
4454d1a8d658SYegappan Lakshmanan && guifg == NULL && guibg == NULL && guisp == NULL
4455d1a8d658SYegappan Lakshmanan )
4456d1a8d658SYegappan Lakshmanan return TRUE;
4457d1a8d658SYegappan Lakshmanan
4458d1a8d658SYegappan Lakshmanan vim_snprintf((char *)IObuff, IOSIZE,
44592a16dc66SYegappan Lakshmanan "%s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s %s%s",
44602a16dc66SYegappan Lakshmanan dodefault ? "default " : "",
4461d1a8d658SYegappan Lakshmanan name,
4462d1a8d658SYegappan Lakshmanan term_attr[0] != NUL ? "term=" : "",
4463d1a8d658SYegappan Lakshmanan term_attr[0] != NUL ? term_attr : (char_u *)"",
4464d1a8d658SYegappan Lakshmanan start != NULL ? "start=" : "",
4465d1a8d658SYegappan Lakshmanan start != NULL ? start : (char_u *)"",
4466d1a8d658SYegappan Lakshmanan stop != NULL ? "stop=" : "",
4467d1a8d658SYegappan Lakshmanan stop != NULL ? stop : (char_u *)"",
4468d1a8d658SYegappan Lakshmanan cterm_attr[0] != NUL ? "cterm=" : "",
4469d1a8d658SYegappan Lakshmanan cterm_attr[0] != NUL ? cterm_attr : (char_u *)"",
4470d1a8d658SYegappan Lakshmanan ctermfg != NULL ? "ctermfg=" : "",
4471d1a8d658SYegappan Lakshmanan ctermfg != NULL ? ctermfg : (char_u *)"",
4472d1a8d658SYegappan Lakshmanan ctermbg != NULL ? "ctermbg=" : "",
4473d1a8d658SYegappan Lakshmanan ctermbg != NULL ? ctermbg : (char_u *)"",
4474d1a8d658SYegappan Lakshmanan ctermul != NULL ? "ctermul=" : "",
4475d1a8d658SYegappan Lakshmanan ctermul != NULL ? ctermul : (char_u *)"",
4476d1a8d658SYegappan Lakshmanan gui_attr[0] != NUL ? "gui=" : "",
4477d1a8d658SYegappan Lakshmanan gui_attr[0] != NUL ? gui_attr : (char_u *)"",
4478d1a8d658SYegappan Lakshmanan # ifdef FEAT_GUI
4479d1a8d658SYegappan Lakshmanan font != NULL ? "font=" : "",
4480d1a8d658SYegappan Lakshmanan font != NULL ? font : (char_u *)"",
4481d1a8d658SYegappan Lakshmanan # else
4482d1a8d658SYegappan Lakshmanan "", "",
4483d1a8d658SYegappan Lakshmanan # endif
4484d1a8d658SYegappan Lakshmanan guifg != NULL ? "guifg=" : "",
4485d1a8d658SYegappan Lakshmanan guifg != NULL ? guifg : (char_u *)"",
4486d1a8d658SYegappan Lakshmanan guibg != NULL ? "guibg=" : "",
4487d1a8d658SYegappan Lakshmanan guibg != NULL ? guibg : (char_u *)"",
4488d1a8d658SYegappan Lakshmanan guisp != NULL ? "guisp=" : "",
4489d1a8d658SYegappan Lakshmanan guisp != NULL ? guisp : (char_u *)""
4490d1a8d658SYegappan Lakshmanan );
4491d1a8d658SYegappan Lakshmanan
44922a16dc66SYegappan Lakshmanan do_highlight(IObuff, forceit, FALSE);
4493d1a8d658SYegappan Lakshmanan
4494d1a8d658SYegappan Lakshmanan return TRUE;
4495d1a8d658SYegappan Lakshmanan }
4496d1a8d658SYegappan Lakshmanan
4497d1a8d658SYegappan Lakshmanan /*
4498d1a8d658SYegappan Lakshmanan * "hlset([{highlight_attr}])" function
4499d1a8d658SYegappan Lakshmanan * Add or modify highlight groups
4500d1a8d658SYegappan Lakshmanan */
4501d1a8d658SYegappan Lakshmanan void
f_hlset(typval_T * argvars,typval_T * rettv)4502d1a8d658SYegappan Lakshmanan f_hlset(typval_T *argvars, typval_T *rettv)
4503d1a8d658SYegappan Lakshmanan {
4504d1a8d658SYegappan Lakshmanan listitem_T *li;
4505d1a8d658SYegappan Lakshmanan dict_T *dict;
4506d1a8d658SYegappan Lakshmanan
4507d1a8d658SYegappan Lakshmanan rettv->vval.v_number = -1;
4508d1a8d658SYegappan Lakshmanan
4509d1a8d658SYegappan Lakshmanan if (check_for_list_arg(argvars, 0) == FAIL)
4510d1a8d658SYegappan Lakshmanan return;
4511d1a8d658SYegappan Lakshmanan
4512d1a8d658SYegappan Lakshmanan FOR_ALL_LIST_ITEMS(argvars->vval.v_list, li)
4513d1a8d658SYegappan Lakshmanan {
4514d1a8d658SYegappan Lakshmanan if (li->li_tv.v_type != VAR_DICT)
4515d1a8d658SYegappan Lakshmanan {
4516d1a8d658SYegappan Lakshmanan emsg(_(e_dictreq));
4517d1a8d658SYegappan Lakshmanan return;
4518d1a8d658SYegappan Lakshmanan }
4519d1a8d658SYegappan Lakshmanan
4520d1a8d658SYegappan Lakshmanan dict = li->li_tv.vval.v_dict;
4521d1a8d658SYegappan Lakshmanan if (!hlg_add_or_update(dict))
4522d1a8d658SYegappan Lakshmanan return;
4523d1a8d658SYegappan Lakshmanan }
4524d1a8d658SYegappan Lakshmanan
4525d1a8d658SYegappan Lakshmanan rettv->vval.v_number = 0;
4526d1a8d658SYegappan Lakshmanan }
4527d1a8d658SYegappan Lakshmanan #endif
4528