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. 1229b7d7a9SBram Moolenaar * Includes highlighting matches. 13f9cc9f20SBram Moolenaar */ 14f9cc9f20SBram Moolenaar 15f9cc9f20SBram Moolenaar #include "vim.h" 16f9cc9f20SBram Moolenaar 17f9cc9f20SBram Moolenaar #define SG_TERM 1 // term has been set 18f9cc9f20SBram Moolenaar #define SG_CTERM 2 // cterm has been set 19f9cc9f20SBram Moolenaar #define SG_GUI 4 // gui has been set 20f9cc9f20SBram Moolenaar #define SG_LINK 8 // link has been set 21f9cc9f20SBram Moolenaar 22f9cc9f20SBram Moolenaar /* 23f9cc9f20SBram Moolenaar * The "term", "cterm" and "gui" arguments can be any combination of the 24f9cc9f20SBram Moolenaar * following names, separated by commas (but no spaces!). 25f9cc9f20SBram Moolenaar */ 26f9cc9f20SBram Moolenaar static char *(hl_name_table[]) = 27f9cc9f20SBram Moolenaar {"bold", "standout", "underline", "undercurl", 28f9cc9f20SBram Moolenaar "italic", "reverse", "inverse", "nocombine", "strikethrough", "NONE"}; 29f9cc9f20SBram Moolenaar static int hl_attr_table[] = 30f9cc9f20SBram Moolenaar {HL_BOLD, HL_STANDOUT, HL_UNDERLINE, HL_UNDERCURL, HL_ITALIC, HL_INVERSE, HL_INVERSE, HL_NOCOMBINE, HL_STRIKETHROUGH, 0}; 31f9cc9f20SBram Moolenaar #define ATTR_COMBINE(attr_a, attr_b) ((((attr_b) & HL_NOCOMBINE) ? attr_b : (attr_a)) | (attr_b)) 32f9cc9f20SBram Moolenaar 332ac6e82aSBram Moolenaar /* 342ac6e82aSBram Moolenaar * Structure that stores information about a highlight group. 352ac6e82aSBram Moolenaar * The ID of a highlight group is also called group ID. It is the index in 362ac6e82aSBram Moolenaar * the highlight_ga array PLUS ONE. 372ac6e82aSBram Moolenaar */ 382ac6e82aSBram Moolenaar typedef struct 392ac6e82aSBram Moolenaar { 402ac6e82aSBram Moolenaar char_u *sg_name; // highlight group name 412ac6e82aSBram Moolenaar char_u *sg_name_u; // uppercase of sg_name 422ac6e82aSBram Moolenaar int sg_cleared; // "hi clear" was used 432ac6e82aSBram Moolenaar // for normal terminals 442ac6e82aSBram Moolenaar int sg_term; // "term=" highlighting attributes 452ac6e82aSBram Moolenaar char_u *sg_start; // terminal string for start highl 462ac6e82aSBram Moolenaar char_u *sg_stop; // terminal string for stop highl 472ac6e82aSBram Moolenaar int sg_term_attr; // Screen attr for term mode 482ac6e82aSBram Moolenaar // for color terminals 492ac6e82aSBram Moolenaar int sg_cterm; // "cterm=" highlighting attr 502ac6e82aSBram Moolenaar int sg_cterm_bold; // bold attr was set for light color 512ac6e82aSBram Moolenaar int sg_cterm_fg; // terminal fg color number + 1 522ac6e82aSBram Moolenaar int sg_cterm_bg; // terminal bg 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 582ac6e82aSBram Moolenaar #endif 592ac6e82aSBram Moolenaar #ifdef FEAT_GUI 602ac6e82aSBram Moolenaar guicolor_T sg_gui_sp; // GUI special color handle 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 762ac6e82aSBram Moolenaar int sg_set; // combination of SG_* flags 772ac6e82aSBram Moolenaar #ifdef FEAT_EVAL 782ac6e82aSBram Moolenaar sctx_T sg_script_ctx; // script in which the group was last set 792ac6e82aSBram Moolenaar #endif 802ac6e82aSBram Moolenaar } hl_group_T; 812ac6e82aSBram Moolenaar 822ac6e82aSBram Moolenaar // highlight groups for 'highlight' option 832ac6e82aSBram Moolenaar static garray_T highlight_ga; 842ac6e82aSBram Moolenaar #define HL_TABLE() ((hl_group_T *)((highlight_ga.ga_data))) 852ac6e82aSBram Moolenaar 862ac6e82aSBram Moolenaar /* 872ac6e82aSBram Moolenaar * An attribute number is the index in attr_table plus ATTR_OFF. 882ac6e82aSBram Moolenaar */ 892ac6e82aSBram Moolenaar #define ATTR_OFF (HL_ALL + 1) 902ac6e82aSBram Moolenaar 91f9cc9f20SBram Moolenaar static void syn_unadd_group(void); 92f9cc9f20SBram Moolenaar static void set_hl_attr(int idx); 93f9cc9f20SBram Moolenaar static void highlight_list_one(int id); 94f9cc9f20SBram Moolenaar static int highlight_list_arg(int id, int didh, int type, int iarg, char_u *sarg, char *name); 95f9cc9f20SBram Moolenaar static int syn_add_group(char_u *name); 96f9cc9f20SBram Moolenaar static int hl_has_settings(int idx, int check_link); 97f9cc9f20SBram Moolenaar static void highlight_clear(int idx); 98f9cc9f20SBram Moolenaar 99f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 100f9cc9f20SBram Moolenaar static void gui_do_one_color(int idx, int do_menu, int do_tooltip); 101f9cc9f20SBram Moolenaar #endif 102f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 103f9cc9f20SBram Moolenaar static int set_group_colors(char_u *name, guicolor_T *fgp, guicolor_T *bgp, int do_menu, int use_norm, int do_tooltip); 104f9cc9f20SBram Moolenaar static void hl_do_font(int idx, char_u *arg, int do_normal, int do_menu, int do_tooltip, int free_font); 105f9cc9f20SBram Moolenaar #endif 106f9cc9f20SBram Moolenaar 107f9cc9f20SBram Moolenaar /* 108f9cc9f20SBram Moolenaar * The default highlight groups. These are compiled-in for fast startup and 109f9cc9f20SBram Moolenaar * they still work when the runtime files can't be found. 110f9cc9f20SBram Moolenaar * When making changes here, also change runtime/colors/default.vim! 111f9cc9f20SBram Moolenaar * The #ifdefs are needed to reduce the amount of static data. Helps to make 112f9cc9f20SBram Moolenaar * the 16 bit DOS (museum) version compile. 113f9cc9f20SBram Moolenaar */ 114f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 115f9cc9f20SBram Moolenaar # define CENT(a, b) b 116f9cc9f20SBram Moolenaar #else 117f9cc9f20SBram Moolenaar # define CENT(a, b) a 118f9cc9f20SBram Moolenaar #endif 119f9cc9f20SBram Moolenaar static char *(highlight_init_both[]) = { 120f9cc9f20SBram Moolenaar CENT("ErrorMsg term=standout ctermbg=DarkRed ctermfg=White", 121f9cc9f20SBram Moolenaar "ErrorMsg term=standout ctermbg=DarkRed ctermfg=White guibg=Red guifg=White"), 122f9cc9f20SBram Moolenaar CENT("IncSearch term=reverse cterm=reverse", 123f9cc9f20SBram Moolenaar "IncSearch term=reverse cterm=reverse gui=reverse"), 124f9cc9f20SBram Moolenaar CENT("ModeMsg term=bold cterm=bold", 125f9cc9f20SBram Moolenaar "ModeMsg term=bold cterm=bold gui=bold"), 126f9cc9f20SBram Moolenaar CENT("NonText term=bold ctermfg=Blue", 127f9cc9f20SBram Moolenaar "NonText term=bold ctermfg=Blue gui=bold guifg=Blue"), 128f9cc9f20SBram Moolenaar CENT("StatusLine term=reverse,bold cterm=reverse,bold", 129f9cc9f20SBram Moolenaar "StatusLine term=reverse,bold cterm=reverse,bold gui=reverse,bold"), 130f9cc9f20SBram Moolenaar CENT("StatusLineNC term=reverse cterm=reverse", 131f9cc9f20SBram Moolenaar "StatusLineNC term=reverse cterm=reverse gui=reverse"), 132f9cc9f20SBram Moolenaar "default link EndOfBuffer NonText", 133f9cc9f20SBram Moolenaar CENT("VertSplit term=reverse cterm=reverse", 134f9cc9f20SBram Moolenaar "VertSplit term=reverse cterm=reverse gui=reverse"), 135f9cc9f20SBram Moolenaar #ifdef FEAT_CLIPBOARD 136f9cc9f20SBram Moolenaar CENT("VisualNOS term=underline,bold cterm=underline,bold", 137f9cc9f20SBram Moolenaar "VisualNOS term=underline,bold cterm=underline,bold gui=underline,bold"), 138f9cc9f20SBram Moolenaar #endif 139f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF 140f9cc9f20SBram Moolenaar CENT("DiffText term=reverse cterm=bold ctermbg=Red", 141f9cc9f20SBram Moolenaar "DiffText term=reverse cterm=bold ctermbg=Red gui=bold guibg=Red"), 142f9cc9f20SBram Moolenaar #endif 143f9cc9f20SBram Moolenaar CENT("PmenuSbar ctermbg=Grey", 144f9cc9f20SBram Moolenaar "PmenuSbar ctermbg=Grey guibg=Grey"), 145f9cc9f20SBram Moolenaar CENT("TabLineSel term=bold cterm=bold", 146f9cc9f20SBram Moolenaar "TabLineSel term=bold cterm=bold gui=bold"), 147f9cc9f20SBram Moolenaar CENT("TabLineFill term=reverse cterm=reverse", 148f9cc9f20SBram Moolenaar "TabLineFill term=reverse cterm=reverse gui=reverse"), 149f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 150f9cc9f20SBram Moolenaar "Cursor guibg=fg guifg=bg", 151f9cc9f20SBram Moolenaar "lCursor guibg=fg guifg=bg", // should be different, but what? 152f9cc9f20SBram Moolenaar #endif 153f9cc9f20SBram Moolenaar "default link QuickFixLine Search", 154f9cc9f20SBram Moolenaar CENT("Normal cterm=NONE", "Normal gui=NONE"), 155f9cc9f20SBram Moolenaar NULL 156f9cc9f20SBram Moolenaar }; 157f9cc9f20SBram Moolenaar 1581f164b19SBram Moolenaar // Default colors only used with a light background. 159f9cc9f20SBram Moolenaar static char *(highlight_init_light[]) = { 160f9cc9f20SBram Moolenaar CENT("Directory term=bold ctermfg=DarkBlue", 161f9cc9f20SBram Moolenaar "Directory term=bold ctermfg=DarkBlue guifg=Blue"), 162f9cc9f20SBram Moolenaar CENT("LineNr term=underline ctermfg=Brown", 163f9cc9f20SBram Moolenaar "LineNr term=underline ctermfg=Brown guifg=Brown"), 164017ba07fSBram Moolenaar CENT("CursorLineNr term=bold cterm=underline ctermfg=Brown", 165017ba07fSBram Moolenaar "CursorLineNr term=bold cterm=underline ctermfg=Brown gui=bold guifg=Brown"), 166f9cc9f20SBram Moolenaar CENT("MoreMsg term=bold ctermfg=DarkGreen", 167f9cc9f20SBram Moolenaar "MoreMsg term=bold ctermfg=DarkGreen gui=bold guifg=SeaGreen"), 168f9cc9f20SBram Moolenaar CENT("Question term=standout ctermfg=DarkGreen", 169f9cc9f20SBram Moolenaar "Question term=standout ctermfg=DarkGreen gui=bold guifg=SeaGreen"), 170f9cc9f20SBram Moolenaar CENT("Search term=reverse ctermbg=Yellow ctermfg=NONE", 171f9cc9f20SBram Moolenaar "Search term=reverse ctermbg=Yellow ctermfg=NONE guibg=Yellow guifg=NONE"), 172f9cc9f20SBram Moolenaar #ifdef FEAT_SPELL 173f9cc9f20SBram Moolenaar CENT("SpellBad term=reverse ctermbg=LightRed", 174f9cc9f20SBram Moolenaar "SpellBad term=reverse ctermbg=LightRed guisp=Red gui=undercurl"), 175f9cc9f20SBram Moolenaar CENT("SpellCap term=reverse ctermbg=LightBlue", 176f9cc9f20SBram Moolenaar "SpellCap term=reverse ctermbg=LightBlue guisp=Blue gui=undercurl"), 177f9cc9f20SBram Moolenaar CENT("SpellRare term=reverse ctermbg=LightMagenta", 178f9cc9f20SBram Moolenaar "SpellRare term=reverse ctermbg=LightMagenta guisp=Magenta gui=undercurl"), 179f9cc9f20SBram Moolenaar CENT("SpellLocal term=underline ctermbg=Cyan", 180f9cc9f20SBram Moolenaar "SpellLocal term=underline ctermbg=Cyan guisp=DarkCyan gui=undercurl"), 181f9cc9f20SBram Moolenaar #endif 182f9cc9f20SBram Moolenaar CENT("PmenuThumb ctermbg=Black", 183f9cc9f20SBram Moolenaar "PmenuThumb ctermbg=Black guibg=Black"), 184f9cc9f20SBram Moolenaar CENT("Pmenu ctermbg=LightMagenta ctermfg=Black", 185f9cc9f20SBram Moolenaar "Pmenu ctermbg=LightMagenta ctermfg=Black guibg=LightMagenta"), 186f9cc9f20SBram Moolenaar CENT("PmenuSel ctermbg=LightGrey ctermfg=Black", 187f9cc9f20SBram Moolenaar "PmenuSel ctermbg=LightGrey ctermfg=Black guibg=Grey"), 188f9cc9f20SBram Moolenaar CENT("SpecialKey term=bold ctermfg=DarkBlue", 189f9cc9f20SBram Moolenaar "SpecialKey term=bold ctermfg=DarkBlue guifg=Blue"), 190f9cc9f20SBram Moolenaar CENT("Title term=bold ctermfg=DarkMagenta", 191f9cc9f20SBram Moolenaar "Title term=bold ctermfg=DarkMagenta gui=bold guifg=Magenta"), 192f9cc9f20SBram Moolenaar CENT("WarningMsg term=standout ctermfg=DarkRed", 193f9cc9f20SBram Moolenaar "WarningMsg term=standout ctermfg=DarkRed guifg=Red"), 194f9cc9f20SBram Moolenaar #ifdef FEAT_WILDMENU 195f9cc9f20SBram Moolenaar CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black", 196f9cc9f20SBram Moolenaar "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), 197f9cc9f20SBram Moolenaar #endif 198f9cc9f20SBram Moolenaar #ifdef FEAT_FOLDING 199f9cc9f20SBram Moolenaar CENT("Folded term=standout ctermbg=Grey ctermfg=DarkBlue", 200f9cc9f20SBram Moolenaar "Folded term=standout ctermbg=Grey ctermfg=DarkBlue guibg=LightGrey guifg=DarkBlue"), 201f9cc9f20SBram Moolenaar CENT("FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue", 202f9cc9f20SBram Moolenaar "FoldColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"), 203f9cc9f20SBram Moolenaar #endif 204f9cc9f20SBram Moolenaar #ifdef FEAT_SIGNS 205f9cc9f20SBram Moolenaar CENT("SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue", 206f9cc9f20SBram Moolenaar "SignColumn term=standout ctermbg=Grey ctermfg=DarkBlue guibg=Grey guifg=DarkBlue"), 207f9cc9f20SBram Moolenaar #endif 208f9cc9f20SBram Moolenaar CENT("Visual term=reverse", 209f9cc9f20SBram Moolenaar "Visual term=reverse guibg=LightGrey"), 210f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF 211f9cc9f20SBram Moolenaar CENT("DiffAdd term=bold ctermbg=LightBlue", 212f9cc9f20SBram Moolenaar "DiffAdd term=bold ctermbg=LightBlue guibg=LightBlue"), 213f9cc9f20SBram Moolenaar CENT("DiffChange term=bold ctermbg=LightMagenta", 214f9cc9f20SBram Moolenaar "DiffChange term=bold ctermbg=LightMagenta guibg=LightMagenta"), 215f9cc9f20SBram Moolenaar CENT("DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan", 216f9cc9f20SBram Moolenaar "DiffDelete term=bold ctermfg=Blue ctermbg=LightCyan gui=bold guifg=Blue guibg=LightCyan"), 217f9cc9f20SBram Moolenaar #endif 218f9cc9f20SBram Moolenaar CENT("TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey", 219f9cc9f20SBram Moolenaar "TabLine term=underline cterm=underline ctermfg=black ctermbg=LightGrey gui=underline guibg=LightGrey"), 220f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL 221f9cc9f20SBram Moolenaar CENT("CursorColumn term=reverse ctermbg=LightGrey", 222f9cc9f20SBram Moolenaar "CursorColumn term=reverse ctermbg=LightGrey guibg=Grey90"), 223f9cc9f20SBram Moolenaar CENT("CursorLine term=underline cterm=underline", 224f9cc9f20SBram Moolenaar "CursorLine term=underline cterm=underline guibg=Grey90"), 225f9cc9f20SBram Moolenaar CENT("ColorColumn term=reverse ctermbg=LightRed", 226f9cc9f20SBram Moolenaar "ColorColumn term=reverse ctermbg=LightRed guibg=LightRed"), 227f9cc9f20SBram Moolenaar #endif 228f9cc9f20SBram Moolenaar #ifdef FEAT_CONCEAL 229f9cc9f20SBram Moolenaar CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey", 230f9cc9f20SBram Moolenaar "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"), 231f9cc9f20SBram Moolenaar #endif 232f9cc9f20SBram Moolenaar CENT("MatchParen term=reverse ctermbg=Cyan", 233f9cc9f20SBram Moolenaar "MatchParen term=reverse ctermbg=Cyan guibg=Cyan"), 234f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 235f9cc9f20SBram Moolenaar CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen", 236f9cc9f20SBram Moolenaar "StatusLineTerm term=reverse,bold cterm=bold ctermfg=White ctermbg=DarkGreen gui=bold guifg=bg guibg=DarkGreen"), 237f9cc9f20SBram Moolenaar CENT("StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen", 238f9cc9f20SBram Moolenaar "StatusLineTermNC term=reverse ctermfg=White ctermbg=DarkGreen guifg=bg guibg=DarkGreen"), 239f9cc9f20SBram Moolenaar #endif 240f9cc9f20SBram Moolenaar #ifdef FEAT_MENU 241f9cc9f20SBram Moolenaar CENT("ToolbarLine term=underline ctermbg=LightGrey", 242f9cc9f20SBram Moolenaar "ToolbarLine term=underline ctermbg=LightGrey guibg=LightGrey"), 243f9cc9f20SBram Moolenaar CENT("ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey", 244f9cc9f20SBram Moolenaar "ToolbarButton cterm=bold ctermfg=White ctermbg=DarkGrey gui=bold guifg=White guibg=Grey40"), 245f9cc9f20SBram Moolenaar #endif 246f9cc9f20SBram Moolenaar NULL 247f9cc9f20SBram Moolenaar }; 248f9cc9f20SBram Moolenaar 2491f164b19SBram Moolenaar // Default colors only used with a dark background. 250f9cc9f20SBram Moolenaar static char *(highlight_init_dark[]) = { 251f9cc9f20SBram Moolenaar CENT("Directory term=bold ctermfg=LightCyan", 252f9cc9f20SBram Moolenaar "Directory term=bold ctermfg=LightCyan guifg=Cyan"), 253f9cc9f20SBram Moolenaar CENT("LineNr term=underline ctermfg=Yellow", 254f9cc9f20SBram Moolenaar "LineNr term=underline ctermfg=Yellow guifg=Yellow"), 255017ba07fSBram Moolenaar CENT("CursorLineNr term=bold cterm=underline ctermfg=Yellow", 256017ba07fSBram Moolenaar "CursorLineNr term=bold cterm=underline ctermfg=Yellow gui=bold guifg=Yellow"), 257f9cc9f20SBram Moolenaar CENT("MoreMsg term=bold ctermfg=LightGreen", 258f9cc9f20SBram Moolenaar "MoreMsg term=bold ctermfg=LightGreen gui=bold guifg=SeaGreen"), 259f9cc9f20SBram Moolenaar CENT("Question term=standout ctermfg=LightGreen", 260f9cc9f20SBram Moolenaar "Question term=standout ctermfg=LightGreen gui=bold guifg=Green"), 261f9cc9f20SBram Moolenaar CENT("Search term=reverse ctermbg=Yellow ctermfg=Black", 262f9cc9f20SBram Moolenaar "Search term=reverse ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), 263f9cc9f20SBram Moolenaar CENT("SpecialKey term=bold ctermfg=LightBlue", 264f9cc9f20SBram Moolenaar "SpecialKey term=bold ctermfg=LightBlue guifg=Cyan"), 265f9cc9f20SBram Moolenaar #ifdef FEAT_SPELL 266f9cc9f20SBram Moolenaar CENT("SpellBad term=reverse ctermbg=Red", 267f9cc9f20SBram Moolenaar "SpellBad term=reverse ctermbg=Red guisp=Red gui=undercurl"), 268f9cc9f20SBram Moolenaar CENT("SpellCap term=reverse ctermbg=Blue", 269f9cc9f20SBram Moolenaar "SpellCap term=reverse ctermbg=Blue guisp=Blue gui=undercurl"), 270f9cc9f20SBram Moolenaar CENT("SpellRare term=reverse ctermbg=Magenta", 271f9cc9f20SBram Moolenaar "SpellRare term=reverse ctermbg=Magenta guisp=Magenta gui=undercurl"), 272f9cc9f20SBram Moolenaar CENT("SpellLocal term=underline ctermbg=Cyan", 273f9cc9f20SBram Moolenaar "SpellLocal term=underline ctermbg=Cyan guisp=Cyan gui=undercurl"), 274f9cc9f20SBram Moolenaar #endif 275f9cc9f20SBram Moolenaar CENT("PmenuThumb ctermbg=White", 276f9cc9f20SBram Moolenaar "PmenuThumb ctermbg=White guibg=White"), 277f9cc9f20SBram Moolenaar CENT("Pmenu ctermbg=Magenta ctermfg=Black", 278f9cc9f20SBram Moolenaar "Pmenu ctermbg=Magenta ctermfg=Black guibg=Magenta"), 279f9cc9f20SBram Moolenaar CENT("PmenuSel ctermbg=Black ctermfg=DarkGrey", 280f9cc9f20SBram Moolenaar "PmenuSel ctermbg=Black ctermfg=DarkGrey guibg=DarkGrey"), 281f9cc9f20SBram Moolenaar CENT("Title term=bold ctermfg=LightMagenta", 282f9cc9f20SBram Moolenaar "Title term=bold ctermfg=LightMagenta gui=bold guifg=Magenta"), 283f9cc9f20SBram Moolenaar CENT("WarningMsg term=standout ctermfg=LightRed", 284f9cc9f20SBram Moolenaar "WarningMsg term=standout ctermfg=LightRed guifg=Red"), 285f9cc9f20SBram Moolenaar #ifdef FEAT_WILDMENU 286f9cc9f20SBram Moolenaar CENT("WildMenu term=standout ctermbg=Yellow ctermfg=Black", 287f9cc9f20SBram Moolenaar "WildMenu term=standout ctermbg=Yellow ctermfg=Black guibg=Yellow guifg=Black"), 288f9cc9f20SBram Moolenaar #endif 289f9cc9f20SBram Moolenaar #ifdef FEAT_FOLDING 290f9cc9f20SBram Moolenaar CENT("Folded term=standout ctermbg=DarkGrey ctermfg=Cyan", 291f9cc9f20SBram Moolenaar "Folded term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=DarkGrey guifg=Cyan"), 292f9cc9f20SBram Moolenaar CENT("FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan", 293f9cc9f20SBram Moolenaar "FoldColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"), 294f9cc9f20SBram Moolenaar #endif 295f9cc9f20SBram Moolenaar #ifdef FEAT_SIGNS 296f9cc9f20SBram Moolenaar CENT("SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan", 297f9cc9f20SBram Moolenaar "SignColumn term=standout ctermbg=DarkGrey ctermfg=Cyan guibg=Grey guifg=Cyan"), 298f9cc9f20SBram Moolenaar #endif 299f9cc9f20SBram Moolenaar CENT("Visual term=reverse", 300f9cc9f20SBram Moolenaar "Visual term=reverse guibg=DarkGrey"), 301f9cc9f20SBram Moolenaar #ifdef FEAT_DIFF 302f9cc9f20SBram Moolenaar CENT("DiffAdd term=bold ctermbg=DarkBlue", 303f9cc9f20SBram Moolenaar "DiffAdd term=bold ctermbg=DarkBlue guibg=DarkBlue"), 304f9cc9f20SBram Moolenaar CENT("DiffChange term=bold ctermbg=DarkMagenta", 305f9cc9f20SBram Moolenaar "DiffChange term=bold ctermbg=DarkMagenta guibg=DarkMagenta"), 306f9cc9f20SBram Moolenaar CENT("DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan", 307f9cc9f20SBram Moolenaar "DiffDelete term=bold ctermfg=Blue ctermbg=DarkCyan gui=bold guifg=Blue guibg=DarkCyan"), 308f9cc9f20SBram Moolenaar #endif 309f9cc9f20SBram Moolenaar CENT("TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey", 310f9cc9f20SBram Moolenaar "TabLine term=underline cterm=underline ctermfg=white ctermbg=DarkGrey gui=underline guibg=DarkGrey"), 311f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL 312f9cc9f20SBram Moolenaar CENT("CursorColumn term=reverse ctermbg=DarkGrey", 313f9cc9f20SBram Moolenaar "CursorColumn term=reverse ctermbg=DarkGrey guibg=Grey40"), 314f9cc9f20SBram Moolenaar CENT("CursorLine term=underline cterm=underline", 315f9cc9f20SBram Moolenaar "CursorLine term=underline cterm=underline guibg=Grey40"), 316f9cc9f20SBram Moolenaar CENT("ColorColumn term=reverse ctermbg=DarkRed", 317f9cc9f20SBram Moolenaar "ColorColumn term=reverse ctermbg=DarkRed guibg=DarkRed"), 318f9cc9f20SBram Moolenaar #endif 319f9cc9f20SBram Moolenaar CENT("MatchParen term=reverse ctermbg=DarkCyan", 320f9cc9f20SBram Moolenaar "MatchParen term=reverse ctermbg=DarkCyan guibg=DarkCyan"), 321f9cc9f20SBram Moolenaar #ifdef FEAT_CONCEAL 322f9cc9f20SBram Moolenaar CENT("Conceal ctermbg=DarkGrey ctermfg=LightGrey", 323f9cc9f20SBram Moolenaar "Conceal ctermbg=DarkGrey ctermfg=LightGrey guibg=DarkGrey guifg=LightGrey"), 324f9cc9f20SBram Moolenaar #endif 325f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 326f9cc9f20SBram Moolenaar CENT("StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen", 327f9cc9f20SBram Moolenaar "StatusLineTerm term=reverse,bold cterm=bold ctermfg=Black ctermbg=LightGreen gui=bold guifg=bg guibg=LightGreen"), 328f9cc9f20SBram Moolenaar CENT("StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen", 329f9cc9f20SBram Moolenaar "StatusLineTermNC term=reverse ctermfg=Black ctermbg=LightGreen guifg=bg guibg=LightGreen"), 330f9cc9f20SBram Moolenaar #endif 331f9cc9f20SBram Moolenaar #ifdef FEAT_MENU 332f9cc9f20SBram Moolenaar CENT("ToolbarLine term=underline ctermbg=DarkGrey", 333f9cc9f20SBram Moolenaar "ToolbarLine term=underline ctermbg=DarkGrey guibg=Grey50"), 334f9cc9f20SBram Moolenaar CENT("ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey", 335f9cc9f20SBram Moolenaar "ToolbarButton cterm=bold ctermfg=Black ctermbg=LightGrey gui=bold guifg=Black guibg=LightGrey"), 336f9cc9f20SBram Moolenaar #endif 337f9cc9f20SBram Moolenaar NULL 338f9cc9f20SBram Moolenaar }; 339f9cc9f20SBram Moolenaar 3402ac6e82aSBram Moolenaar /* 3412ac6e82aSBram Moolenaar * Returns the number of highlight groups. 3422ac6e82aSBram Moolenaar */ 3432ac6e82aSBram Moolenaar int 3442ac6e82aSBram Moolenaar highlight_num_groups(void) 3452ac6e82aSBram Moolenaar { 3462ac6e82aSBram Moolenaar return highlight_ga.ga_len; 3472ac6e82aSBram Moolenaar } 3482ac6e82aSBram Moolenaar 3492ac6e82aSBram Moolenaar /* 3502ac6e82aSBram Moolenaar * Returns the name of a highlight group. 3512ac6e82aSBram Moolenaar */ 3522ac6e82aSBram Moolenaar char_u * 3532ac6e82aSBram Moolenaar highlight_group_name(int id) 3542ac6e82aSBram Moolenaar { 3552ac6e82aSBram Moolenaar return HL_TABLE()[id].sg_name; 3562ac6e82aSBram Moolenaar } 3572ac6e82aSBram Moolenaar 3582ac6e82aSBram Moolenaar /* 3592ac6e82aSBram Moolenaar * Returns the ID of the link to a highlight group. 3602ac6e82aSBram Moolenaar */ 3612ac6e82aSBram Moolenaar int 3622ac6e82aSBram Moolenaar highlight_link_id(int id) 3632ac6e82aSBram Moolenaar { 3642ac6e82aSBram Moolenaar return HL_TABLE()[id].sg_link; 3652ac6e82aSBram Moolenaar } 3662ac6e82aSBram Moolenaar 367f9cc9f20SBram Moolenaar void 368f9cc9f20SBram Moolenaar init_highlight( 369f9cc9f20SBram Moolenaar int both, // include groups where 'bg' doesn't matter 370f9cc9f20SBram Moolenaar int reset) // clear group first 371f9cc9f20SBram Moolenaar { 372f9cc9f20SBram Moolenaar int i; 373f9cc9f20SBram Moolenaar char **pp; 374f9cc9f20SBram Moolenaar static int had_both = FALSE; 375f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 376f9cc9f20SBram Moolenaar char_u *p; 377f9cc9f20SBram Moolenaar 378f9cc9f20SBram Moolenaar /* 379f9cc9f20SBram Moolenaar * Try finding the color scheme file. Used when a color file was loaded 380f9cc9f20SBram Moolenaar * and 'background' or 't_Co' is changed. 381f9cc9f20SBram Moolenaar */ 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 401f9cc9f20SBram Moolenaar /* 402f9cc9f20SBram Moolenaar * Didn't use a color file, use the compiled-in colors. 403f9cc9f20SBram Moolenaar */ 404f9cc9f20SBram Moolenaar if (both) 405f9cc9f20SBram Moolenaar { 406f9cc9f20SBram Moolenaar had_both = TRUE; 407f9cc9f20SBram Moolenaar pp = highlight_init_both; 408f9cc9f20SBram Moolenaar for (i = 0; pp[i] != NULL; ++i) 409f9cc9f20SBram Moolenaar do_highlight((char_u *)pp[i], reset, TRUE); 410f9cc9f20SBram Moolenaar } 411f9cc9f20SBram Moolenaar else if (!had_both) 412f9cc9f20SBram Moolenaar // Don't do anything before the call with both == TRUE from main(). 413f9cc9f20SBram Moolenaar // Not everything has been setup then, and that call will overrule 414f9cc9f20SBram Moolenaar // everything anyway. 415f9cc9f20SBram Moolenaar return; 416f9cc9f20SBram Moolenaar 417f9cc9f20SBram Moolenaar if (*p_bg == 'l') 418f9cc9f20SBram Moolenaar pp = highlight_init_light; 419f9cc9f20SBram Moolenaar else 420f9cc9f20SBram Moolenaar pp = highlight_init_dark; 421f9cc9f20SBram Moolenaar for (i = 0; pp[i] != NULL; ++i) 422f9cc9f20SBram Moolenaar do_highlight((char_u *)pp[i], reset, TRUE); 423f9cc9f20SBram Moolenaar 424f9cc9f20SBram Moolenaar // Reverse looks ugly, but grey may not work for 8 colors. Thus let it 425f9cc9f20SBram Moolenaar // depend on the number of colors available. 426f9cc9f20SBram Moolenaar // With 8 colors brown is equal to yellow, need to use black for Search fg 427f9cc9f20SBram Moolenaar // to avoid Statement highlighted text disappears. 428f9cc9f20SBram Moolenaar // Clear the attributes, needed when changing the t_Co value. 429f9cc9f20SBram Moolenaar if (t_colors > 8) 430f9cc9f20SBram Moolenaar do_highlight((char_u *)(*p_bg == 'l' 431f9cc9f20SBram Moolenaar ? "Visual cterm=NONE ctermbg=LightGrey" 432f9cc9f20SBram Moolenaar : "Visual cterm=NONE ctermbg=DarkGrey"), FALSE, TRUE); 433f9cc9f20SBram Moolenaar else 434f9cc9f20SBram Moolenaar { 435f9cc9f20SBram Moolenaar do_highlight((char_u *)"Visual cterm=reverse ctermbg=NONE", 436f9cc9f20SBram Moolenaar FALSE, TRUE); 437f9cc9f20SBram Moolenaar if (*p_bg == 'l') 438f9cc9f20SBram Moolenaar do_highlight((char_u *)"Search ctermfg=black", FALSE, TRUE); 439f9cc9f20SBram Moolenaar } 440f9cc9f20SBram Moolenaar 441f9cc9f20SBram Moolenaar #ifdef FEAT_SYN_HL 442f9cc9f20SBram Moolenaar /* 443f9cc9f20SBram Moolenaar * If syntax highlighting is enabled load the highlighting for it. 444f9cc9f20SBram Moolenaar */ 445f9cc9f20SBram Moolenaar if (get_var_value((char_u *)"g:syntax_on") != NULL) 446f9cc9f20SBram Moolenaar { 447f9cc9f20SBram Moolenaar static int recursive = 0; 448f9cc9f20SBram Moolenaar 449f9cc9f20SBram Moolenaar if (recursive >= 5) 450f9cc9f20SBram Moolenaar emsg(_("E679: recursive loop loading syncolor.vim")); 451f9cc9f20SBram Moolenaar else 452f9cc9f20SBram Moolenaar { 453f9cc9f20SBram Moolenaar ++recursive; 454f9cc9f20SBram Moolenaar (void)source_runtime((char_u *)"syntax/syncolor.vim", DIP_ALL); 455f9cc9f20SBram Moolenaar --recursive; 456f9cc9f20SBram Moolenaar } 457f9cc9f20SBram Moolenaar } 458f9cc9f20SBram Moolenaar #endif 459f9cc9f20SBram Moolenaar } 460f9cc9f20SBram Moolenaar 461f9cc9f20SBram Moolenaar /* 462f9cc9f20SBram Moolenaar * Load color file "name". 463f9cc9f20SBram Moolenaar * Return OK for success, FAIL for failure. 464f9cc9f20SBram Moolenaar */ 465f9cc9f20SBram Moolenaar int 466f9cc9f20SBram Moolenaar load_colors(char_u *name) 467f9cc9f20SBram Moolenaar { 468f9cc9f20SBram Moolenaar char_u *buf; 469f9cc9f20SBram Moolenaar int retval = FAIL; 470f9cc9f20SBram Moolenaar static int recursive = FALSE; 471f9cc9f20SBram Moolenaar 472f9cc9f20SBram Moolenaar // When being called recursively, this is probably because setting 473f9cc9f20SBram Moolenaar // 'background' caused the highlighting to be reloaded. This means it is 474f9cc9f20SBram Moolenaar // working, thus we should return OK. 475f9cc9f20SBram Moolenaar if (recursive) 476f9cc9f20SBram Moolenaar return OK; 477f9cc9f20SBram Moolenaar 478f9cc9f20SBram Moolenaar recursive = TRUE; 479f9cc9f20SBram Moolenaar buf = alloc(STRLEN(name) + 12); 480f9cc9f20SBram Moolenaar if (buf != NULL) 481f9cc9f20SBram Moolenaar { 482f9cc9f20SBram Moolenaar apply_autocmds(EVENT_COLORSCHEMEPRE, name, 483f9cc9f20SBram Moolenaar curbuf->b_fname, FALSE, curbuf); 484f9cc9f20SBram Moolenaar sprintf((char *)buf, "colors/%s.vim", name); 485f9cc9f20SBram Moolenaar retval = source_runtime(buf, DIP_START + DIP_OPT); 486f9cc9f20SBram Moolenaar vim_free(buf); 487f9cc9f20SBram Moolenaar apply_autocmds(EVENT_COLORSCHEME, name, curbuf->b_fname, FALSE, curbuf); 488f9cc9f20SBram Moolenaar } 489f9cc9f20SBram Moolenaar recursive = FALSE; 490f9cc9f20SBram Moolenaar 491f9cc9f20SBram Moolenaar return retval; 492f9cc9f20SBram Moolenaar } 493f9cc9f20SBram Moolenaar 494f9cc9f20SBram Moolenaar static char *(color_names[28]) = { 495f9cc9f20SBram Moolenaar "Black", "DarkBlue", "DarkGreen", "DarkCyan", 496f9cc9f20SBram Moolenaar "DarkRed", "DarkMagenta", "Brown", "DarkYellow", 497f9cc9f20SBram Moolenaar "Gray", "Grey", "LightGray", "LightGrey", 498f9cc9f20SBram Moolenaar "DarkGray", "DarkGrey", 499f9cc9f20SBram Moolenaar "Blue", "LightBlue", "Green", "LightGreen", 500f9cc9f20SBram Moolenaar "Cyan", "LightCyan", "Red", "LightRed", "Magenta", 501f9cc9f20SBram Moolenaar "LightMagenta", "Yellow", "LightYellow", "White", "NONE"}; 502f9cc9f20SBram Moolenaar // indices: 503f9cc9f20SBram Moolenaar // 0, 1, 2, 3, 504f9cc9f20SBram Moolenaar // 4, 5, 6, 7, 505f9cc9f20SBram Moolenaar // 8, 9, 10, 11, 506f9cc9f20SBram Moolenaar // 12, 13, 507f9cc9f20SBram Moolenaar // 14, 15, 16, 17, 508f9cc9f20SBram Moolenaar // 18, 19, 20, 21, 22, 509f9cc9f20SBram Moolenaar // 23, 24, 25, 26, 27 510f9cc9f20SBram Moolenaar static int color_numbers_16[28] = {0, 1, 2, 3, 511f9cc9f20SBram Moolenaar 4, 5, 6, 6, 512f9cc9f20SBram Moolenaar 7, 7, 7, 7, 513f9cc9f20SBram Moolenaar 8, 8, 514f9cc9f20SBram Moolenaar 9, 9, 10, 10, 515f9cc9f20SBram Moolenaar 11, 11, 12, 12, 13, 516f9cc9f20SBram Moolenaar 13, 14, 14, 15, -1}; 517f9cc9f20SBram Moolenaar // for xterm with 88 colors... 518f9cc9f20SBram Moolenaar static int color_numbers_88[28] = {0, 4, 2, 6, 519f9cc9f20SBram Moolenaar 1, 5, 32, 72, 520f9cc9f20SBram Moolenaar 84, 84, 7, 7, 521f9cc9f20SBram Moolenaar 82, 82, 522f9cc9f20SBram Moolenaar 12, 43, 10, 61, 523f9cc9f20SBram Moolenaar 14, 63, 9, 74, 13, 524f9cc9f20SBram Moolenaar 75, 11, 78, 15, -1}; 525f9cc9f20SBram Moolenaar // for xterm with 256 colors... 526f9cc9f20SBram Moolenaar static int color_numbers_256[28] = {0, 4, 2, 6, 527e93c968fSBram Moolenaar 1, 5, 130, 3, 528f9cc9f20SBram Moolenaar 248, 248, 7, 7, 529f9cc9f20SBram Moolenaar 242, 242, 530f9cc9f20SBram Moolenaar 12, 81, 10, 121, 531f9cc9f20SBram Moolenaar 14, 159, 9, 224, 13, 532f9cc9f20SBram Moolenaar 225, 11, 229, 15, -1}; 533f9cc9f20SBram Moolenaar // for terminals with less than 16 colors... 534f9cc9f20SBram Moolenaar static int color_numbers_8[28] = {0, 4, 2, 6, 535f9cc9f20SBram Moolenaar 1, 5, 3, 3, 536f9cc9f20SBram Moolenaar 7, 7, 7, 7, 537f9cc9f20SBram Moolenaar 0+8, 0+8, 538f9cc9f20SBram Moolenaar 4+8, 4+8, 2+8, 2+8, 539f9cc9f20SBram Moolenaar 6+8, 6+8, 1+8, 1+8, 5+8, 540f9cc9f20SBram Moolenaar 5+8, 3+8, 3+8, 7+8, -1}; 541f9cc9f20SBram Moolenaar 542f9cc9f20SBram Moolenaar /* 543f9cc9f20SBram Moolenaar * Lookup the "cterm" value to be used for color with index "idx" in 544f9cc9f20SBram Moolenaar * color_names[]. 545f9cc9f20SBram Moolenaar * "boldp" will be set to TRUE or FALSE for a foreground color when using 8 546f9cc9f20SBram Moolenaar * colors, otherwise it will be unchanged. 547f9cc9f20SBram Moolenaar */ 548f9cc9f20SBram Moolenaar int 549f9cc9f20SBram Moolenaar lookup_color(int idx, int foreground, int *boldp) 550f9cc9f20SBram Moolenaar { 551f9cc9f20SBram Moolenaar int color = color_numbers_16[idx]; 552f9cc9f20SBram Moolenaar char_u *p; 553f9cc9f20SBram Moolenaar 554f9cc9f20SBram Moolenaar // Use the _16 table to check if it's a valid color name. 555f9cc9f20SBram Moolenaar if (color < 0) 556f9cc9f20SBram Moolenaar return -1; 557f9cc9f20SBram Moolenaar 558f9cc9f20SBram Moolenaar if (t_colors == 8) 559f9cc9f20SBram Moolenaar { 560f9cc9f20SBram Moolenaar // t_Co is 8: use the 8 colors table 561f9cc9f20SBram Moolenaar #if defined(__QNXNTO__) 562c95e8d64SBram Moolenaar // On qnx, the 8 & 16 color arrays are the same 563c95e8d64SBram Moolenaar if (STRNCMP(T_NAME, "qansi", 5) == 0) 564c95e8d64SBram Moolenaar color = color_numbers_16[idx]; 565c95e8d64SBram Moolenaar else 566f9cc9f20SBram Moolenaar #endif 567c95e8d64SBram Moolenaar color = color_numbers_8[idx]; 568f9cc9f20SBram Moolenaar if (foreground) 569f9cc9f20SBram Moolenaar { 570f9cc9f20SBram Moolenaar // set/reset bold attribute to get light foreground 571f9cc9f20SBram Moolenaar // colors (on some terminals, e.g. "linux") 572f9cc9f20SBram Moolenaar if (color & 8) 573f9cc9f20SBram Moolenaar *boldp = TRUE; 574f9cc9f20SBram Moolenaar else 575f9cc9f20SBram Moolenaar *boldp = FALSE; 576f9cc9f20SBram Moolenaar } 577f9cc9f20SBram Moolenaar color &= 7; // truncate to 8 colors 578f9cc9f20SBram Moolenaar } 579f9cc9f20SBram Moolenaar else if (t_colors == 16 || t_colors == 88 580f9cc9f20SBram Moolenaar || t_colors >= 256) 581f9cc9f20SBram Moolenaar { 582f9cc9f20SBram Moolenaar /* 583f9cc9f20SBram Moolenaar * Guess: if the termcap entry ends in 'm', it is 584f9cc9f20SBram Moolenaar * probably an xterm-like terminal. Use the changed 585f9cc9f20SBram Moolenaar * order for colors. 586f9cc9f20SBram Moolenaar */ 587f9cc9f20SBram Moolenaar if (*T_CAF != NUL) 588f9cc9f20SBram Moolenaar p = T_CAF; 589f9cc9f20SBram Moolenaar else 590f9cc9f20SBram Moolenaar p = T_CSF; 591f9cc9f20SBram Moolenaar if (*p != NUL && (t_colors > 256 592f9cc9f20SBram Moolenaar || *(p + STRLEN(p) - 1) == 'm')) 593f9cc9f20SBram Moolenaar { 594f9cc9f20SBram Moolenaar if (t_colors == 88) 595f9cc9f20SBram Moolenaar color = color_numbers_88[idx]; 596f9cc9f20SBram Moolenaar else if (t_colors >= 256) 597f9cc9f20SBram Moolenaar color = color_numbers_256[idx]; 598f9cc9f20SBram Moolenaar else 599f9cc9f20SBram Moolenaar color = color_numbers_8[idx]; 600f9cc9f20SBram Moolenaar } 601f9cc9f20SBram Moolenaar #ifdef FEAT_TERMRESPONSE 602f9cc9f20SBram Moolenaar if (t_colors >= 256 && color == 15 && is_mac_terminal) 603f9cc9f20SBram Moolenaar // Terminal.app has a bug: 15 is light grey. Use white 604f9cc9f20SBram Moolenaar // from the color cube instead. 605f9cc9f20SBram Moolenaar color = 231; 606f9cc9f20SBram Moolenaar #endif 607f9cc9f20SBram Moolenaar } 608f9cc9f20SBram Moolenaar return color; 609f9cc9f20SBram Moolenaar } 610f9cc9f20SBram Moolenaar 611f9cc9f20SBram Moolenaar /* 612f9cc9f20SBram Moolenaar * Handle the ":highlight .." command. 613f9cc9f20SBram Moolenaar * When using ":hi clear" this is called recursively for each group with 614f9cc9f20SBram Moolenaar * "forceit" and "init" both TRUE. 615f9cc9f20SBram Moolenaar */ 616f9cc9f20SBram Moolenaar void 617f9cc9f20SBram Moolenaar do_highlight( 618f9cc9f20SBram Moolenaar char_u *line, 619f9cc9f20SBram Moolenaar int forceit, 620f9cc9f20SBram Moolenaar int init) // TRUE when called for initializing 621f9cc9f20SBram Moolenaar { 622f9cc9f20SBram Moolenaar char_u *name_end; 623f9cc9f20SBram Moolenaar char_u *p; 624f9cc9f20SBram Moolenaar char_u *linep; 625f9cc9f20SBram Moolenaar char_u *key_start; 626f9cc9f20SBram Moolenaar char_u *arg_start; 627f9cc9f20SBram Moolenaar char_u *key = NULL, *arg = NULL; 628f9cc9f20SBram Moolenaar long i; 629f9cc9f20SBram Moolenaar int off; 630f9cc9f20SBram Moolenaar int len; 631f9cc9f20SBram Moolenaar int attr; 632f9cc9f20SBram Moolenaar int id; 633f9cc9f20SBram Moolenaar int idx; 634f9cc9f20SBram Moolenaar hl_group_T item_before; 635f9cc9f20SBram Moolenaar int did_change = FALSE; 636f9cc9f20SBram Moolenaar int dodefault = FALSE; 637f9cc9f20SBram Moolenaar int doclear = FALSE; 638f9cc9f20SBram Moolenaar int dolink = FALSE; 639f9cc9f20SBram Moolenaar int error = FALSE; 640f9cc9f20SBram Moolenaar int color; 641f9cc9f20SBram Moolenaar int is_normal_group = FALSE; // "Normal" group 642f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 643f9cc9f20SBram Moolenaar int is_terminal_group = FALSE; // "Terminal" group 644f9cc9f20SBram Moolenaar #endif 645f9cc9f20SBram Moolenaar #ifdef FEAT_GUI_X11 646f9cc9f20SBram Moolenaar int is_menu_group = FALSE; // "Menu" group 647f9cc9f20SBram Moolenaar int is_scrollbar_group = FALSE; // "Scrollbar" group 648f9cc9f20SBram Moolenaar int is_tooltip_group = FALSE; // "Tooltip" group 649f9cc9f20SBram Moolenaar int do_colors = FALSE; // need to update colors? 650f9cc9f20SBram Moolenaar #else 651f9cc9f20SBram Moolenaar # define is_menu_group 0 652f9cc9f20SBram Moolenaar # define is_tooltip_group 0 653f9cc9f20SBram Moolenaar #endif 654f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 655f9cc9f20SBram Moolenaar int did_highlight_changed = FALSE; 656f9cc9f20SBram Moolenaar #endif 657f9cc9f20SBram Moolenaar 658f9cc9f20SBram Moolenaar /* 659f9cc9f20SBram Moolenaar * If no argument, list current highlighting. 660f9cc9f20SBram Moolenaar */ 6612c5ed4e3SBram Moolenaar if (!init && ends_excmd2(line - 1, line)) 662f9cc9f20SBram Moolenaar { 663f9cc9f20SBram Moolenaar for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i) 664f9cc9f20SBram Moolenaar // TODO: only call when the group has attributes set 665f9cc9f20SBram Moolenaar highlight_list_one((int)i); 666f9cc9f20SBram Moolenaar return; 667f9cc9f20SBram Moolenaar } 668f9cc9f20SBram Moolenaar 669f9cc9f20SBram Moolenaar /* 670f9cc9f20SBram Moolenaar * Isolate the name. 671f9cc9f20SBram Moolenaar */ 672f9cc9f20SBram Moolenaar name_end = skiptowhite(line); 673f9cc9f20SBram Moolenaar linep = skipwhite(name_end); 674f9cc9f20SBram Moolenaar 675f9cc9f20SBram Moolenaar /* 676f9cc9f20SBram Moolenaar * Check for "default" argument. 677f9cc9f20SBram Moolenaar */ 678f9cc9f20SBram Moolenaar if (STRNCMP(line, "default", name_end - line) == 0) 679f9cc9f20SBram Moolenaar { 680f9cc9f20SBram Moolenaar dodefault = TRUE; 681f9cc9f20SBram Moolenaar line = linep; 682f9cc9f20SBram Moolenaar name_end = skiptowhite(line); 683f9cc9f20SBram Moolenaar linep = skipwhite(name_end); 684f9cc9f20SBram Moolenaar } 685f9cc9f20SBram Moolenaar 686f9cc9f20SBram Moolenaar /* 687f9cc9f20SBram Moolenaar * Check for "clear" or "link" argument. 688f9cc9f20SBram Moolenaar */ 689f9cc9f20SBram Moolenaar if (STRNCMP(line, "clear", name_end - line) == 0) 690f9cc9f20SBram Moolenaar doclear = TRUE; 691f9cc9f20SBram Moolenaar if (STRNCMP(line, "link", name_end - line) == 0) 692f9cc9f20SBram Moolenaar dolink = TRUE; 693f9cc9f20SBram Moolenaar 694f9cc9f20SBram Moolenaar /* 695f9cc9f20SBram Moolenaar * ":highlight {group-name}": list highlighting for one group. 696f9cc9f20SBram Moolenaar */ 6971966c248SBram Moolenaar if (!doclear && !dolink && ends_excmd2(line, linep)) 698f9cc9f20SBram Moolenaar { 699f9cc9f20SBram Moolenaar id = syn_namen2id(line, (int)(name_end - line)); 700f9cc9f20SBram Moolenaar if (id == 0) 701f9cc9f20SBram Moolenaar semsg(_("E411: highlight group not found: %s"), line); 702f9cc9f20SBram Moolenaar else 703f9cc9f20SBram Moolenaar highlight_list_one(id); 704f9cc9f20SBram Moolenaar return; 705f9cc9f20SBram Moolenaar } 706f9cc9f20SBram Moolenaar 707f9cc9f20SBram Moolenaar /* 708f9cc9f20SBram Moolenaar * Handle ":highlight link {from} {to}" command. 709f9cc9f20SBram Moolenaar */ 710f9cc9f20SBram Moolenaar if (dolink) 711f9cc9f20SBram Moolenaar { 712f9cc9f20SBram Moolenaar char_u *from_start = linep; 713f9cc9f20SBram Moolenaar char_u *from_end; 714f9cc9f20SBram Moolenaar char_u *to_start; 715f9cc9f20SBram Moolenaar char_u *to_end; 716f9cc9f20SBram Moolenaar int from_id; 717f9cc9f20SBram Moolenaar int to_id; 718f9cc9f20SBram Moolenaar 719f9cc9f20SBram Moolenaar from_end = skiptowhite(from_start); 720f9cc9f20SBram Moolenaar to_start = skipwhite(from_end); 721f9cc9f20SBram Moolenaar to_end = skiptowhite(to_start); 722f9cc9f20SBram Moolenaar 7231966c248SBram Moolenaar if (ends_excmd2(line, from_start) || ends_excmd2(line, to_start)) 724f9cc9f20SBram Moolenaar { 725f9cc9f20SBram Moolenaar semsg(_("E412: Not enough arguments: \":highlight link %s\""), 726f9cc9f20SBram Moolenaar from_start); 727f9cc9f20SBram Moolenaar return; 728f9cc9f20SBram Moolenaar } 729f9cc9f20SBram Moolenaar 7301966c248SBram Moolenaar if (!ends_excmd2(line, skipwhite(to_end))) 731f9cc9f20SBram Moolenaar { 732f9cc9f20SBram Moolenaar semsg(_("E413: Too many arguments: \":highlight link %s\""), from_start); 733f9cc9f20SBram Moolenaar return; 734f9cc9f20SBram Moolenaar } 735f9cc9f20SBram Moolenaar 736f9cc9f20SBram Moolenaar from_id = syn_check_group(from_start, (int)(from_end - from_start)); 737f9cc9f20SBram Moolenaar if (STRNCMP(to_start, "NONE", 4) == 0) 738f9cc9f20SBram Moolenaar to_id = 0; 739f9cc9f20SBram Moolenaar else 740f9cc9f20SBram Moolenaar to_id = syn_check_group(to_start, (int)(to_end - to_start)); 741f9cc9f20SBram Moolenaar 742f9cc9f20SBram Moolenaar if (from_id > 0 && (!init || HL_TABLE()[from_id - 1].sg_set == 0)) 743f9cc9f20SBram Moolenaar { 744f9cc9f20SBram Moolenaar /* 745f9cc9f20SBram Moolenaar * Don't allow a link when there already is some highlighting 746f9cc9f20SBram Moolenaar * for the group, unless '!' is used 747f9cc9f20SBram Moolenaar */ 748f9cc9f20SBram Moolenaar if (to_id > 0 && !forceit && !init 749f9cc9f20SBram Moolenaar && hl_has_settings(from_id - 1, dodefault)) 750f9cc9f20SBram Moolenaar { 7511a47ae32SBram Moolenaar if (SOURCING_NAME == NULL && !dodefault) 752f9cc9f20SBram Moolenaar emsg(_("E414: group has settings, highlight link ignored")); 753f9cc9f20SBram Moolenaar } 754f9cc9f20SBram Moolenaar else if (HL_TABLE()[from_id - 1].sg_link != to_id 755f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 756f9cc9f20SBram Moolenaar || HL_TABLE()[from_id - 1].sg_script_ctx.sc_sid 757f9cc9f20SBram Moolenaar != current_sctx.sc_sid 758f9cc9f20SBram Moolenaar #endif 759f9cc9f20SBram Moolenaar || HL_TABLE()[from_id - 1].sg_cleared) 760f9cc9f20SBram Moolenaar { 761f9cc9f20SBram Moolenaar if (!init) 762f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_set |= SG_LINK; 763f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_link = to_id; 764f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 765f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_script_ctx = current_sctx; 7661a47ae32SBram Moolenaar HL_TABLE()[from_id - 1].sg_script_ctx.sc_lnum += SOURCING_LNUM; 767f9cc9f20SBram Moolenaar #endif 768f9cc9f20SBram Moolenaar HL_TABLE()[from_id - 1].sg_cleared = FALSE; 769f9cc9f20SBram Moolenaar redraw_all_later(SOME_VALID); 770f9cc9f20SBram Moolenaar 771f9cc9f20SBram Moolenaar // Only call highlight_changed() once after multiple changes. 772f9cc9f20SBram Moolenaar need_highlight_changed = TRUE; 773f9cc9f20SBram Moolenaar } 774f9cc9f20SBram Moolenaar } 775f9cc9f20SBram Moolenaar 776f9cc9f20SBram Moolenaar return; 777f9cc9f20SBram Moolenaar } 778f9cc9f20SBram Moolenaar 779f9cc9f20SBram Moolenaar if (doclear) 780f9cc9f20SBram Moolenaar { 781f9cc9f20SBram Moolenaar /* 782f9cc9f20SBram Moolenaar * ":highlight clear [group]" command. 783f9cc9f20SBram Moolenaar */ 7841966c248SBram Moolenaar if (ends_excmd2(line, linep)) 785f9cc9f20SBram Moolenaar { 786f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 787f9cc9f20SBram Moolenaar // First, we do not destroy the old values, but allocate the new 788f9cc9f20SBram Moolenaar // ones and update the display. THEN we destroy the old values. 789f9cc9f20SBram Moolenaar // If we destroy the old values first, then the old values 790f9cc9f20SBram Moolenaar // (such as GuiFont's or GuiFontset's) will still be displayed but 791f9cc9f20SBram Moolenaar // invalid because they were free'd. 792f9cc9f20SBram Moolenaar if (gui.in_use) 793f9cc9f20SBram Moolenaar { 794f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP 795f9cc9f20SBram Moolenaar gui_init_tooltip_font(); 796f9cc9f20SBram Moolenaar # endif 797f9cc9f20SBram Moolenaar # if defined(FEAT_MENU) && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF)) 798f9cc9f20SBram Moolenaar gui_init_menu_font(); 799f9cc9f20SBram Moolenaar # endif 800f9cc9f20SBram Moolenaar } 801f9cc9f20SBram Moolenaar # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_X11) 802f9cc9f20SBram Moolenaar gui_mch_def_colors(); 803f9cc9f20SBram Moolenaar # endif 804f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11 805f9cc9f20SBram Moolenaar # ifdef FEAT_MENU 806f9cc9f20SBram Moolenaar 807f9cc9f20SBram Moolenaar // This only needs to be done when there is no Menu highlight 808f9cc9f20SBram Moolenaar // group defined by default, which IS currently the case. 809f9cc9f20SBram Moolenaar gui_mch_new_menu_colors(); 810f9cc9f20SBram Moolenaar # endif 811f9cc9f20SBram Moolenaar if (gui.in_use) 812f9cc9f20SBram Moolenaar { 813f9cc9f20SBram Moolenaar gui_new_scrollbar_colors(); 814f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 815f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors(); 816f9cc9f20SBram Moolenaar # endif 817f9cc9f20SBram Moolenaar # ifdef FEAT_MENU 818f9cc9f20SBram Moolenaar gui_mch_new_menu_font(); 819f9cc9f20SBram Moolenaar # endif 820f9cc9f20SBram Moolenaar } 821f9cc9f20SBram Moolenaar # endif 822f9cc9f20SBram Moolenaar 823f9cc9f20SBram Moolenaar // Ok, we're done allocating the new default graphics items. 824f9cc9f20SBram Moolenaar // The screen should already be refreshed at this point. 825f9cc9f20SBram Moolenaar // It is now Ok to clear out the old data. 826f9cc9f20SBram Moolenaar #endif 827f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 8281966c248SBram Moolenaar do_unlet((char_u *)"g:colors_name", TRUE); 829f9cc9f20SBram Moolenaar #endif 830f9cc9f20SBram Moolenaar restore_cterm_colors(); 831f9cc9f20SBram Moolenaar 832f9cc9f20SBram Moolenaar /* 833f9cc9f20SBram Moolenaar * Clear all default highlight groups and load the defaults. 834f9cc9f20SBram Moolenaar */ 835f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx) 836f9cc9f20SBram Moolenaar highlight_clear(idx); 837f9cc9f20SBram Moolenaar init_highlight(TRUE, TRUE); 838f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 839f9cc9f20SBram Moolenaar if (USE_24BIT) 840f9cc9f20SBram Moolenaar highlight_gui_started(); 841f9cc9f20SBram Moolenaar else 842f9cc9f20SBram Moolenaar #endif 843f9cc9f20SBram Moolenaar highlight_changed(); 844f9cc9f20SBram Moolenaar redraw_later_clear(); 845f9cc9f20SBram Moolenaar return; 846f9cc9f20SBram Moolenaar } 8471966c248SBram Moolenaar line = linep; 848f9cc9f20SBram Moolenaar name_end = skiptowhite(line); 849f9cc9f20SBram Moolenaar linep = skipwhite(name_end); 850f9cc9f20SBram Moolenaar } 851f9cc9f20SBram Moolenaar 852f9cc9f20SBram Moolenaar /* 853f9cc9f20SBram Moolenaar * Find the group name in the table. If it does not exist yet, add it. 854f9cc9f20SBram Moolenaar */ 855f9cc9f20SBram Moolenaar id = syn_check_group(line, (int)(name_end - line)); 856f9cc9f20SBram Moolenaar if (id == 0) // failed (out of memory) 857f9cc9f20SBram Moolenaar return; 858f9cc9f20SBram Moolenaar idx = id - 1; // index is ID minus one 859f9cc9f20SBram Moolenaar 860f9cc9f20SBram Moolenaar // Return if "default" was used and the group already has settings. 861f9cc9f20SBram Moolenaar if (dodefault && hl_has_settings(idx, TRUE)) 862f9cc9f20SBram Moolenaar return; 863f9cc9f20SBram Moolenaar 864f9cc9f20SBram Moolenaar // Make a copy so we can check if any attribute actually changed. 865f9cc9f20SBram Moolenaar item_before = HL_TABLE()[idx]; 866f9cc9f20SBram Moolenaar 867f9cc9f20SBram Moolenaar if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0) 868f9cc9f20SBram Moolenaar is_normal_group = TRUE; 869f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 870f9cc9f20SBram Moolenaar else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TERMINAL") == 0) 871f9cc9f20SBram Moolenaar is_terminal_group = TRUE; 872f9cc9f20SBram Moolenaar #endif 873f9cc9f20SBram Moolenaar #ifdef FEAT_GUI_X11 874f9cc9f20SBram Moolenaar else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0) 875f9cc9f20SBram Moolenaar is_menu_group = TRUE; 876f9cc9f20SBram Moolenaar else if (STRCMP(HL_TABLE()[idx].sg_name_u, "SCROLLBAR") == 0) 877f9cc9f20SBram Moolenaar is_scrollbar_group = TRUE; 878f9cc9f20SBram Moolenaar else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TOOLTIP") == 0) 879f9cc9f20SBram Moolenaar is_tooltip_group = TRUE; 880f9cc9f20SBram Moolenaar #endif 881f9cc9f20SBram Moolenaar 882f9cc9f20SBram Moolenaar // Clear the highlighting for ":hi clear {group}" and ":hi clear". 883f9cc9f20SBram Moolenaar if (doclear || (forceit && init)) 884f9cc9f20SBram Moolenaar { 885f9cc9f20SBram Moolenaar highlight_clear(idx); 886f9cc9f20SBram Moolenaar if (!doclear) 887f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set = 0; 888f9cc9f20SBram Moolenaar } 889f9cc9f20SBram Moolenaar 890f9cc9f20SBram Moolenaar if (!doclear) 8911966c248SBram Moolenaar while (!ends_excmd2(line, linep)) 892f9cc9f20SBram Moolenaar { 893f9cc9f20SBram Moolenaar key_start = linep; 894f9cc9f20SBram Moolenaar if (*linep == '=') 895f9cc9f20SBram Moolenaar { 896f9cc9f20SBram Moolenaar semsg(_("E415: unexpected equal sign: %s"), key_start); 897f9cc9f20SBram Moolenaar error = TRUE; 898f9cc9f20SBram Moolenaar break; 899f9cc9f20SBram Moolenaar } 900f9cc9f20SBram Moolenaar 901f9cc9f20SBram Moolenaar /* 902f9cc9f20SBram Moolenaar * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or 903f9cc9f20SBram Moolenaar * "guibg"). 904f9cc9f20SBram Moolenaar */ 905f9cc9f20SBram Moolenaar while (*linep && !VIM_ISWHITE(*linep) && *linep != '=') 906f9cc9f20SBram Moolenaar ++linep; 907f9cc9f20SBram Moolenaar vim_free(key); 908f9cc9f20SBram Moolenaar key = vim_strnsave_up(key_start, (int)(linep - key_start)); 909f9cc9f20SBram Moolenaar if (key == NULL) 910f9cc9f20SBram Moolenaar { 911f9cc9f20SBram Moolenaar error = TRUE; 912f9cc9f20SBram Moolenaar break; 913f9cc9f20SBram Moolenaar } 914f9cc9f20SBram Moolenaar linep = skipwhite(linep); 915f9cc9f20SBram Moolenaar 916f9cc9f20SBram Moolenaar if (STRCMP(key, "NONE") == 0) 917f9cc9f20SBram Moolenaar { 918f9cc9f20SBram Moolenaar if (!init || HL_TABLE()[idx].sg_set == 0) 919f9cc9f20SBram Moolenaar { 920f9cc9f20SBram Moolenaar if (!init) 921f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI; 922f9cc9f20SBram Moolenaar highlight_clear(idx); 923f9cc9f20SBram Moolenaar } 924f9cc9f20SBram Moolenaar continue; 925f9cc9f20SBram Moolenaar } 926f9cc9f20SBram Moolenaar 927f9cc9f20SBram Moolenaar /* 928f9cc9f20SBram Moolenaar * Check for the equal sign. 929f9cc9f20SBram Moolenaar */ 930f9cc9f20SBram Moolenaar if (*linep != '=') 931f9cc9f20SBram Moolenaar { 932f9cc9f20SBram Moolenaar semsg(_("E416: missing equal sign: %s"), key_start); 933f9cc9f20SBram Moolenaar error = TRUE; 934f9cc9f20SBram Moolenaar break; 935f9cc9f20SBram Moolenaar } 936f9cc9f20SBram Moolenaar ++linep; 937f9cc9f20SBram Moolenaar 938f9cc9f20SBram Moolenaar /* 939f9cc9f20SBram Moolenaar * Isolate the argument. 940f9cc9f20SBram Moolenaar */ 941f9cc9f20SBram Moolenaar linep = skipwhite(linep); 942f9cc9f20SBram Moolenaar if (*linep == '\'') // guifg='color name' 943f9cc9f20SBram Moolenaar { 944f9cc9f20SBram Moolenaar arg_start = ++linep; 945f9cc9f20SBram Moolenaar linep = vim_strchr(linep, '\''); 946f9cc9f20SBram Moolenaar if (linep == NULL) 947f9cc9f20SBram Moolenaar { 948f9cc9f20SBram Moolenaar semsg(_(e_invarg2), key_start); 949f9cc9f20SBram Moolenaar error = TRUE; 950f9cc9f20SBram Moolenaar break; 951f9cc9f20SBram Moolenaar } 952f9cc9f20SBram Moolenaar } 953f9cc9f20SBram Moolenaar else 954f9cc9f20SBram Moolenaar { 955f9cc9f20SBram Moolenaar arg_start = linep; 956f9cc9f20SBram Moolenaar linep = skiptowhite(linep); 957f9cc9f20SBram Moolenaar } 958f9cc9f20SBram Moolenaar if (linep == arg_start) 959f9cc9f20SBram Moolenaar { 960f9cc9f20SBram Moolenaar semsg(_("E417: missing argument: %s"), key_start); 961f9cc9f20SBram Moolenaar error = TRUE; 962f9cc9f20SBram Moolenaar break; 963f9cc9f20SBram Moolenaar } 964f9cc9f20SBram Moolenaar vim_free(arg); 965f9cc9f20SBram Moolenaar arg = vim_strnsave(arg_start, (int)(linep - arg_start)); 966f9cc9f20SBram Moolenaar if (arg == NULL) 967f9cc9f20SBram Moolenaar { 968f9cc9f20SBram Moolenaar error = TRUE; 969f9cc9f20SBram Moolenaar break; 970f9cc9f20SBram Moolenaar } 971f9cc9f20SBram Moolenaar if (*linep == '\'') 972f9cc9f20SBram Moolenaar ++linep; 973f9cc9f20SBram Moolenaar 974f9cc9f20SBram Moolenaar /* 975f9cc9f20SBram Moolenaar * Store the argument. 976f9cc9f20SBram Moolenaar */ 977f9cc9f20SBram Moolenaar if ( STRCMP(key, "TERM") == 0 978f9cc9f20SBram Moolenaar || STRCMP(key, "CTERM") == 0 979f9cc9f20SBram Moolenaar || STRCMP(key, "GUI") == 0) 980f9cc9f20SBram Moolenaar { 981f9cc9f20SBram Moolenaar attr = 0; 982f9cc9f20SBram Moolenaar off = 0; 983f9cc9f20SBram Moolenaar while (arg[off] != NUL) 984f9cc9f20SBram Moolenaar { 985f9cc9f20SBram Moolenaar for (i = sizeof(hl_attr_table) / sizeof(int); --i >= 0; ) 986f9cc9f20SBram Moolenaar { 987f9cc9f20SBram Moolenaar len = (int)STRLEN(hl_name_table[i]); 988f9cc9f20SBram Moolenaar if (STRNICMP(arg + off, hl_name_table[i], len) == 0) 989f9cc9f20SBram Moolenaar { 990f9cc9f20SBram Moolenaar attr |= hl_attr_table[i]; 991f9cc9f20SBram Moolenaar off += len; 992f9cc9f20SBram Moolenaar break; 993f9cc9f20SBram Moolenaar } 994f9cc9f20SBram Moolenaar } 995f9cc9f20SBram Moolenaar if (i < 0) 996f9cc9f20SBram Moolenaar { 997f9cc9f20SBram Moolenaar semsg(_("E418: Illegal value: %s"), arg); 998f9cc9f20SBram Moolenaar error = TRUE; 999f9cc9f20SBram Moolenaar break; 1000f9cc9f20SBram Moolenaar } 1001f9cc9f20SBram Moolenaar if (arg[off] == ',') // another one follows 1002f9cc9f20SBram Moolenaar ++off; 1003f9cc9f20SBram Moolenaar } 1004f9cc9f20SBram Moolenaar if (error) 1005f9cc9f20SBram Moolenaar break; 1006f9cc9f20SBram Moolenaar if (*key == 'T') 1007f9cc9f20SBram Moolenaar { 1008f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM)) 1009f9cc9f20SBram Moolenaar { 1010f9cc9f20SBram Moolenaar if (!init) 1011f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_TERM; 1012f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term = attr; 1013f9cc9f20SBram Moolenaar } 1014f9cc9f20SBram Moolenaar } 1015f9cc9f20SBram Moolenaar else if (*key == 'C') 1016f9cc9f20SBram Moolenaar { 1017f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) 1018f9cc9f20SBram Moolenaar { 1019f9cc9f20SBram Moolenaar if (!init) 1020f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_CTERM; 1021f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm = attr; 1022f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = FALSE; 1023f9cc9f20SBram Moolenaar } 1024f9cc9f20SBram Moolenaar } 1025f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1026f9cc9f20SBram Moolenaar else 1027f9cc9f20SBram Moolenaar { 1028f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) 1029f9cc9f20SBram Moolenaar { 1030f9cc9f20SBram Moolenaar if (!init) 1031f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI; 1032f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui = attr; 1033f9cc9f20SBram Moolenaar } 1034f9cc9f20SBram Moolenaar } 1035f9cc9f20SBram Moolenaar #endif 1036f9cc9f20SBram Moolenaar } 1037f9cc9f20SBram Moolenaar else if (STRCMP(key, "FONT") == 0) 1038f9cc9f20SBram Moolenaar { 1039f9cc9f20SBram Moolenaar // in non-GUI fonts are simply ignored 1040f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1041f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font_name != NULL 1042f9cc9f20SBram Moolenaar && STRCMP(HL_TABLE()[idx].sg_font_name, arg) == 0) 1043f9cc9f20SBram Moolenaar { 1044f9cc9f20SBram Moolenaar // Font name didn't change, ignore. 1045f9cc9f20SBram Moolenaar } 1046f9cc9f20SBram Moolenaar else if (!gui.shell_created) 1047f9cc9f20SBram Moolenaar { 1048f9cc9f20SBram Moolenaar // GUI not started yet, always accept the name. 1049f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name); 1050f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg); 1051f9cc9f20SBram Moolenaar did_change = TRUE; 1052f9cc9f20SBram Moolenaar } 1053f9cc9f20SBram Moolenaar else 1054f9cc9f20SBram Moolenaar { 1055f9cc9f20SBram Moolenaar GuiFont temp_sg_font = HL_TABLE()[idx].sg_font; 1056f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1057f9cc9f20SBram Moolenaar GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset; 1058f9cc9f20SBram Moolenaar # endif 1059f9cc9f20SBram Moolenaar // First, save the current font/fontset. 1060f9cc9f20SBram Moolenaar // Then try to allocate the font/fontset. 1061f9cc9f20SBram Moolenaar // If the allocation fails, HL_TABLE()[idx].sg_font OR 1062f9cc9f20SBram Moolenaar // sg_fontset will be set to NOFONT or NOFONTSET respectively. 1063f9cc9f20SBram Moolenaar 1064f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT; 1065f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1066f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET; 1067f9cc9f20SBram Moolenaar # endif 1068f9cc9f20SBram Moolenaar hl_do_font(idx, arg, is_normal_group, is_menu_group, 1069f9cc9f20SBram Moolenaar is_tooltip_group, FALSE); 1070f9cc9f20SBram Moolenaar 1071f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1072f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_fontset != NOFONTSET) 1073f9cc9f20SBram Moolenaar { 1074f9cc9f20SBram Moolenaar // New fontset was accepted. Free the old one, if there 1075f9cc9f20SBram Moolenaar // was one. 1076f9cc9f20SBram Moolenaar gui_mch_free_fontset(temp_sg_fontset); 1077f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name); 1078f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg); 1079f9cc9f20SBram Moolenaar did_change = TRUE; 1080f9cc9f20SBram Moolenaar } 1081f9cc9f20SBram Moolenaar else 1082f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = temp_sg_fontset; 1083f9cc9f20SBram Moolenaar # endif 1084f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font != NOFONT) 1085f9cc9f20SBram Moolenaar { 1086f9cc9f20SBram Moolenaar // New font was accepted. Free the old one, if there was 1087f9cc9f20SBram Moolenaar // one. 1088f9cc9f20SBram Moolenaar gui_mch_free_font(temp_sg_font); 1089f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_font_name); 1090f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font_name = vim_strsave(arg); 1091f9cc9f20SBram Moolenaar did_change = TRUE; 1092f9cc9f20SBram Moolenaar } 1093f9cc9f20SBram Moolenaar else 1094f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = temp_sg_font; 1095f9cc9f20SBram Moolenaar } 1096f9cc9f20SBram Moolenaar #endif 1097f9cc9f20SBram Moolenaar } 1098f9cc9f20SBram Moolenaar else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) 1099f9cc9f20SBram Moolenaar { 1100f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) 1101f9cc9f20SBram Moolenaar { 1102f9cc9f20SBram Moolenaar if (!init) 1103f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_CTERM; 1104f9cc9f20SBram Moolenaar 1105f9cc9f20SBram Moolenaar // When setting the foreground color, and previously the "bold" 1106f9cc9f20SBram Moolenaar // flag was set for a light color, reset it now 1107f9cc9f20SBram Moolenaar if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold) 1108f9cc9f20SBram Moolenaar { 1109f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; 1110f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = FALSE; 1111f9cc9f20SBram Moolenaar } 1112f9cc9f20SBram Moolenaar 1113f9cc9f20SBram Moolenaar if (VIM_ISDIGIT(*arg)) 1114f9cc9f20SBram Moolenaar color = atoi((char *)arg); 1115f9cc9f20SBram Moolenaar else if (STRICMP(arg, "fg") == 0) 1116f9cc9f20SBram Moolenaar { 1117f9cc9f20SBram Moolenaar if (cterm_normal_fg_color) 1118f9cc9f20SBram Moolenaar color = cterm_normal_fg_color - 1; 1119f9cc9f20SBram Moolenaar else 1120f9cc9f20SBram Moolenaar { 1121f9cc9f20SBram Moolenaar emsg(_("E419: FG color unknown")); 1122f9cc9f20SBram Moolenaar error = TRUE; 1123f9cc9f20SBram Moolenaar break; 1124f9cc9f20SBram Moolenaar } 1125f9cc9f20SBram Moolenaar } 1126f9cc9f20SBram Moolenaar else if (STRICMP(arg, "bg") == 0) 1127f9cc9f20SBram Moolenaar { 1128f9cc9f20SBram Moolenaar if (cterm_normal_bg_color > 0) 1129f9cc9f20SBram Moolenaar color = cterm_normal_bg_color - 1; 1130f9cc9f20SBram Moolenaar else 1131f9cc9f20SBram Moolenaar { 1132f9cc9f20SBram Moolenaar emsg(_("E420: BG color unknown")); 1133f9cc9f20SBram Moolenaar error = TRUE; 1134f9cc9f20SBram Moolenaar break; 1135f9cc9f20SBram Moolenaar } 1136f9cc9f20SBram Moolenaar } 1137f9cc9f20SBram Moolenaar else 1138f9cc9f20SBram Moolenaar { 1139f9cc9f20SBram Moolenaar int bold = MAYBE; 1140f9cc9f20SBram Moolenaar 1141f9cc9f20SBram Moolenaar // reduce calls to STRICMP a bit, it can be slow 1142f9cc9f20SBram Moolenaar off = TOUPPER_ASC(*arg); 1143f9cc9f20SBram Moolenaar for (i = (sizeof(color_names) / sizeof(char *)); --i >= 0; ) 1144f9cc9f20SBram Moolenaar if (off == color_names[i][0] 1145f9cc9f20SBram Moolenaar && STRICMP(arg + 1, color_names[i] + 1) == 0) 1146f9cc9f20SBram Moolenaar break; 1147f9cc9f20SBram Moolenaar if (i < 0) 1148f9cc9f20SBram Moolenaar { 1149f9cc9f20SBram Moolenaar semsg(_("E421: Color name or number not recognized: %s"), key_start); 1150f9cc9f20SBram Moolenaar error = TRUE; 1151f9cc9f20SBram Moolenaar break; 1152f9cc9f20SBram Moolenaar } 1153f9cc9f20SBram Moolenaar 1154f9cc9f20SBram Moolenaar color = lookup_color(i, key[5] == 'F', &bold); 1155f9cc9f20SBram Moolenaar 1156f9cc9f20SBram Moolenaar // set/reset bold attribute to get light foreground 1157f9cc9f20SBram Moolenaar // colors (on some terminals, e.g. "linux") 1158f9cc9f20SBram Moolenaar if (bold == TRUE) 1159f9cc9f20SBram Moolenaar { 1160f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm |= HL_BOLD; 1161f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = TRUE; 1162f9cc9f20SBram Moolenaar } 1163f9cc9f20SBram Moolenaar else if (bold == FALSE) 1164f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; 1165f9cc9f20SBram Moolenaar } 1166f9cc9f20SBram Moolenaar 1167f9cc9f20SBram Moolenaar // Add one to the argument, to avoid zero. Zero is used for 1168f9cc9f20SBram Moolenaar // "NONE", then "color" is -1. 1169f9cc9f20SBram Moolenaar if (key[5] == 'F') 1170f9cc9f20SBram Moolenaar { 1171f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_fg = color + 1; 1172f9cc9f20SBram Moolenaar if (is_normal_group) 1173f9cc9f20SBram Moolenaar { 1174f9cc9f20SBram Moolenaar cterm_normal_fg_color = color + 1; 1175f9cc9f20SBram Moolenaar cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD); 1176f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1177f9cc9f20SBram Moolenaar // Don't do this if the GUI is used. 1178f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting) 1179f9cc9f20SBram Moolenaar #endif 1180f9cc9f20SBram Moolenaar { 1181f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1182f9cc9f20SBram Moolenaar if (termcap_active && color >= 0) 1183f9cc9f20SBram Moolenaar term_fg_color(color); 1184f9cc9f20SBram Moolenaar } 1185f9cc9f20SBram Moolenaar } 1186f9cc9f20SBram Moolenaar } 1187f9cc9f20SBram Moolenaar else 1188f9cc9f20SBram Moolenaar { 1189f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bg = color + 1; 1190f9cc9f20SBram Moolenaar if (is_normal_group) 1191f9cc9f20SBram Moolenaar { 1192f9cc9f20SBram Moolenaar cterm_normal_bg_color = color + 1; 1193f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1194f9cc9f20SBram Moolenaar // Don't mess with 'background' if the GUI is used. 1195f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting) 1196f9cc9f20SBram Moolenaar #endif 1197f9cc9f20SBram Moolenaar { 1198f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1199f9cc9f20SBram Moolenaar if (color >= 0) 1200f9cc9f20SBram Moolenaar { 1201f9cc9f20SBram Moolenaar int dark = -1; 1202f9cc9f20SBram Moolenaar 1203f9cc9f20SBram Moolenaar if (termcap_active) 1204f9cc9f20SBram Moolenaar term_bg_color(color); 1205f9cc9f20SBram Moolenaar if (t_colors < 16) 1206f9cc9f20SBram Moolenaar dark = (color == 0 || color == 4); 1207f9cc9f20SBram Moolenaar // Limit the heuristic to the standard 16 colors 1208f9cc9f20SBram Moolenaar else if (color < 16) 1209f9cc9f20SBram Moolenaar dark = (color < 7 || color == 8); 1210f9cc9f20SBram Moolenaar // Set the 'background' option if the value is 1211f9cc9f20SBram Moolenaar // wrong. 1212f9cc9f20SBram Moolenaar if (dark != -1 1213f9cc9f20SBram Moolenaar && dark != (*p_bg == 'd') 1214f9cc9f20SBram Moolenaar && !option_was_set((char_u *)"bg")) 1215f9cc9f20SBram Moolenaar { 1216f9cc9f20SBram Moolenaar set_option_value((char_u *)"bg", 0L, 1217f9cc9f20SBram Moolenaar (char_u *)(dark ? "dark" : "light"), 0); 1218f9cc9f20SBram Moolenaar reset_option_was_set((char_u *)"bg"); 1219f9cc9f20SBram Moolenaar } 1220f9cc9f20SBram Moolenaar } 1221f9cc9f20SBram Moolenaar } 1222f9cc9f20SBram Moolenaar } 1223f9cc9f20SBram Moolenaar } 1224f9cc9f20SBram Moolenaar } 1225f9cc9f20SBram Moolenaar } 1226f9cc9f20SBram Moolenaar else if (STRCMP(key, "GUIFG") == 0) 1227f9cc9f20SBram Moolenaar { 1228f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1229f9cc9f20SBram Moolenaar char_u **namep = &HL_TABLE()[idx].sg_gui_fg_name; 1230f9cc9f20SBram Moolenaar 1231f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) 1232f9cc9f20SBram Moolenaar { 1233f9cc9f20SBram Moolenaar if (!init) 1234f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI; 1235f9cc9f20SBram Moolenaar 1236f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1237f9cc9f20SBram Moolenaar // In GUI guifg colors are only used when recognized 1238f9cc9f20SBram Moolenaar i = color_name2handle(arg); 1239f9cc9f20SBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) 1240f9cc9f20SBram Moolenaar { 1241f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg = i; 1242f9cc9f20SBram Moolenaar # endif 1243f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0) 1244f9cc9f20SBram Moolenaar { 1245f9cc9f20SBram Moolenaar vim_free(*namep); 1246f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0) 1247f9cc9f20SBram Moolenaar *namep = vim_strsave(arg); 1248f9cc9f20SBram Moolenaar else 1249f9cc9f20SBram Moolenaar *namep = NULL; 1250f9cc9f20SBram Moolenaar did_change = TRUE; 1251f9cc9f20SBram Moolenaar } 1252f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1253f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11 1254f9cc9f20SBram Moolenaar if (is_menu_group && gui.menu_fg_pixel != i) 1255f9cc9f20SBram Moolenaar { 1256f9cc9f20SBram Moolenaar gui.menu_fg_pixel = i; 1257f9cc9f20SBram Moolenaar do_colors = TRUE; 1258f9cc9f20SBram Moolenaar } 1259f9cc9f20SBram Moolenaar if (is_scrollbar_group && gui.scroll_fg_pixel != i) 1260f9cc9f20SBram Moolenaar { 1261f9cc9f20SBram Moolenaar gui.scroll_fg_pixel = i; 1262f9cc9f20SBram Moolenaar do_colors = TRUE; 1263f9cc9f20SBram Moolenaar } 1264f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1265f9cc9f20SBram Moolenaar if (is_tooltip_group && gui.tooltip_fg_pixel != i) 1266f9cc9f20SBram Moolenaar { 1267f9cc9f20SBram Moolenaar gui.tooltip_fg_pixel = i; 1268f9cc9f20SBram Moolenaar do_colors = TRUE; 1269f9cc9f20SBram Moolenaar } 1270f9cc9f20SBram Moolenaar # endif 1271f9cc9f20SBram Moolenaar # endif 1272f9cc9f20SBram Moolenaar } 1273f9cc9f20SBram Moolenaar # endif 1274f9cc9f20SBram Moolenaar } 1275f9cc9f20SBram Moolenaar #endif 1276f9cc9f20SBram Moolenaar } 1277f9cc9f20SBram Moolenaar else if (STRCMP(key, "GUIBG") == 0) 1278f9cc9f20SBram Moolenaar { 1279f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1280f9cc9f20SBram Moolenaar char_u **namep = &HL_TABLE()[idx].sg_gui_bg_name; 1281f9cc9f20SBram Moolenaar 1282f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) 1283f9cc9f20SBram Moolenaar { 1284f9cc9f20SBram Moolenaar if (!init) 1285f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI; 1286f9cc9f20SBram Moolenaar 1287f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1288f9cc9f20SBram Moolenaar // In GUI guifg colors are only used when recognized 1289f9cc9f20SBram Moolenaar i = color_name2handle(arg); 1290f9cc9f20SBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT) 1291f9cc9f20SBram Moolenaar { 1292f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg = i; 1293f9cc9f20SBram Moolenaar # endif 1294f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0) 1295f9cc9f20SBram Moolenaar { 1296f9cc9f20SBram Moolenaar vim_free(*namep); 1297f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0) 1298f9cc9f20SBram Moolenaar *namep = vim_strsave(arg); 1299f9cc9f20SBram Moolenaar else 1300f9cc9f20SBram Moolenaar *namep = NULL; 1301f9cc9f20SBram Moolenaar did_change = TRUE; 1302f9cc9f20SBram Moolenaar } 1303f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1304f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11 1305f9cc9f20SBram Moolenaar if (is_menu_group && gui.menu_bg_pixel != i) 1306f9cc9f20SBram Moolenaar { 1307f9cc9f20SBram Moolenaar gui.menu_bg_pixel = i; 1308f9cc9f20SBram Moolenaar do_colors = TRUE; 1309f9cc9f20SBram Moolenaar } 1310f9cc9f20SBram Moolenaar if (is_scrollbar_group && gui.scroll_bg_pixel != i) 1311f9cc9f20SBram Moolenaar { 1312f9cc9f20SBram Moolenaar gui.scroll_bg_pixel = i; 1313f9cc9f20SBram Moolenaar do_colors = TRUE; 1314f9cc9f20SBram Moolenaar } 1315f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1316f9cc9f20SBram Moolenaar if (is_tooltip_group && gui.tooltip_bg_pixel != i) 1317f9cc9f20SBram Moolenaar { 1318f9cc9f20SBram Moolenaar gui.tooltip_bg_pixel = i; 1319f9cc9f20SBram Moolenaar do_colors = TRUE; 1320f9cc9f20SBram Moolenaar } 1321f9cc9f20SBram Moolenaar # endif 1322f9cc9f20SBram Moolenaar # endif 1323f9cc9f20SBram Moolenaar } 1324f9cc9f20SBram Moolenaar # endif 1325f9cc9f20SBram Moolenaar } 1326f9cc9f20SBram Moolenaar #endif 1327f9cc9f20SBram Moolenaar } 1328f9cc9f20SBram Moolenaar else if (STRCMP(key, "GUISP") == 0) 1329f9cc9f20SBram Moolenaar { 1330f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1331f9cc9f20SBram Moolenaar char_u **namep = &HL_TABLE()[idx].sg_gui_sp_name; 1332f9cc9f20SBram Moolenaar 1333f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) 1334f9cc9f20SBram Moolenaar { 1335f9cc9f20SBram Moolenaar if (!init) 1336f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_GUI; 1337f9cc9f20SBram Moolenaar 1338f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 1339f9cc9f20SBram Moolenaar i = color_name2handle(arg); 1340f9cc9f20SBram Moolenaar if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use) 1341f9cc9f20SBram Moolenaar { 1342f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_sp = i; 1343f9cc9f20SBram Moolenaar # endif 1344f9cc9f20SBram Moolenaar if (*namep == NULL || STRCMP(*namep, arg) != 0) 1345f9cc9f20SBram Moolenaar { 1346f9cc9f20SBram Moolenaar vim_free(*namep); 1347f9cc9f20SBram Moolenaar if (STRCMP(arg, "NONE") != 0) 1348f9cc9f20SBram Moolenaar *namep = vim_strsave(arg); 1349f9cc9f20SBram Moolenaar else 1350f9cc9f20SBram Moolenaar *namep = NULL; 1351f9cc9f20SBram Moolenaar did_change = TRUE; 1352f9cc9f20SBram Moolenaar } 1353f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 1354f9cc9f20SBram Moolenaar } 1355f9cc9f20SBram Moolenaar # endif 1356f9cc9f20SBram Moolenaar } 1357f9cc9f20SBram Moolenaar #endif 1358f9cc9f20SBram Moolenaar } 1359f9cc9f20SBram Moolenaar else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0) 1360f9cc9f20SBram Moolenaar { 1361f9cc9f20SBram Moolenaar char_u buf[100]; 1362f9cc9f20SBram Moolenaar char_u *tname; 1363f9cc9f20SBram Moolenaar 1364f9cc9f20SBram Moolenaar if (!init) 1365f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_set |= SG_TERM; 1366f9cc9f20SBram Moolenaar 1367f9cc9f20SBram Moolenaar /* 1368f9cc9f20SBram Moolenaar * The "start" and "stop" arguments can be a literal escape 1369f9cc9f20SBram Moolenaar * sequence, or a comma separated list of terminal codes. 1370f9cc9f20SBram Moolenaar */ 1371f9cc9f20SBram Moolenaar if (STRNCMP(arg, "t_", 2) == 0) 1372f9cc9f20SBram Moolenaar { 1373f9cc9f20SBram Moolenaar off = 0; 1374f9cc9f20SBram Moolenaar buf[0] = 0; 1375f9cc9f20SBram Moolenaar while (arg[off] != NUL) 1376f9cc9f20SBram Moolenaar { 1377f9cc9f20SBram Moolenaar // Isolate one termcap name 1378f9cc9f20SBram Moolenaar for (len = 0; arg[off + len] && 1379f9cc9f20SBram Moolenaar arg[off + len] != ','; ++len) 1380f9cc9f20SBram Moolenaar ; 1381f9cc9f20SBram Moolenaar tname = vim_strnsave(arg + off, len); 1382f9cc9f20SBram Moolenaar if (tname == NULL) // out of memory 1383f9cc9f20SBram Moolenaar { 1384f9cc9f20SBram Moolenaar error = TRUE; 1385f9cc9f20SBram Moolenaar break; 1386f9cc9f20SBram Moolenaar } 1387f9cc9f20SBram Moolenaar // lookup the escape sequence for the item 1388f9cc9f20SBram Moolenaar p = get_term_code(tname); 1389f9cc9f20SBram Moolenaar vim_free(tname); 1390f9cc9f20SBram Moolenaar if (p == NULL) // ignore non-existing things 1391f9cc9f20SBram Moolenaar p = (char_u *)""; 1392f9cc9f20SBram Moolenaar 1393f9cc9f20SBram Moolenaar // Append it to the already found stuff 1394f9cc9f20SBram Moolenaar if ((int)(STRLEN(buf) + STRLEN(p)) >= 99) 1395f9cc9f20SBram Moolenaar { 1396f9cc9f20SBram Moolenaar semsg(_("E422: terminal code too long: %s"), arg); 1397f9cc9f20SBram Moolenaar error = TRUE; 1398f9cc9f20SBram Moolenaar break; 1399f9cc9f20SBram Moolenaar } 1400f9cc9f20SBram Moolenaar STRCAT(buf, p); 1401f9cc9f20SBram Moolenaar 1402f9cc9f20SBram Moolenaar // Advance to the next item 1403f9cc9f20SBram Moolenaar off += len; 1404f9cc9f20SBram Moolenaar if (arg[off] == ',') // another one follows 1405f9cc9f20SBram Moolenaar ++off; 1406f9cc9f20SBram Moolenaar } 1407f9cc9f20SBram Moolenaar } 1408f9cc9f20SBram Moolenaar else 1409f9cc9f20SBram Moolenaar { 1410f9cc9f20SBram Moolenaar /* 1411f9cc9f20SBram Moolenaar * Copy characters from arg[] to buf[], translating <> codes. 1412f9cc9f20SBram Moolenaar */ 1413f9cc9f20SBram Moolenaar for (p = arg, off = 0; off < 100 - 6 && *p; ) 1414f9cc9f20SBram Moolenaar { 1415*ebe9d34aSBram Moolenaar len = trans_special(&p, buf + off, FSK_SIMPLIFY, NULL); 1416f9cc9f20SBram Moolenaar if (len > 0) // recognized special char 1417f9cc9f20SBram Moolenaar off += len; 1418f9cc9f20SBram Moolenaar else // copy as normal char 1419f9cc9f20SBram Moolenaar buf[off++] = *p++; 1420f9cc9f20SBram Moolenaar } 1421f9cc9f20SBram Moolenaar buf[off] = NUL; 1422f9cc9f20SBram Moolenaar } 1423f9cc9f20SBram Moolenaar if (error) 1424f9cc9f20SBram Moolenaar break; 1425f9cc9f20SBram Moolenaar 1426f9cc9f20SBram Moolenaar if (STRCMP(buf, "NONE") == 0) // resetting the value 1427f9cc9f20SBram Moolenaar p = NULL; 1428f9cc9f20SBram Moolenaar else 1429f9cc9f20SBram Moolenaar p = vim_strsave(buf); 1430f9cc9f20SBram Moolenaar if (key[2] == 'A') 1431f9cc9f20SBram Moolenaar { 1432f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_start); 1433f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_start = p; 1434f9cc9f20SBram Moolenaar } 1435f9cc9f20SBram Moolenaar else 1436f9cc9f20SBram Moolenaar { 1437f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[idx].sg_stop); 1438f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_stop = p; 1439f9cc9f20SBram Moolenaar } 1440f9cc9f20SBram Moolenaar } 1441f9cc9f20SBram Moolenaar else 1442f9cc9f20SBram Moolenaar { 1443f9cc9f20SBram Moolenaar semsg(_("E423: Illegal argument: %s"), key_start); 1444f9cc9f20SBram Moolenaar error = TRUE; 1445f9cc9f20SBram Moolenaar break; 1446f9cc9f20SBram Moolenaar } 1447f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cleared = FALSE; 1448f9cc9f20SBram Moolenaar 1449f9cc9f20SBram Moolenaar /* 1450f9cc9f20SBram Moolenaar * When highlighting has been given for a group, don't link it. 1451f9cc9f20SBram Moolenaar */ 1452f9cc9f20SBram Moolenaar if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK)) 1453f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_link = 0; 1454f9cc9f20SBram Moolenaar 1455f9cc9f20SBram Moolenaar /* 1456f9cc9f20SBram Moolenaar * Continue with next argument. 1457f9cc9f20SBram Moolenaar */ 1458f9cc9f20SBram Moolenaar linep = skipwhite(linep); 1459f9cc9f20SBram Moolenaar } 1460f9cc9f20SBram Moolenaar 1461f9cc9f20SBram Moolenaar /* 1462f9cc9f20SBram Moolenaar * If there is an error, and it's a new entry, remove it from the table. 1463f9cc9f20SBram Moolenaar */ 1464f9cc9f20SBram Moolenaar if (error && idx == highlight_ga.ga_len) 1465f9cc9f20SBram Moolenaar syn_unadd_group(); 1466f9cc9f20SBram Moolenaar else 1467f9cc9f20SBram Moolenaar { 1468f9cc9f20SBram Moolenaar if (is_normal_group) 1469f9cc9f20SBram Moolenaar { 1470f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term_attr = 0; 1471f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_attr = 0; 1472f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1473f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_attr = 0; 1474f9cc9f20SBram Moolenaar /* 1475f9cc9f20SBram Moolenaar * Need to update all groups, because they might be using "bg" 1476f9cc9f20SBram Moolenaar * and/or "fg", which have been changed now. 1477f9cc9f20SBram Moolenaar */ 1478f9cc9f20SBram Moolenaar #endif 1479f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1480f9cc9f20SBram Moolenaar if (USE_24BIT) 1481f9cc9f20SBram Moolenaar { 1482f9cc9f20SBram Moolenaar highlight_gui_started(); 1483f9cc9f20SBram Moolenaar did_highlight_changed = TRUE; 1484f9cc9f20SBram Moolenaar redraw_all_later(NOT_VALID); 1485f9cc9f20SBram Moolenaar } 1486f9cc9f20SBram Moolenaar #endif 1487a8bd3496SBram Moolenaar #ifdef FEAT_VTP 1488a8bd3496SBram Moolenaar control_console_color_rgb(); 1489a8bd3496SBram Moolenaar #endif 1490f9cc9f20SBram Moolenaar } 1491f9cc9f20SBram Moolenaar #ifdef FEAT_TERMINAL 1492f9cc9f20SBram Moolenaar else if (is_terminal_group) 1493f9cc9f20SBram Moolenaar set_terminal_default_colors( 1494f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_fg, HL_TABLE()[idx].sg_cterm_bg); 1495f9cc9f20SBram Moolenaar #endif 1496f9cc9f20SBram Moolenaar #ifdef FEAT_GUI_X11 1497f9cc9f20SBram Moolenaar # ifdef FEAT_MENU 1498f9cc9f20SBram Moolenaar else if (is_menu_group) 1499f9cc9f20SBram Moolenaar { 1500f9cc9f20SBram Moolenaar if (gui.in_use && do_colors) 1501f9cc9f20SBram Moolenaar gui_mch_new_menu_colors(); 1502f9cc9f20SBram Moolenaar } 1503f9cc9f20SBram Moolenaar # endif 1504f9cc9f20SBram Moolenaar else if (is_scrollbar_group) 1505f9cc9f20SBram Moolenaar { 1506f9cc9f20SBram Moolenaar if (gui.in_use && do_colors) 1507f9cc9f20SBram Moolenaar gui_new_scrollbar_colors(); 1508f9cc9f20SBram Moolenaar else 1509f9cc9f20SBram Moolenaar set_hl_attr(idx); 1510f9cc9f20SBram Moolenaar } 1511f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1512f9cc9f20SBram Moolenaar else if (is_tooltip_group) 1513f9cc9f20SBram Moolenaar { 1514f9cc9f20SBram Moolenaar if (gui.in_use && do_colors) 1515f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors(); 1516f9cc9f20SBram Moolenaar } 1517f9cc9f20SBram Moolenaar # endif 1518f9cc9f20SBram Moolenaar #endif 1519f9cc9f20SBram Moolenaar else 1520f9cc9f20SBram Moolenaar set_hl_attr(idx); 1521f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 1522f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_script_ctx = current_sctx; 15231a47ae32SBram Moolenaar HL_TABLE()[idx].sg_script_ctx.sc_lnum += SOURCING_LNUM; 1524f9cc9f20SBram Moolenaar #endif 1525f9cc9f20SBram Moolenaar } 1526f9cc9f20SBram Moolenaar 1527f9cc9f20SBram Moolenaar vim_free(key); 1528f9cc9f20SBram Moolenaar vim_free(arg); 1529f9cc9f20SBram Moolenaar 1530f9cc9f20SBram Moolenaar // Only call highlight_changed() once, after a sequence of highlight 1531f9cc9f20SBram Moolenaar // commands, and only if an attribute actually changed. 1532f9cc9f20SBram Moolenaar if ((did_change 1533f9cc9f20SBram Moolenaar || memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0) 1534f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1535f9cc9f20SBram Moolenaar && !did_highlight_changed 1536f9cc9f20SBram Moolenaar #endif 1537f9cc9f20SBram Moolenaar ) 1538f9cc9f20SBram Moolenaar { 1539f9cc9f20SBram Moolenaar // Do not trigger a redraw when highlighting is changed while 1540f9cc9f20SBram Moolenaar // redrawing. This may happen when evaluating 'statusline' changes the 1541f9cc9f20SBram Moolenaar // StatusLine group. 1542f9cc9f20SBram Moolenaar if (!updating_screen) 1543f9cc9f20SBram Moolenaar redraw_all_later(NOT_VALID); 1544f9cc9f20SBram Moolenaar need_highlight_changed = TRUE; 1545f9cc9f20SBram Moolenaar } 1546f9cc9f20SBram Moolenaar } 1547f9cc9f20SBram Moolenaar 1548f9cc9f20SBram Moolenaar #if defined(EXITFREE) || defined(PROTO) 1549f9cc9f20SBram Moolenaar void 1550f9cc9f20SBram Moolenaar free_highlight(void) 1551f9cc9f20SBram Moolenaar { 1552f9cc9f20SBram Moolenaar int i; 1553f9cc9f20SBram Moolenaar 1554f9cc9f20SBram Moolenaar for (i = 0; i < highlight_ga.ga_len; ++i) 1555f9cc9f20SBram Moolenaar { 1556f9cc9f20SBram Moolenaar highlight_clear(i); 1557f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[i].sg_name); 1558f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[i].sg_name_u); 1559f9cc9f20SBram Moolenaar } 1560f9cc9f20SBram Moolenaar ga_clear(&highlight_ga); 1561f9cc9f20SBram Moolenaar } 1562f9cc9f20SBram Moolenaar #endif 1563f9cc9f20SBram Moolenaar 1564f9cc9f20SBram Moolenaar /* 1565f9cc9f20SBram Moolenaar * Reset the cterm colors to what they were before Vim was started, if 1566f9cc9f20SBram Moolenaar * possible. Otherwise reset them to zero. 1567f9cc9f20SBram Moolenaar */ 1568f9cc9f20SBram Moolenaar void 1569f9cc9f20SBram Moolenaar restore_cterm_colors(void) 1570f9cc9f20SBram Moolenaar { 1571f9cc9f20SBram Moolenaar #if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) 1572f9cc9f20SBram Moolenaar // Since t_me has been set, this probably means that the user 1573f9cc9f20SBram Moolenaar // wants to use this as default colors. Need to reset default 1574f9cc9f20SBram Moolenaar // background/foreground colors. 1575f9cc9f20SBram Moolenaar mch_set_normal_colors(); 1576f9cc9f20SBram Moolenaar #else 1577f9cc9f20SBram Moolenaar # ifdef VIMDLL 1578f9cc9f20SBram Moolenaar if (!gui.in_use) 1579f9cc9f20SBram Moolenaar { 1580f9cc9f20SBram Moolenaar mch_set_normal_colors(); 1581f9cc9f20SBram Moolenaar return; 1582f9cc9f20SBram Moolenaar } 1583f9cc9f20SBram Moolenaar # endif 1584f9cc9f20SBram Moolenaar cterm_normal_fg_color = 0; 1585f9cc9f20SBram Moolenaar cterm_normal_fg_bold = 0; 1586f9cc9f20SBram Moolenaar cterm_normal_bg_color = 0; 1587f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 1588f9cc9f20SBram Moolenaar cterm_normal_fg_gui_color = INVALCOLOR; 1589f9cc9f20SBram Moolenaar cterm_normal_bg_gui_color = INVALCOLOR; 1590f9cc9f20SBram Moolenaar # endif 1591f9cc9f20SBram Moolenaar #endif 1592f9cc9f20SBram Moolenaar } 1593f9cc9f20SBram Moolenaar 1594f9cc9f20SBram Moolenaar /* 1595f9cc9f20SBram Moolenaar * Return TRUE if highlight group "idx" has any settings. 1596f9cc9f20SBram Moolenaar * When "check_link" is TRUE also check for an existing link. 1597f9cc9f20SBram Moolenaar */ 1598f9cc9f20SBram Moolenaar static int 1599f9cc9f20SBram Moolenaar hl_has_settings(int idx, int check_link) 1600f9cc9f20SBram Moolenaar { 1601f9cc9f20SBram Moolenaar return ( HL_TABLE()[idx].sg_term_attr != 0 1602f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_attr != 0 1603f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_fg != 0 1604f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_cterm_bg != 0 1605f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1606f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_attr != 0 1607f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_fg_name != NULL 1608f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_bg_name != NULL 1609f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_gui_sp_name != NULL 1610f9cc9f20SBram Moolenaar || HL_TABLE()[idx].sg_font_name != NULL 1611f9cc9f20SBram Moolenaar #endif 1612f9cc9f20SBram Moolenaar || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK))); 1613f9cc9f20SBram Moolenaar } 1614f9cc9f20SBram Moolenaar 1615f9cc9f20SBram Moolenaar /* 1616f9cc9f20SBram Moolenaar * Clear highlighting for one group. 1617f9cc9f20SBram Moolenaar */ 1618f9cc9f20SBram Moolenaar static void 1619f9cc9f20SBram Moolenaar highlight_clear(int idx) 1620f9cc9f20SBram Moolenaar { 1621f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cleared = TRUE; 1622f9cc9f20SBram Moolenaar 1623f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term = 0; 1624f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_start); 1625f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_stop); 1626f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_term_attr = 0; 1627f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm = 0; 1628f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bold = FALSE; 1629f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_fg = 0; 1630f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_bg = 0; 1631f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_cterm_attr = 0; 1632f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 1633f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui = 0; 1634f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_fg_name); 1635f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_bg_name); 1636f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_gui_sp_name); 1637f9cc9f20SBram Moolenaar #endif 1638f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 1639f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg = INVALCOLOR; 1640f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg = INVALCOLOR; 1641f9cc9f20SBram Moolenaar #endif 1642f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1643f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_sp = INVALCOLOR; 1644f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font); 1645f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT; 1646f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1647f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); 1648f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET; 1649f9cc9f20SBram Moolenaar # endif 1650f9cc9f20SBram Moolenaar VIM_CLEAR(HL_TABLE()[idx].sg_font_name); 1651f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_attr = 0; 1652f9cc9f20SBram Moolenaar #endif 1653f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 1654f9cc9f20SBram Moolenaar // Clear the script ID only when there is no link, since that is not 1655f9cc9f20SBram Moolenaar // cleared. 1656f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_link == 0) 1657f9cc9f20SBram Moolenaar { 1658f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_script_ctx.sc_sid = 0; 1659f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_script_ctx.sc_lnum = 0; 1660f9cc9f20SBram Moolenaar } 1661f9cc9f20SBram Moolenaar #endif 1662f9cc9f20SBram Moolenaar } 1663f9cc9f20SBram Moolenaar 1664f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) 1665f9cc9f20SBram Moolenaar /* 1666f9cc9f20SBram Moolenaar * Set the normal foreground and background colors according to the "Normal" 1667f9cc9f20SBram Moolenaar * highlighting group. For X11 also set "Menu", "Scrollbar", and 1668f9cc9f20SBram Moolenaar * "Tooltip" colors. 1669f9cc9f20SBram Moolenaar */ 1670f9cc9f20SBram Moolenaar void 1671f9cc9f20SBram Moolenaar set_normal_colors(void) 1672f9cc9f20SBram Moolenaar { 1673f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 1674f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 1675f9cc9f20SBram Moolenaar if (gui.in_use) 1676f9cc9f20SBram Moolenaar # endif 1677f9cc9f20SBram Moolenaar { 1678f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Normal", 1679f9cc9f20SBram Moolenaar &gui.norm_pixel, &gui.back_pixel, 1680f9cc9f20SBram Moolenaar FALSE, TRUE, FALSE)) 1681f9cc9f20SBram Moolenaar { 1682f9cc9f20SBram Moolenaar gui_mch_new_colors(); 1683f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1684f9cc9f20SBram Moolenaar } 1685f9cc9f20SBram Moolenaar # ifdef FEAT_GUI_X11 1686f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Menu", 1687f9cc9f20SBram Moolenaar &gui.menu_fg_pixel, &gui.menu_bg_pixel, 1688f9cc9f20SBram Moolenaar TRUE, FALSE, FALSE)) 1689f9cc9f20SBram Moolenaar { 1690f9cc9f20SBram Moolenaar # ifdef FEAT_MENU 1691f9cc9f20SBram Moolenaar gui_mch_new_menu_colors(); 1692f9cc9f20SBram Moolenaar # endif 1693f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1694f9cc9f20SBram Moolenaar } 1695f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1696f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Tooltip", 1697f9cc9f20SBram Moolenaar &gui.tooltip_fg_pixel, &gui.tooltip_bg_pixel, 1698f9cc9f20SBram Moolenaar FALSE, FALSE, TRUE)) 1699f9cc9f20SBram Moolenaar { 1700f9cc9f20SBram Moolenaar # ifdef FEAT_TOOLBAR 1701f9cc9f20SBram Moolenaar gui_mch_new_tooltip_colors(); 1702f9cc9f20SBram Moolenaar # endif 1703f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1704f9cc9f20SBram Moolenaar } 1705f9cc9f20SBram Moolenaar # endif 1706f9cc9f20SBram Moolenaar if (set_group_colors((char_u *)"Scrollbar", 1707f9cc9f20SBram Moolenaar &gui.scroll_fg_pixel, &gui.scroll_bg_pixel, 1708f9cc9f20SBram Moolenaar FALSE, FALSE, FALSE)) 1709f9cc9f20SBram Moolenaar { 1710f9cc9f20SBram Moolenaar gui_new_scrollbar_colors(); 1711f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1712f9cc9f20SBram Moolenaar } 1713f9cc9f20SBram Moolenaar # endif 1714f9cc9f20SBram Moolenaar } 1715f9cc9f20SBram Moolenaar # endif 1716f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 1717f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 1718f9cc9f20SBram Moolenaar else 1719f9cc9f20SBram Moolenaar # endif 1720f9cc9f20SBram Moolenaar { 1721f9cc9f20SBram Moolenaar int idx; 1722f9cc9f20SBram Moolenaar 1723f9cc9f20SBram Moolenaar idx = syn_name2id((char_u *)"Normal") - 1; 1724f9cc9f20SBram Moolenaar if (idx >= 0) 1725f9cc9f20SBram Moolenaar { 1726f9cc9f20SBram Moolenaar gui_do_one_color(idx, FALSE, FALSE); 1727f9cc9f20SBram Moolenaar 1728f9cc9f20SBram Moolenaar // If the normal fg or bg color changed a complete redraw is 1729f9cc9f20SBram Moolenaar // required. 1730f9cc9f20SBram Moolenaar if (cterm_normal_fg_gui_color != HL_TABLE()[idx].sg_gui_fg 1731f9cc9f20SBram Moolenaar || cterm_normal_bg_gui_color != HL_TABLE()[idx].sg_gui_bg) 1732f9cc9f20SBram Moolenaar { 1733f9cc9f20SBram Moolenaar // if the GUI color is INVALCOLOR then we use the default cterm 1734f9cc9f20SBram Moolenaar // color 1735f9cc9f20SBram Moolenaar cterm_normal_fg_gui_color = HL_TABLE()[idx].sg_gui_fg; 1736f9cc9f20SBram Moolenaar cterm_normal_bg_gui_color = HL_TABLE()[idx].sg_gui_bg; 1737f9cc9f20SBram Moolenaar must_redraw = CLEAR; 1738f9cc9f20SBram Moolenaar } 1739f9cc9f20SBram Moolenaar } 1740f9cc9f20SBram Moolenaar } 1741f9cc9f20SBram Moolenaar # endif 1742f9cc9f20SBram Moolenaar } 1743f9cc9f20SBram Moolenaar #endif 1744f9cc9f20SBram Moolenaar 1745f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(PROTO) 1746f9cc9f20SBram Moolenaar /* 1747f9cc9f20SBram Moolenaar * Set the colors for "Normal", "Menu", "Tooltip" or "Scrollbar". 1748f9cc9f20SBram Moolenaar */ 1749f9cc9f20SBram Moolenaar static int 1750f9cc9f20SBram Moolenaar set_group_colors( 1751f9cc9f20SBram Moolenaar char_u *name, 1752f9cc9f20SBram Moolenaar guicolor_T *fgp, 1753f9cc9f20SBram Moolenaar guicolor_T *bgp, 1754f9cc9f20SBram Moolenaar int do_menu, 1755f9cc9f20SBram Moolenaar int use_norm, 1756f9cc9f20SBram Moolenaar int do_tooltip) 1757f9cc9f20SBram Moolenaar { 1758f9cc9f20SBram Moolenaar int idx; 1759f9cc9f20SBram Moolenaar 1760f9cc9f20SBram Moolenaar idx = syn_name2id(name) - 1; 1761f9cc9f20SBram Moolenaar if (idx >= 0) 1762f9cc9f20SBram Moolenaar { 1763f9cc9f20SBram Moolenaar gui_do_one_color(idx, do_menu, do_tooltip); 1764f9cc9f20SBram Moolenaar 1765f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_fg != INVALCOLOR) 1766f9cc9f20SBram Moolenaar *fgp = HL_TABLE()[idx].sg_gui_fg; 1767f9cc9f20SBram Moolenaar else if (use_norm) 1768f9cc9f20SBram Moolenaar *fgp = gui.def_norm_pixel; 1769f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_bg != INVALCOLOR) 1770f9cc9f20SBram Moolenaar *bgp = HL_TABLE()[idx].sg_gui_bg; 1771f9cc9f20SBram Moolenaar else if (use_norm) 1772f9cc9f20SBram Moolenaar *bgp = gui.def_back_pixel; 1773f9cc9f20SBram Moolenaar return TRUE; 1774f9cc9f20SBram Moolenaar } 1775f9cc9f20SBram Moolenaar return FALSE; 1776f9cc9f20SBram Moolenaar } 1777f9cc9f20SBram Moolenaar 1778f9cc9f20SBram Moolenaar /* 1779f9cc9f20SBram Moolenaar * Get the font of the "Normal" group. 1780f9cc9f20SBram Moolenaar * Returns "" when it's not found or not set. 1781f9cc9f20SBram Moolenaar */ 1782f9cc9f20SBram Moolenaar char_u * 1783f9cc9f20SBram Moolenaar hl_get_font_name(void) 1784f9cc9f20SBram Moolenaar { 1785f9cc9f20SBram Moolenaar int id; 1786f9cc9f20SBram Moolenaar char_u *s; 1787f9cc9f20SBram Moolenaar 1788f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 1789f9cc9f20SBram Moolenaar if (id > 0) 1790f9cc9f20SBram Moolenaar { 1791f9cc9f20SBram Moolenaar s = HL_TABLE()[id - 1].sg_font_name; 1792f9cc9f20SBram Moolenaar if (s != NULL) 1793f9cc9f20SBram Moolenaar return s; 1794f9cc9f20SBram Moolenaar } 1795f9cc9f20SBram Moolenaar return (char_u *)""; 1796f9cc9f20SBram Moolenaar } 1797f9cc9f20SBram Moolenaar 1798f9cc9f20SBram Moolenaar /* 1799f9cc9f20SBram Moolenaar * Set font for "Normal" group. Called by gui_mch_init_font() when a font has 1800f9cc9f20SBram Moolenaar * actually chosen to be used. 1801f9cc9f20SBram Moolenaar */ 1802f9cc9f20SBram Moolenaar void 1803f9cc9f20SBram Moolenaar hl_set_font_name(char_u *font_name) 1804f9cc9f20SBram Moolenaar { 1805f9cc9f20SBram Moolenaar int id; 1806f9cc9f20SBram Moolenaar 1807f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 1808f9cc9f20SBram Moolenaar if (id > 0) 1809f9cc9f20SBram Moolenaar { 1810f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_font_name); 1811f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_font_name = vim_strsave(font_name); 1812f9cc9f20SBram Moolenaar } 1813f9cc9f20SBram Moolenaar } 1814f9cc9f20SBram Moolenaar 1815f9cc9f20SBram Moolenaar /* 1816f9cc9f20SBram Moolenaar * Set background color for "Normal" group. Called by gui_set_bg_color() 1817f9cc9f20SBram Moolenaar * when the color is known. 1818f9cc9f20SBram Moolenaar */ 1819f9cc9f20SBram Moolenaar void 1820f9cc9f20SBram Moolenaar hl_set_bg_color_name( 1821f9cc9f20SBram Moolenaar char_u *name) // must have been allocated 1822f9cc9f20SBram Moolenaar { 1823f9cc9f20SBram Moolenaar int id; 1824f9cc9f20SBram Moolenaar 1825f9cc9f20SBram Moolenaar if (name != NULL) 1826f9cc9f20SBram Moolenaar { 1827f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 1828f9cc9f20SBram Moolenaar if (id > 0) 1829f9cc9f20SBram Moolenaar { 1830f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_gui_bg_name); 1831f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_gui_bg_name = name; 1832f9cc9f20SBram Moolenaar } 1833f9cc9f20SBram Moolenaar } 1834f9cc9f20SBram Moolenaar } 1835f9cc9f20SBram Moolenaar 1836f9cc9f20SBram Moolenaar /* 1837f9cc9f20SBram Moolenaar * Set foreground color for "Normal" group. Called by gui_set_fg_color() 1838f9cc9f20SBram Moolenaar * when the color is known. 1839f9cc9f20SBram Moolenaar */ 1840f9cc9f20SBram Moolenaar void 1841f9cc9f20SBram Moolenaar hl_set_fg_color_name( 1842f9cc9f20SBram Moolenaar char_u *name) // must have been allocated 1843f9cc9f20SBram Moolenaar { 1844f9cc9f20SBram Moolenaar int id; 1845f9cc9f20SBram Moolenaar 1846f9cc9f20SBram Moolenaar if (name != NULL) 1847f9cc9f20SBram Moolenaar { 1848f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 1849f9cc9f20SBram Moolenaar if (id > 0) 1850f9cc9f20SBram Moolenaar { 1851f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[id - 1].sg_gui_fg_name); 1852f9cc9f20SBram Moolenaar HL_TABLE()[id - 1].sg_gui_fg_name = name; 1853f9cc9f20SBram Moolenaar } 1854f9cc9f20SBram Moolenaar } 1855f9cc9f20SBram Moolenaar } 1856f9cc9f20SBram Moolenaar 1857f9cc9f20SBram Moolenaar /* 1858f9cc9f20SBram Moolenaar * Return the handle for a font name. 1859f9cc9f20SBram Moolenaar * Returns NOFONT when failed. 1860f9cc9f20SBram Moolenaar */ 1861f9cc9f20SBram Moolenaar static GuiFont 1862f9cc9f20SBram Moolenaar font_name2handle(char_u *name) 1863f9cc9f20SBram Moolenaar { 1864f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0) 1865f9cc9f20SBram Moolenaar return NOFONT; 1866f9cc9f20SBram Moolenaar 1867f9cc9f20SBram Moolenaar return gui_mch_get_font(name, TRUE); 1868f9cc9f20SBram Moolenaar } 1869f9cc9f20SBram Moolenaar 1870f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1871f9cc9f20SBram Moolenaar /* 1872f9cc9f20SBram Moolenaar * Return the handle for a fontset name. 1873f9cc9f20SBram Moolenaar * Returns NOFONTSET when failed. 1874f9cc9f20SBram Moolenaar */ 1875f9cc9f20SBram Moolenaar static GuiFontset 1876f9cc9f20SBram Moolenaar fontset_name2handle(char_u *name, int fixed_width) 1877f9cc9f20SBram Moolenaar { 1878f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0) 1879f9cc9f20SBram Moolenaar return NOFONTSET; 1880f9cc9f20SBram Moolenaar 1881f9cc9f20SBram Moolenaar return gui_mch_get_fontset(name, TRUE, fixed_width); 1882f9cc9f20SBram Moolenaar } 1883f9cc9f20SBram Moolenaar # endif 1884f9cc9f20SBram Moolenaar 1885f9cc9f20SBram Moolenaar /* 1886f9cc9f20SBram Moolenaar * Get the font or fontset for one highlight group. 1887f9cc9f20SBram Moolenaar */ 1888f9cc9f20SBram Moolenaar static void 1889f9cc9f20SBram Moolenaar hl_do_font( 1890f9cc9f20SBram Moolenaar int idx, 1891f9cc9f20SBram Moolenaar char_u *arg, 1892f9cc9f20SBram Moolenaar int do_normal, // set normal font 1893f9cc9f20SBram Moolenaar int do_menu UNUSED, // set menu font 1894f9cc9f20SBram Moolenaar int do_tooltip UNUSED, // set tooltip font 1895f9cc9f20SBram Moolenaar int free_font) // free current font/fontset 1896f9cc9f20SBram Moolenaar { 1897f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 1898f9cc9f20SBram Moolenaar // If 'guifontset' is not empty, first try using the name as a 1899f9cc9f20SBram Moolenaar // fontset. If that doesn't work, use it as a font name. 1900f9cc9f20SBram Moolenaar if (*p_guifontset != NUL 1901f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS 1902f9cc9f20SBram Moolenaar || do_menu 1903f9cc9f20SBram Moolenaar # endif 1904f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP 1905f9cc9f20SBram Moolenaar // In Athena & Motif, the Tooltip highlight group is always a fontset 1906f9cc9f20SBram Moolenaar || do_tooltip 1907f9cc9f20SBram Moolenaar # endif 1908f9cc9f20SBram Moolenaar ) 1909f9cc9f20SBram Moolenaar { 1910f9cc9f20SBram Moolenaar if (free_font) 1911f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); 1912f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = fontset_name2handle(arg, 0 1913f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS 1914f9cc9f20SBram Moolenaar || do_menu 1915f9cc9f20SBram Moolenaar # endif 1916f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_TIP 1917f9cc9f20SBram Moolenaar || do_tooltip 1918f9cc9f20SBram Moolenaar # endif 1919f9cc9f20SBram Moolenaar ); 1920f9cc9f20SBram Moolenaar } 1921f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_fontset != NOFONTSET) 1922f9cc9f20SBram Moolenaar { 1923f9cc9f20SBram Moolenaar // If it worked and it's the Normal group, use it as the normal 1924f9cc9f20SBram Moolenaar // fontset. Same for the Menu group. 1925f9cc9f20SBram Moolenaar if (do_normal) 1926f9cc9f20SBram Moolenaar gui_init_font(arg, TRUE); 1927f9cc9f20SBram Moolenaar # if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU) 1928f9cc9f20SBram Moolenaar if (do_menu) 1929f9cc9f20SBram Moolenaar { 1930f9cc9f20SBram Moolenaar # ifdef FONTSET_ALWAYS 1931f9cc9f20SBram Moolenaar gui.menu_fontset = HL_TABLE()[idx].sg_fontset; 1932f9cc9f20SBram Moolenaar # else 1933f9cc9f20SBram Moolenaar // YIKES! This is a bug waiting to crash the program 1934f9cc9f20SBram Moolenaar gui.menu_font = HL_TABLE()[idx].sg_fontset; 1935f9cc9f20SBram Moolenaar # endif 1936f9cc9f20SBram Moolenaar gui_mch_new_menu_font(); 1937f9cc9f20SBram Moolenaar } 1938f9cc9f20SBram Moolenaar # ifdef FEAT_BEVAL_GUI 1939f9cc9f20SBram Moolenaar if (do_tooltip) 1940f9cc9f20SBram Moolenaar { 1941f9cc9f20SBram Moolenaar // The Athena widget set cannot currently handle switching between 1942f9cc9f20SBram Moolenaar // displaying a single font and a fontset. 1943f9cc9f20SBram Moolenaar // If the XtNinternational resource is set to True at widget 1944f9cc9f20SBram Moolenaar // creation, then a fontset is always used, otherwise an 1945f9cc9f20SBram Moolenaar // XFontStruct is used. 1946f9cc9f20SBram Moolenaar gui.tooltip_fontset = (XFontSet)HL_TABLE()[idx].sg_fontset; 1947f9cc9f20SBram Moolenaar gui_mch_new_tooltip_font(); 1948f9cc9f20SBram Moolenaar } 1949f9cc9f20SBram Moolenaar # endif 1950f9cc9f20SBram Moolenaar # endif 1951f9cc9f20SBram Moolenaar } 1952f9cc9f20SBram Moolenaar else 1953f9cc9f20SBram Moolenaar # endif 1954f9cc9f20SBram Moolenaar { 1955f9cc9f20SBram Moolenaar if (free_font) 1956f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font); 1957f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = font_name2handle(arg); 1958f9cc9f20SBram Moolenaar // If it worked and it's the Normal group, use it as the 1959f9cc9f20SBram Moolenaar // normal font. Same for the Menu group. 1960f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font != NOFONT) 1961f9cc9f20SBram Moolenaar { 1962f9cc9f20SBram Moolenaar if (do_normal) 1963f9cc9f20SBram Moolenaar gui_init_font(arg, FALSE); 1964f9cc9f20SBram Moolenaar #ifndef FONTSET_ALWAYS 1965f9cc9f20SBram Moolenaar # if (defined(FEAT_GUI_MOTIF) || defined(FEAT_GUI_ATHENA)) && defined(FEAT_MENU) 1966f9cc9f20SBram Moolenaar if (do_menu) 1967f9cc9f20SBram Moolenaar { 1968f9cc9f20SBram Moolenaar gui.menu_font = HL_TABLE()[idx].sg_font; 1969f9cc9f20SBram Moolenaar gui_mch_new_menu_font(); 1970f9cc9f20SBram Moolenaar } 1971f9cc9f20SBram Moolenaar # endif 1972f9cc9f20SBram Moolenaar #endif 1973f9cc9f20SBram Moolenaar } 1974f9cc9f20SBram Moolenaar } 1975f9cc9f20SBram Moolenaar } 1976f9cc9f20SBram Moolenaar 1977f9cc9f20SBram Moolenaar #endif // FEAT_GUI 1978f9cc9f20SBram Moolenaar 1979f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) 1980f9cc9f20SBram Moolenaar /* 1981f9cc9f20SBram Moolenaar * Return the handle for a color name. 1982f9cc9f20SBram Moolenaar * Returns INVALCOLOR when failed. 1983f9cc9f20SBram Moolenaar */ 1984f9cc9f20SBram Moolenaar guicolor_T 1985f9cc9f20SBram Moolenaar color_name2handle(char_u *name) 1986f9cc9f20SBram Moolenaar { 1987f9cc9f20SBram Moolenaar if (STRCMP(name, "NONE") == 0) 1988f9cc9f20SBram Moolenaar return INVALCOLOR; 1989f9cc9f20SBram Moolenaar 1990f9cc9f20SBram Moolenaar if (STRICMP(name, "fg") == 0 || STRICMP(name, "foreground") == 0) 1991f9cc9f20SBram Moolenaar { 1992f9cc9f20SBram Moolenaar #if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) 1993f9cc9f20SBram Moolenaar if (gui.in_use) 1994f9cc9f20SBram Moolenaar #endif 1995f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 1996f9cc9f20SBram Moolenaar return gui.norm_pixel; 1997f9cc9f20SBram Moolenaar #endif 1998f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 1999f9cc9f20SBram Moolenaar if (cterm_normal_fg_gui_color != INVALCOLOR) 2000f9cc9f20SBram Moolenaar return cterm_normal_fg_gui_color; 2001f9cc9f20SBram Moolenaar // Guess that the foreground is black or white. 2002f9cc9f20SBram Moolenaar return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "black" : "white")); 2003f9cc9f20SBram Moolenaar #endif 2004f9cc9f20SBram Moolenaar } 2005f9cc9f20SBram Moolenaar if (STRICMP(name, "bg") == 0 || STRICMP(name, "background") == 0) 2006f9cc9f20SBram Moolenaar { 2007f9cc9f20SBram Moolenaar #if defined(FEAT_TERMGUICOLORS) && defined(FEAT_GUI) 2008f9cc9f20SBram Moolenaar if (gui.in_use) 2009f9cc9f20SBram Moolenaar #endif 2010f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2011f9cc9f20SBram Moolenaar return gui.back_pixel; 2012f9cc9f20SBram Moolenaar #endif 2013f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2014f9cc9f20SBram Moolenaar if (cterm_normal_bg_gui_color != INVALCOLOR) 2015f9cc9f20SBram Moolenaar return cterm_normal_bg_gui_color; 2016f9cc9f20SBram Moolenaar // Guess that the background is white or black. 2017f9cc9f20SBram Moolenaar return GUI_GET_COLOR((char_u *)(*p_bg == 'l' ? "white" : "black")); 2018f9cc9f20SBram Moolenaar #endif 2019f9cc9f20SBram Moolenaar } 2020f9cc9f20SBram Moolenaar 2021f9cc9f20SBram Moolenaar return GUI_GET_COLOR(name); 2022f9cc9f20SBram Moolenaar } 2023f9cc9f20SBram Moolenaar #endif 2024f9cc9f20SBram Moolenaar 2025f9cc9f20SBram Moolenaar /* 2026f9cc9f20SBram Moolenaar * Table with the specifications for an attribute number. 2027f9cc9f20SBram Moolenaar * Note that this table is used by ALL buffers. This is required because the 2028f9cc9f20SBram Moolenaar * GUI can redraw at any time for any buffer. 2029f9cc9f20SBram Moolenaar */ 2030f9cc9f20SBram Moolenaar static garray_T term_attr_table = {0, 0, 0, 0, NULL}; 2031f9cc9f20SBram Moolenaar 2032f9cc9f20SBram Moolenaar #define TERM_ATTR_ENTRY(idx) ((attrentry_T *)term_attr_table.ga_data)[idx] 2033f9cc9f20SBram Moolenaar 2034f9cc9f20SBram Moolenaar static garray_T cterm_attr_table = {0, 0, 0, 0, NULL}; 2035f9cc9f20SBram Moolenaar 2036f9cc9f20SBram Moolenaar #define CTERM_ATTR_ENTRY(idx) ((attrentry_T *)cterm_attr_table.ga_data)[idx] 2037f9cc9f20SBram Moolenaar 2038f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2039f9cc9f20SBram Moolenaar static garray_T gui_attr_table = {0, 0, 0, 0, NULL}; 2040f9cc9f20SBram Moolenaar 2041f9cc9f20SBram Moolenaar #define GUI_ATTR_ENTRY(idx) ((attrentry_T *)gui_attr_table.ga_data)[idx] 2042f9cc9f20SBram Moolenaar #endif 2043f9cc9f20SBram Moolenaar 2044f9cc9f20SBram Moolenaar /* 2045f9cc9f20SBram Moolenaar * Return the attr number for a set of colors and font. 2046f9cc9f20SBram Moolenaar * Add a new entry to the term_attr_table, cterm_attr_table or gui_attr_table 2047f9cc9f20SBram Moolenaar * if the combination is new. 2048f9cc9f20SBram Moolenaar * Return 0 for error (no more room). 2049f9cc9f20SBram Moolenaar */ 2050f9cc9f20SBram Moolenaar static int 2051f9cc9f20SBram Moolenaar get_attr_entry(garray_T *table, attrentry_T *aep) 2052f9cc9f20SBram Moolenaar { 2053f9cc9f20SBram Moolenaar int i; 2054f9cc9f20SBram Moolenaar attrentry_T *taep; 2055f9cc9f20SBram Moolenaar static int recursive = FALSE; 2056f9cc9f20SBram Moolenaar 2057f9cc9f20SBram Moolenaar /* 2058f9cc9f20SBram Moolenaar * Init the table, in case it wasn't done yet. 2059f9cc9f20SBram Moolenaar */ 2060f9cc9f20SBram Moolenaar table->ga_itemsize = sizeof(attrentry_T); 2061f9cc9f20SBram Moolenaar table->ga_growsize = 7; 2062f9cc9f20SBram Moolenaar 2063f9cc9f20SBram Moolenaar /* 2064f9cc9f20SBram Moolenaar * Try to find an entry with the same specifications. 2065f9cc9f20SBram Moolenaar */ 2066f9cc9f20SBram Moolenaar for (i = 0; i < table->ga_len; ++i) 2067f9cc9f20SBram Moolenaar { 2068f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)table->ga_data)[i]); 2069f9cc9f20SBram Moolenaar if ( aep->ae_attr == taep->ae_attr 2070f9cc9f20SBram Moolenaar && ( 2071f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2072f9cc9f20SBram Moolenaar (table == &gui_attr_table 2073f9cc9f20SBram Moolenaar && (aep->ae_u.gui.fg_color == taep->ae_u.gui.fg_color 2074f9cc9f20SBram Moolenaar && aep->ae_u.gui.bg_color 2075f9cc9f20SBram Moolenaar == taep->ae_u.gui.bg_color 2076f9cc9f20SBram Moolenaar && aep->ae_u.gui.sp_color 2077f9cc9f20SBram Moolenaar == taep->ae_u.gui.sp_color 2078f9cc9f20SBram Moolenaar && aep->ae_u.gui.font == taep->ae_u.gui.font 2079f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2080f9cc9f20SBram Moolenaar && aep->ae_u.gui.fontset == taep->ae_u.gui.fontset 2081f9cc9f20SBram Moolenaar # endif 2082f9cc9f20SBram Moolenaar )) 2083f9cc9f20SBram Moolenaar || 2084f9cc9f20SBram Moolenaar #endif 2085f9cc9f20SBram Moolenaar (table == &term_attr_table 2086f9cc9f20SBram Moolenaar && (aep->ae_u.term.start == NULL) 2087f9cc9f20SBram Moolenaar == (taep->ae_u.term.start == NULL) 2088f9cc9f20SBram Moolenaar && (aep->ae_u.term.start == NULL 2089f9cc9f20SBram Moolenaar || STRCMP(aep->ae_u.term.start, 2090f9cc9f20SBram Moolenaar taep->ae_u.term.start) == 0) 2091f9cc9f20SBram Moolenaar && (aep->ae_u.term.stop == NULL) 2092f9cc9f20SBram Moolenaar == (taep->ae_u.term.stop == NULL) 2093f9cc9f20SBram Moolenaar && (aep->ae_u.term.stop == NULL 2094f9cc9f20SBram Moolenaar || STRCMP(aep->ae_u.term.stop, 2095f9cc9f20SBram Moolenaar taep->ae_u.term.stop) == 0)) 2096f9cc9f20SBram Moolenaar || (table == &cterm_attr_table 2097f9cc9f20SBram Moolenaar && aep->ae_u.cterm.fg_color 2098f9cc9f20SBram Moolenaar == taep->ae_u.cterm.fg_color 2099f9cc9f20SBram Moolenaar && aep->ae_u.cterm.bg_color 2100f9cc9f20SBram Moolenaar == taep->ae_u.cterm.bg_color 2101f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2102f9cc9f20SBram Moolenaar && aep->ae_u.cterm.fg_rgb 2103f9cc9f20SBram Moolenaar == taep->ae_u.cterm.fg_rgb 2104f9cc9f20SBram Moolenaar && aep->ae_u.cterm.bg_rgb 2105f9cc9f20SBram Moolenaar == taep->ae_u.cterm.bg_rgb 2106f9cc9f20SBram Moolenaar #endif 2107f9cc9f20SBram Moolenaar ))) 2108f9cc9f20SBram Moolenaar 2109f9cc9f20SBram Moolenaar return i + ATTR_OFF; 2110f9cc9f20SBram Moolenaar } 2111f9cc9f20SBram Moolenaar 2112f9cc9f20SBram Moolenaar if (table->ga_len + ATTR_OFF > MAX_TYPENR) 2113f9cc9f20SBram Moolenaar { 2114f9cc9f20SBram Moolenaar /* 2115f9cc9f20SBram Moolenaar * Running out of attribute entries! remove all attributes, and 2116f9cc9f20SBram Moolenaar * compute new ones for all groups. 2117f9cc9f20SBram Moolenaar * When called recursively, we are really out of numbers. 2118f9cc9f20SBram Moolenaar */ 2119f9cc9f20SBram Moolenaar if (recursive) 2120f9cc9f20SBram Moolenaar { 2121f9cc9f20SBram Moolenaar emsg(_("E424: Too many different highlighting attributes in use")); 2122f9cc9f20SBram Moolenaar return 0; 2123f9cc9f20SBram Moolenaar } 2124f9cc9f20SBram Moolenaar recursive = TRUE; 2125f9cc9f20SBram Moolenaar 2126f9cc9f20SBram Moolenaar clear_hl_tables(); 2127f9cc9f20SBram Moolenaar 2128f9cc9f20SBram Moolenaar must_redraw = CLEAR; 2129f9cc9f20SBram Moolenaar 2130f9cc9f20SBram Moolenaar for (i = 0; i < highlight_ga.ga_len; ++i) 2131f9cc9f20SBram Moolenaar set_hl_attr(i); 2132f9cc9f20SBram Moolenaar 2133f9cc9f20SBram Moolenaar recursive = FALSE; 2134f9cc9f20SBram Moolenaar } 2135f9cc9f20SBram Moolenaar 2136f9cc9f20SBram Moolenaar /* 2137f9cc9f20SBram Moolenaar * This is a new combination of colors and font, add an entry. 2138f9cc9f20SBram Moolenaar */ 2139f9cc9f20SBram Moolenaar if (ga_grow(table, 1) == FAIL) 2140f9cc9f20SBram Moolenaar return 0; 2141f9cc9f20SBram Moolenaar 2142f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)table->ga_data)[table->ga_len]); 2143a80faa89SBram Moolenaar CLEAR_POINTER(taep); 2144f9cc9f20SBram Moolenaar taep->ae_attr = aep->ae_attr; 2145f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2146f9cc9f20SBram Moolenaar if (table == &gui_attr_table) 2147f9cc9f20SBram Moolenaar { 2148f9cc9f20SBram Moolenaar taep->ae_u.gui.fg_color = aep->ae_u.gui.fg_color; 2149f9cc9f20SBram Moolenaar taep->ae_u.gui.bg_color = aep->ae_u.gui.bg_color; 2150f9cc9f20SBram Moolenaar taep->ae_u.gui.sp_color = aep->ae_u.gui.sp_color; 2151f9cc9f20SBram Moolenaar taep->ae_u.gui.font = aep->ae_u.gui.font; 2152f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2153f9cc9f20SBram Moolenaar taep->ae_u.gui.fontset = aep->ae_u.gui.fontset; 2154f9cc9f20SBram Moolenaar # endif 2155f9cc9f20SBram Moolenaar } 2156f9cc9f20SBram Moolenaar #endif 2157f9cc9f20SBram Moolenaar if (table == &term_attr_table) 2158f9cc9f20SBram Moolenaar { 2159f9cc9f20SBram Moolenaar if (aep->ae_u.term.start == NULL) 2160f9cc9f20SBram Moolenaar taep->ae_u.term.start = NULL; 2161f9cc9f20SBram Moolenaar else 2162f9cc9f20SBram Moolenaar taep->ae_u.term.start = vim_strsave(aep->ae_u.term.start); 2163f9cc9f20SBram Moolenaar if (aep->ae_u.term.stop == NULL) 2164f9cc9f20SBram Moolenaar taep->ae_u.term.stop = NULL; 2165f9cc9f20SBram Moolenaar else 2166f9cc9f20SBram Moolenaar taep->ae_u.term.stop = vim_strsave(aep->ae_u.term.stop); 2167f9cc9f20SBram Moolenaar } 2168f9cc9f20SBram Moolenaar else if (table == &cterm_attr_table) 2169f9cc9f20SBram Moolenaar { 2170f9cc9f20SBram Moolenaar taep->ae_u.cterm.fg_color = aep->ae_u.cterm.fg_color; 2171f9cc9f20SBram Moolenaar taep->ae_u.cterm.bg_color = aep->ae_u.cterm.bg_color; 2172f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2173f9cc9f20SBram Moolenaar taep->ae_u.cterm.fg_rgb = aep->ae_u.cterm.fg_rgb; 2174f9cc9f20SBram Moolenaar taep->ae_u.cterm.bg_rgb = aep->ae_u.cterm.bg_rgb; 2175f9cc9f20SBram Moolenaar #endif 2176f9cc9f20SBram Moolenaar } 2177f9cc9f20SBram Moolenaar ++table->ga_len; 2178f9cc9f20SBram Moolenaar return (table->ga_len - 1 + ATTR_OFF); 2179f9cc9f20SBram Moolenaar } 2180f9cc9f20SBram Moolenaar 2181f9cc9f20SBram Moolenaar #if defined(FEAT_TERMINAL) || defined(PROTO) 2182f9cc9f20SBram Moolenaar /* 2183f9cc9f20SBram Moolenaar * Get an attribute index for a cterm entry. 2184f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed. 2185f9cc9f20SBram Moolenaar */ 2186f9cc9f20SBram Moolenaar int 2187f9cc9f20SBram Moolenaar get_cterm_attr_idx(int attr, int fg, int bg) 2188f9cc9f20SBram Moolenaar { 2189f9cc9f20SBram Moolenaar attrentry_T at_en; 2190f9cc9f20SBram Moolenaar 2191a80faa89SBram Moolenaar CLEAR_FIELD(at_en); 2192f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2193f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = INVALCOLOR; 2194f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = INVALCOLOR; 2195f9cc9f20SBram Moolenaar #endif 2196f9cc9f20SBram Moolenaar at_en.ae_attr = attr; 2197f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_color = fg; 2198f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_color = bg; 2199f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &at_en); 2200f9cc9f20SBram Moolenaar } 2201f9cc9f20SBram Moolenaar #endif 2202f9cc9f20SBram Moolenaar 2203f9cc9f20SBram Moolenaar #if (defined(FEAT_TERMINAL) && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) 2204f9cc9f20SBram Moolenaar /* 2205f9cc9f20SBram Moolenaar * Get an attribute index for a 'termguicolors' entry. 2206f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed. 2207f9cc9f20SBram Moolenaar */ 2208f9cc9f20SBram Moolenaar int 2209f9cc9f20SBram Moolenaar get_tgc_attr_idx(int attr, guicolor_T fg, guicolor_T bg) 2210f9cc9f20SBram Moolenaar { 2211f9cc9f20SBram Moolenaar attrentry_T at_en; 2212f9cc9f20SBram Moolenaar 2213a80faa89SBram Moolenaar CLEAR_FIELD(at_en); 2214f9cc9f20SBram Moolenaar at_en.ae_attr = attr; 2215f9cc9f20SBram Moolenaar if (fg == INVALCOLOR && bg == INVALCOLOR) 2216f9cc9f20SBram Moolenaar { 2217f9cc9f20SBram Moolenaar // If both GUI colors are not set fall back to the cterm colors. Helps 2218f9cc9f20SBram Moolenaar // if the GUI only has an attribute, such as undercurl. 2219f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = CTERMCOLOR; 2220f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = CTERMCOLOR; 2221f9cc9f20SBram Moolenaar } 2222f9cc9f20SBram Moolenaar else 2223f9cc9f20SBram Moolenaar { 2224f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = fg; 2225f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = bg; 2226f9cc9f20SBram Moolenaar } 2227f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &at_en); 2228f9cc9f20SBram Moolenaar } 2229f9cc9f20SBram Moolenaar #endif 2230f9cc9f20SBram Moolenaar 2231f9cc9f20SBram Moolenaar #if (defined(FEAT_TERMINAL) && defined(FEAT_GUI)) || defined(PROTO) 2232f9cc9f20SBram Moolenaar /* 2233f9cc9f20SBram Moolenaar * Get an attribute index for a cterm entry. 2234f9cc9f20SBram Moolenaar * Uses an existing entry when possible or adds one when needed. 2235f9cc9f20SBram Moolenaar */ 2236f9cc9f20SBram Moolenaar int 2237f9cc9f20SBram Moolenaar get_gui_attr_idx(int attr, guicolor_T fg, guicolor_T bg) 2238f9cc9f20SBram Moolenaar { 2239f9cc9f20SBram Moolenaar attrentry_T at_en; 2240f9cc9f20SBram Moolenaar 2241a80faa89SBram Moolenaar CLEAR_FIELD(at_en); 2242f9cc9f20SBram Moolenaar at_en.ae_attr = attr; 2243f9cc9f20SBram Moolenaar at_en.ae_u.gui.fg_color = fg; 2244f9cc9f20SBram Moolenaar at_en.ae_u.gui.bg_color = bg; 2245f9cc9f20SBram Moolenaar return get_attr_entry(&gui_attr_table, &at_en); 2246f9cc9f20SBram Moolenaar } 2247f9cc9f20SBram Moolenaar #endif 2248f9cc9f20SBram Moolenaar 2249f9cc9f20SBram Moolenaar /* 2250f9cc9f20SBram Moolenaar * Clear all highlight tables. 2251f9cc9f20SBram Moolenaar */ 2252f9cc9f20SBram Moolenaar void 2253f9cc9f20SBram Moolenaar clear_hl_tables(void) 2254f9cc9f20SBram Moolenaar { 2255f9cc9f20SBram Moolenaar int i; 2256f9cc9f20SBram Moolenaar attrentry_T *taep; 2257f9cc9f20SBram Moolenaar 2258f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2259f9cc9f20SBram Moolenaar ga_clear(&gui_attr_table); 2260f9cc9f20SBram Moolenaar #endif 2261f9cc9f20SBram Moolenaar for (i = 0; i < term_attr_table.ga_len; ++i) 2262f9cc9f20SBram Moolenaar { 2263f9cc9f20SBram Moolenaar taep = &(((attrentry_T *)term_attr_table.ga_data)[i]); 2264f9cc9f20SBram Moolenaar vim_free(taep->ae_u.term.start); 2265f9cc9f20SBram Moolenaar vim_free(taep->ae_u.term.stop); 2266f9cc9f20SBram Moolenaar } 2267f9cc9f20SBram Moolenaar ga_clear(&term_attr_table); 2268f9cc9f20SBram Moolenaar ga_clear(&cterm_attr_table); 2269f9cc9f20SBram Moolenaar } 2270f9cc9f20SBram Moolenaar 2271f9cc9f20SBram Moolenaar /* 2272f9cc9f20SBram Moolenaar * Combine special attributes (e.g., for spelling) with other attributes 2273f9cc9f20SBram Moolenaar * (e.g., for syntax highlighting). 2274f9cc9f20SBram Moolenaar * "prim_attr" overrules "char_attr". 2275f9cc9f20SBram Moolenaar * This creates a new group when required. 2276f9cc9f20SBram Moolenaar * Since we expect there to be few spelling mistakes we don't cache the 2277f9cc9f20SBram Moolenaar * result. 2278f9cc9f20SBram Moolenaar * Return the resulting attributes. 2279f9cc9f20SBram Moolenaar */ 2280f9cc9f20SBram Moolenaar int 2281f9cc9f20SBram Moolenaar hl_combine_attr(int char_attr, int prim_attr) 2282f9cc9f20SBram Moolenaar { 2283f9cc9f20SBram Moolenaar attrentry_T *char_aep = NULL; 2284f9cc9f20SBram Moolenaar attrentry_T *spell_aep; 2285f9cc9f20SBram Moolenaar attrentry_T new_en; 2286f9cc9f20SBram Moolenaar 2287f9cc9f20SBram Moolenaar if (char_attr == 0) 2288f9cc9f20SBram Moolenaar return prim_attr; 2289f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL && prim_attr <= HL_ALL) 2290f9cc9f20SBram Moolenaar return ATTR_COMBINE(char_attr, prim_attr); 2291f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2292f9cc9f20SBram Moolenaar if (gui.in_use) 2293f9cc9f20SBram Moolenaar { 2294f9cc9f20SBram Moolenaar if (char_attr > HL_ALL) 2295f9cc9f20SBram Moolenaar char_aep = syn_gui_attr2entry(char_attr); 2296f9cc9f20SBram Moolenaar if (char_aep != NULL) 2297f9cc9f20SBram Moolenaar new_en = *char_aep; 2298f9cc9f20SBram Moolenaar else 2299f9cc9f20SBram Moolenaar { 2300a80faa89SBram Moolenaar CLEAR_FIELD(new_en); 2301f9cc9f20SBram Moolenaar new_en.ae_u.gui.fg_color = INVALCOLOR; 2302f9cc9f20SBram Moolenaar new_en.ae_u.gui.bg_color = INVALCOLOR; 2303f9cc9f20SBram Moolenaar new_en.ae_u.gui.sp_color = INVALCOLOR; 2304f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL) 2305f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr; 2306f9cc9f20SBram Moolenaar } 2307f9cc9f20SBram Moolenaar 2308f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL) 2309f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); 2310f9cc9f20SBram Moolenaar else 2311f9cc9f20SBram Moolenaar { 2312f9cc9f20SBram Moolenaar spell_aep = syn_gui_attr2entry(prim_attr); 2313f9cc9f20SBram Moolenaar if (spell_aep != NULL) 2314f9cc9f20SBram Moolenaar { 2315f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, 2316f9cc9f20SBram Moolenaar spell_aep->ae_attr); 2317f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.fg_color != INVALCOLOR) 2318f9cc9f20SBram Moolenaar new_en.ae_u.gui.fg_color = spell_aep->ae_u.gui.fg_color; 2319f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.bg_color != INVALCOLOR) 2320f9cc9f20SBram Moolenaar new_en.ae_u.gui.bg_color = spell_aep->ae_u.gui.bg_color; 2321f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.sp_color != INVALCOLOR) 2322f9cc9f20SBram Moolenaar new_en.ae_u.gui.sp_color = spell_aep->ae_u.gui.sp_color; 2323f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.font != NOFONT) 2324f9cc9f20SBram Moolenaar new_en.ae_u.gui.font = spell_aep->ae_u.gui.font; 2325f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2326f9cc9f20SBram Moolenaar if (spell_aep->ae_u.gui.fontset != NOFONTSET) 2327f9cc9f20SBram Moolenaar new_en.ae_u.gui.fontset = spell_aep->ae_u.gui.fontset; 2328f9cc9f20SBram Moolenaar # endif 2329f9cc9f20SBram Moolenaar } 2330f9cc9f20SBram Moolenaar } 2331f9cc9f20SBram Moolenaar return get_attr_entry(&gui_attr_table, &new_en); 2332f9cc9f20SBram Moolenaar } 2333f9cc9f20SBram Moolenaar #endif 2334f9cc9f20SBram Moolenaar 2335f9cc9f20SBram Moolenaar if (IS_CTERM) 2336f9cc9f20SBram Moolenaar { 2337f9cc9f20SBram Moolenaar if (char_attr > HL_ALL) 2338f9cc9f20SBram Moolenaar char_aep = syn_cterm_attr2entry(char_attr); 2339f9cc9f20SBram Moolenaar if (char_aep != NULL) 2340f9cc9f20SBram Moolenaar new_en = *char_aep; 2341f9cc9f20SBram Moolenaar else 2342f9cc9f20SBram Moolenaar { 2343a80faa89SBram Moolenaar CLEAR_FIELD(new_en); 2344f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2345f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = INVALCOLOR; 2346f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = INVALCOLOR; 2347f9cc9f20SBram Moolenaar #endif 2348f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL) 2349f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr; 2350f9cc9f20SBram Moolenaar } 2351f9cc9f20SBram Moolenaar 2352f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL) 2353f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); 2354f9cc9f20SBram Moolenaar else 2355f9cc9f20SBram Moolenaar { 2356f9cc9f20SBram Moolenaar spell_aep = syn_cterm_attr2entry(prim_attr); 2357f9cc9f20SBram Moolenaar if (spell_aep != NULL) 2358f9cc9f20SBram Moolenaar { 2359f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, 2360f9cc9f20SBram Moolenaar spell_aep->ae_attr); 2361f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_color > 0) 2362f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_color = spell_aep->ae_u.cterm.fg_color; 2363f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_color > 0) 2364f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_color = spell_aep->ae_u.cterm.bg_color; 2365f9cc9f20SBram Moolenaar #ifdef FEAT_TERMGUICOLORS 2366f9cc9f20SBram Moolenaar // If both fg and bg are not set fall back to cterm colors. 2367f9cc9f20SBram Moolenaar // Helps for SpellBad which uses undercurl in the GUI. 2368f9cc9f20SBram Moolenaar if (COLOR_INVALID(spell_aep->ae_u.cterm.fg_rgb) 2369f9cc9f20SBram Moolenaar && COLOR_INVALID(spell_aep->ae_u.cterm.bg_rgb)) 2370f9cc9f20SBram Moolenaar { 2371f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_color > 0) 2372f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = CTERMCOLOR; 2373f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_color > 0) 2374f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = CTERMCOLOR; 2375f9cc9f20SBram Moolenaar } 2376f9cc9f20SBram Moolenaar else 2377f9cc9f20SBram Moolenaar { 2378f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.fg_rgb != INVALCOLOR) 2379f9cc9f20SBram Moolenaar new_en.ae_u.cterm.fg_rgb = spell_aep->ae_u.cterm.fg_rgb; 2380f9cc9f20SBram Moolenaar if (spell_aep->ae_u.cterm.bg_rgb != INVALCOLOR) 2381f9cc9f20SBram Moolenaar new_en.ae_u.cterm.bg_rgb = spell_aep->ae_u.cterm.bg_rgb; 2382f9cc9f20SBram Moolenaar } 2383f9cc9f20SBram Moolenaar #endif 2384f9cc9f20SBram Moolenaar } 2385f9cc9f20SBram Moolenaar } 2386f9cc9f20SBram Moolenaar return get_attr_entry(&cterm_attr_table, &new_en); 2387f9cc9f20SBram Moolenaar } 2388f9cc9f20SBram Moolenaar 2389f9cc9f20SBram Moolenaar if (char_attr > HL_ALL) 2390f9cc9f20SBram Moolenaar char_aep = syn_term_attr2entry(char_attr); 2391f9cc9f20SBram Moolenaar if (char_aep != NULL) 2392f9cc9f20SBram Moolenaar new_en = *char_aep; 2393f9cc9f20SBram Moolenaar else 2394f9cc9f20SBram Moolenaar { 2395a80faa89SBram Moolenaar CLEAR_FIELD(new_en); 2396f9cc9f20SBram Moolenaar if (char_attr <= HL_ALL) 2397f9cc9f20SBram Moolenaar new_en.ae_attr = char_attr; 2398f9cc9f20SBram Moolenaar } 2399f9cc9f20SBram Moolenaar 2400f9cc9f20SBram Moolenaar if (prim_attr <= HL_ALL) 2401f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, prim_attr); 2402f9cc9f20SBram Moolenaar else 2403f9cc9f20SBram Moolenaar { 2404f9cc9f20SBram Moolenaar spell_aep = syn_term_attr2entry(prim_attr); 2405f9cc9f20SBram Moolenaar if (spell_aep != NULL) 2406f9cc9f20SBram Moolenaar { 2407f9cc9f20SBram Moolenaar new_en.ae_attr = ATTR_COMBINE(new_en.ae_attr, spell_aep->ae_attr); 2408f9cc9f20SBram Moolenaar if (spell_aep->ae_u.term.start != NULL) 2409f9cc9f20SBram Moolenaar { 2410f9cc9f20SBram Moolenaar new_en.ae_u.term.start = spell_aep->ae_u.term.start; 2411f9cc9f20SBram Moolenaar new_en.ae_u.term.stop = spell_aep->ae_u.term.stop; 2412f9cc9f20SBram Moolenaar } 2413f9cc9f20SBram Moolenaar } 2414f9cc9f20SBram Moolenaar } 2415f9cc9f20SBram Moolenaar return get_attr_entry(&term_attr_table, &new_en); 2416f9cc9f20SBram Moolenaar } 2417f9cc9f20SBram Moolenaar 2418f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2419f9cc9f20SBram Moolenaar attrentry_T * 2420f9cc9f20SBram Moolenaar syn_gui_attr2entry(int attr) 2421f9cc9f20SBram Moolenaar { 2422f9cc9f20SBram Moolenaar attr -= ATTR_OFF; 2423f9cc9f20SBram Moolenaar if (attr >= gui_attr_table.ga_len) // did ":syntax clear" 2424f9cc9f20SBram Moolenaar return NULL; 2425f9cc9f20SBram Moolenaar return &(GUI_ATTR_ENTRY(attr)); 2426f9cc9f20SBram Moolenaar } 2427f9cc9f20SBram Moolenaar #endif 2428f9cc9f20SBram Moolenaar 2429f9cc9f20SBram Moolenaar /* 2430f9cc9f20SBram Moolenaar * Get the highlight attributes (HL_BOLD etc.) from an attribute nr. 2431f9cc9f20SBram Moolenaar * Only to be used when "attr" > HL_ALL. 2432f9cc9f20SBram Moolenaar */ 2433f9cc9f20SBram Moolenaar int 2434f9cc9f20SBram Moolenaar syn_attr2attr(int attr) 2435f9cc9f20SBram Moolenaar { 2436f9cc9f20SBram Moolenaar attrentry_T *aep; 2437f9cc9f20SBram Moolenaar 2438f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2439f9cc9f20SBram Moolenaar if (gui.in_use) 2440f9cc9f20SBram Moolenaar aep = syn_gui_attr2entry(attr); 2441f9cc9f20SBram Moolenaar else 2442f9cc9f20SBram Moolenaar #endif 2443f9cc9f20SBram Moolenaar if (IS_CTERM) 2444f9cc9f20SBram Moolenaar aep = syn_cterm_attr2entry(attr); 2445f9cc9f20SBram Moolenaar else 2446f9cc9f20SBram Moolenaar aep = syn_term_attr2entry(attr); 2447f9cc9f20SBram Moolenaar 2448f9cc9f20SBram Moolenaar if (aep == NULL) // highlighting not set 2449f9cc9f20SBram Moolenaar return 0; 2450f9cc9f20SBram Moolenaar return aep->ae_attr; 2451f9cc9f20SBram Moolenaar } 2452f9cc9f20SBram Moolenaar 2453f9cc9f20SBram Moolenaar 2454f9cc9f20SBram Moolenaar attrentry_T * 2455f9cc9f20SBram Moolenaar syn_term_attr2entry(int attr) 2456f9cc9f20SBram Moolenaar { 2457f9cc9f20SBram Moolenaar attr -= ATTR_OFF; 2458f9cc9f20SBram Moolenaar if (attr >= term_attr_table.ga_len) // did ":syntax clear" 2459f9cc9f20SBram Moolenaar return NULL; 2460f9cc9f20SBram Moolenaar return &(TERM_ATTR_ENTRY(attr)); 2461f9cc9f20SBram Moolenaar } 2462f9cc9f20SBram Moolenaar 2463f9cc9f20SBram Moolenaar attrentry_T * 2464f9cc9f20SBram Moolenaar syn_cterm_attr2entry(int attr) 2465f9cc9f20SBram Moolenaar { 2466f9cc9f20SBram Moolenaar attr -= ATTR_OFF; 2467f9cc9f20SBram Moolenaar if (attr >= cterm_attr_table.ga_len) // did ":syntax clear" 2468f9cc9f20SBram Moolenaar return NULL; 2469f9cc9f20SBram Moolenaar return &(CTERM_ATTR_ENTRY(attr)); 2470f9cc9f20SBram Moolenaar } 2471f9cc9f20SBram Moolenaar 2472f9cc9f20SBram Moolenaar #define LIST_ATTR 1 2473f9cc9f20SBram Moolenaar #define LIST_STRING 2 2474f9cc9f20SBram Moolenaar #define LIST_INT 3 2475f9cc9f20SBram Moolenaar 2476f9cc9f20SBram Moolenaar static void 2477f9cc9f20SBram Moolenaar highlight_list_one(int id) 2478f9cc9f20SBram Moolenaar { 2479f9cc9f20SBram Moolenaar hl_group_T *sgp; 2480f9cc9f20SBram Moolenaar int didh = FALSE; 2481f9cc9f20SBram Moolenaar 2482f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[id - 1]; // index is ID minus one 2483f9cc9f20SBram Moolenaar 2484f9cc9f20SBram Moolenaar if (message_filtered(sgp->sg_name)) 2485f9cc9f20SBram Moolenaar return; 2486f9cc9f20SBram Moolenaar 2487f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR, 2488f9cc9f20SBram Moolenaar sgp->sg_term, NULL, "term"); 2489f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2490f9cc9f20SBram Moolenaar 0, sgp->sg_start, "start"); 2491f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2492f9cc9f20SBram Moolenaar 0, sgp->sg_stop, "stop"); 2493f9cc9f20SBram Moolenaar 2494f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR, 2495f9cc9f20SBram Moolenaar sgp->sg_cterm, NULL, "cterm"); 2496f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_INT, 2497f9cc9f20SBram Moolenaar sgp->sg_cterm_fg, NULL, "ctermfg"); 2498f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_INT, 2499f9cc9f20SBram Moolenaar sgp->sg_cterm_bg, NULL, "ctermbg"); 2500f9cc9f20SBram Moolenaar 2501f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 2502f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_ATTR, 2503f9cc9f20SBram Moolenaar sgp->sg_gui, NULL, "gui"); 2504f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2505f9cc9f20SBram Moolenaar 0, sgp->sg_gui_fg_name, "guifg"); 2506f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2507f9cc9f20SBram Moolenaar 0, sgp->sg_gui_bg_name, "guibg"); 2508f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2509f9cc9f20SBram Moolenaar 0, sgp->sg_gui_sp_name, "guisp"); 2510f9cc9f20SBram Moolenaar #endif 2511f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2512f9cc9f20SBram Moolenaar didh = highlight_list_arg(id, didh, LIST_STRING, 2513f9cc9f20SBram Moolenaar 0, sgp->sg_font_name, "font"); 2514f9cc9f20SBram Moolenaar #endif 2515f9cc9f20SBram Moolenaar 2516f9cc9f20SBram Moolenaar if (sgp->sg_link && !got_int) 2517f9cc9f20SBram Moolenaar { 2518f9cc9f20SBram Moolenaar (void)syn_list_header(didh, 9999, id); 2519f9cc9f20SBram Moolenaar didh = TRUE; 2520f9cc9f20SBram Moolenaar msg_puts_attr("links to", HL_ATTR(HLF_D)); 2521f9cc9f20SBram Moolenaar msg_putchar(' '); 2522f9cc9f20SBram Moolenaar msg_outtrans(HL_TABLE()[HL_TABLE()[id - 1].sg_link - 1].sg_name); 2523f9cc9f20SBram Moolenaar } 2524f9cc9f20SBram Moolenaar 2525f9cc9f20SBram Moolenaar if (!didh) 2526f9cc9f20SBram Moolenaar highlight_list_arg(id, didh, LIST_STRING, 0, (char_u *)"cleared", ""); 2527f9cc9f20SBram Moolenaar #ifdef FEAT_EVAL 2528f9cc9f20SBram Moolenaar if (p_verbose > 0) 2529f9cc9f20SBram Moolenaar last_set_msg(sgp->sg_script_ctx); 2530f9cc9f20SBram Moolenaar #endif 2531f9cc9f20SBram Moolenaar } 2532f9cc9f20SBram Moolenaar 2533f9cc9f20SBram Moolenaar static int 2534f9cc9f20SBram Moolenaar highlight_list_arg( 2535f9cc9f20SBram Moolenaar int id, 2536f9cc9f20SBram Moolenaar int didh, 2537f9cc9f20SBram Moolenaar int type, 2538f9cc9f20SBram Moolenaar int iarg, 2539f9cc9f20SBram Moolenaar char_u *sarg, 2540f9cc9f20SBram Moolenaar char *name) 2541f9cc9f20SBram Moolenaar { 2542f9cc9f20SBram Moolenaar char_u buf[100]; 2543f9cc9f20SBram Moolenaar char_u *ts; 2544f9cc9f20SBram Moolenaar int i; 2545f9cc9f20SBram Moolenaar 2546f9cc9f20SBram Moolenaar if (got_int) 2547f9cc9f20SBram Moolenaar return FALSE; 2548f9cc9f20SBram Moolenaar if (type == LIST_STRING ? (sarg != NULL) : (iarg != 0)) 2549f9cc9f20SBram Moolenaar { 2550f9cc9f20SBram Moolenaar ts = buf; 2551f9cc9f20SBram Moolenaar if (type == LIST_INT) 2552f9cc9f20SBram Moolenaar sprintf((char *)buf, "%d", iarg - 1); 2553f9cc9f20SBram Moolenaar else if (type == LIST_STRING) 2554f9cc9f20SBram Moolenaar ts = sarg; 2555f9cc9f20SBram Moolenaar else // type == LIST_ATTR 2556f9cc9f20SBram Moolenaar { 2557f9cc9f20SBram Moolenaar buf[0] = NUL; 2558f9cc9f20SBram Moolenaar for (i = 0; hl_attr_table[i] != 0; ++i) 2559f9cc9f20SBram Moolenaar { 2560f9cc9f20SBram Moolenaar if (iarg & hl_attr_table[i]) 2561f9cc9f20SBram Moolenaar { 2562f9cc9f20SBram Moolenaar if (buf[0] != NUL) 2563f9cc9f20SBram Moolenaar vim_strcat(buf, (char_u *)",", 100); 2564f9cc9f20SBram Moolenaar vim_strcat(buf, (char_u *)hl_name_table[i], 100); 2565f9cc9f20SBram Moolenaar iarg &= ~hl_attr_table[i]; // don't want "inverse" 2566f9cc9f20SBram Moolenaar } 2567f9cc9f20SBram Moolenaar } 2568f9cc9f20SBram Moolenaar } 2569f9cc9f20SBram Moolenaar 2570f9cc9f20SBram Moolenaar (void)syn_list_header(didh, 2571f9cc9f20SBram Moolenaar (int)(vim_strsize(ts) + STRLEN(name) + 1), id); 2572f9cc9f20SBram Moolenaar didh = TRUE; 2573f9cc9f20SBram Moolenaar if (!got_int) 2574f9cc9f20SBram Moolenaar { 2575f9cc9f20SBram Moolenaar if (*name != NUL) 2576f9cc9f20SBram Moolenaar { 2577f9cc9f20SBram Moolenaar msg_puts_attr(name, HL_ATTR(HLF_D)); 2578f9cc9f20SBram Moolenaar msg_puts_attr("=", HL_ATTR(HLF_D)); 2579f9cc9f20SBram Moolenaar } 2580f9cc9f20SBram Moolenaar msg_outtrans(ts); 2581f9cc9f20SBram Moolenaar } 2582f9cc9f20SBram Moolenaar } 2583f9cc9f20SBram Moolenaar return didh; 2584f9cc9f20SBram Moolenaar } 2585f9cc9f20SBram Moolenaar 2586f9cc9f20SBram Moolenaar #if (((defined(FEAT_EVAL) || defined(FEAT_PRINTER))) && defined(FEAT_SYN_HL)) || defined(PROTO) 2587f9cc9f20SBram Moolenaar /* 2588f9cc9f20SBram Moolenaar * Return "1" if highlight group "id" has attribute "flag". 2589f9cc9f20SBram Moolenaar * Return NULL otherwise. 2590f9cc9f20SBram Moolenaar */ 2591f9cc9f20SBram Moolenaar char_u * 2592f9cc9f20SBram Moolenaar highlight_has_attr( 2593f9cc9f20SBram Moolenaar int id, 2594f9cc9f20SBram Moolenaar int flag, 2595f9cc9f20SBram Moolenaar int modec) // 'g' for GUI, 'c' for cterm, 't' for term 2596f9cc9f20SBram Moolenaar { 2597f9cc9f20SBram Moolenaar int attr; 2598f9cc9f20SBram Moolenaar 2599f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len) 2600f9cc9f20SBram Moolenaar return NULL; 2601f9cc9f20SBram Moolenaar 2602f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_EVAL) 2603f9cc9f20SBram Moolenaar if (modec == 'g') 2604f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_gui; 2605f9cc9f20SBram Moolenaar else 2606f9cc9f20SBram Moolenaar #endif 2607f9cc9f20SBram Moolenaar if (modec == 'c') 2608f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_cterm; 2609f9cc9f20SBram Moolenaar else 2610f9cc9f20SBram Moolenaar attr = HL_TABLE()[id - 1].sg_term; 2611f9cc9f20SBram Moolenaar 2612f9cc9f20SBram Moolenaar if (attr & flag) 2613f9cc9f20SBram Moolenaar return (char_u *)"1"; 2614f9cc9f20SBram Moolenaar return NULL; 2615f9cc9f20SBram Moolenaar } 2616f9cc9f20SBram Moolenaar #endif 2617f9cc9f20SBram Moolenaar 2618f9cc9f20SBram Moolenaar #if (defined(FEAT_SYN_HL) && defined(FEAT_EVAL)) || defined(PROTO) 2619f9cc9f20SBram Moolenaar /* 2620f9cc9f20SBram Moolenaar * Return color name of highlight group "id". 2621f9cc9f20SBram Moolenaar */ 2622f9cc9f20SBram Moolenaar char_u * 2623f9cc9f20SBram Moolenaar highlight_color( 2624f9cc9f20SBram Moolenaar int id, 2625f9cc9f20SBram Moolenaar char_u *what, // "font", "fg", "bg", "sp", "fg#", "bg#" or "sp#" 2626f9cc9f20SBram Moolenaar int modec) // 'g' for GUI, 'c' for cterm, 't' for term 2627f9cc9f20SBram Moolenaar { 2628f9cc9f20SBram Moolenaar static char_u name[20]; 2629f9cc9f20SBram Moolenaar int n; 2630f9cc9f20SBram Moolenaar int fg = FALSE; 2631f9cc9f20SBram Moolenaar int sp = FALSE; 2632f9cc9f20SBram Moolenaar int font = FALSE; 2633f9cc9f20SBram Moolenaar 2634f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len) 2635f9cc9f20SBram Moolenaar return NULL; 2636f9cc9f20SBram Moolenaar 2637f9cc9f20SBram Moolenaar if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'g') 2638f9cc9f20SBram Moolenaar fg = TRUE; 2639f9cc9f20SBram Moolenaar else if (TOLOWER_ASC(what[0]) == 'f' && TOLOWER_ASC(what[1]) == 'o' 2640f9cc9f20SBram Moolenaar && TOLOWER_ASC(what[2]) == 'n' && TOLOWER_ASC(what[3]) == 't') 2641f9cc9f20SBram Moolenaar font = TRUE; 2642f9cc9f20SBram Moolenaar else if (TOLOWER_ASC(what[0]) == 's' && TOLOWER_ASC(what[1]) == 'p') 2643f9cc9f20SBram Moolenaar sp = TRUE; 2644f9cc9f20SBram Moolenaar else if (!(TOLOWER_ASC(what[0]) == 'b' && TOLOWER_ASC(what[1]) == 'g')) 2645f9cc9f20SBram Moolenaar return NULL; 2646f9cc9f20SBram Moolenaar if (modec == 'g') 2647f9cc9f20SBram Moolenaar { 2648f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 2649f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 2650f9cc9f20SBram Moolenaar // return font name 2651f9cc9f20SBram Moolenaar if (font) 2652f9cc9f20SBram Moolenaar return HL_TABLE()[id - 1].sg_font_name; 2653f9cc9f20SBram Moolenaar # endif 2654f9cc9f20SBram Moolenaar 2655f9cc9f20SBram Moolenaar // return #RRGGBB form (only possible when GUI is running) 2656f9cc9f20SBram Moolenaar if ((USE_24BIT) && what[2] == '#') 2657f9cc9f20SBram Moolenaar { 2658f9cc9f20SBram Moolenaar guicolor_T color; 2659f9cc9f20SBram Moolenaar long_u rgb; 2660f9cc9f20SBram Moolenaar static char_u buf[10]; 2661f9cc9f20SBram Moolenaar 2662f9cc9f20SBram Moolenaar if (fg) 2663f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_fg; 2664f9cc9f20SBram Moolenaar else if (sp) 2665f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 2666f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_sp; 2667f9cc9f20SBram Moolenaar # else 2668f9cc9f20SBram Moolenaar color = INVALCOLOR; 2669f9cc9f20SBram Moolenaar # endif 2670f9cc9f20SBram Moolenaar else 2671f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_bg; 2672f9cc9f20SBram Moolenaar if (color == INVALCOLOR) 2673f9cc9f20SBram Moolenaar return NULL; 2674f9cc9f20SBram Moolenaar rgb = (long_u)GUI_MCH_GET_RGB(color); 2675f9cc9f20SBram Moolenaar sprintf((char *)buf, "#%02x%02x%02x", 2676f9cc9f20SBram Moolenaar (unsigned)(rgb >> 16), 2677f9cc9f20SBram Moolenaar (unsigned)(rgb >> 8) & 255, 2678f9cc9f20SBram Moolenaar (unsigned)rgb & 255); 2679f9cc9f20SBram Moolenaar return buf; 2680f9cc9f20SBram Moolenaar } 2681f9cc9f20SBram Moolenaar # endif 2682f9cc9f20SBram Moolenaar if (fg) 2683f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_fg_name); 2684f9cc9f20SBram Moolenaar if (sp) 2685f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_sp_name); 2686f9cc9f20SBram Moolenaar return (HL_TABLE()[id - 1].sg_gui_bg_name); 2687f9cc9f20SBram Moolenaar } 2688f9cc9f20SBram Moolenaar if (font || sp) 2689f9cc9f20SBram Moolenaar return NULL; 2690f9cc9f20SBram Moolenaar if (modec == 'c') 2691f9cc9f20SBram Moolenaar { 2692f9cc9f20SBram Moolenaar if (fg) 2693f9cc9f20SBram Moolenaar n = HL_TABLE()[id - 1].sg_cterm_fg - 1; 2694f9cc9f20SBram Moolenaar else 2695f9cc9f20SBram Moolenaar n = HL_TABLE()[id - 1].sg_cterm_bg - 1; 2696f9cc9f20SBram Moolenaar if (n < 0) 2697f9cc9f20SBram Moolenaar return NULL; 2698f9cc9f20SBram Moolenaar sprintf((char *)name, "%d", n); 2699f9cc9f20SBram Moolenaar return name; 2700f9cc9f20SBram Moolenaar } 2701f9cc9f20SBram Moolenaar // term doesn't have color 2702f9cc9f20SBram Moolenaar return NULL; 2703f9cc9f20SBram Moolenaar } 2704f9cc9f20SBram Moolenaar #endif 2705f9cc9f20SBram Moolenaar 2706f9cc9f20SBram Moolenaar #if (defined(FEAT_SYN_HL) \ 2707f9cc9f20SBram Moolenaar && (defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)) \ 2708f9cc9f20SBram Moolenaar && defined(FEAT_PRINTER)) || defined(PROTO) 2709f9cc9f20SBram Moolenaar /* 2710f9cc9f20SBram Moolenaar * Return color name of highlight group "id" as RGB value. 2711f9cc9f20SBram Moolenaar */ 2712f9cc9f20SBram Moolenaar long_u 2713f9cc9f20SBram Moolenaar highlight_gui_color_rgb( 2714f9cc9f20SBram Moolenaar int id, 2715f9cc9f20SBram Moolenaar int fg) // TRUE = fg, FALSE = bg 2716f9cc9f20SBram Moolenaar { 2717f9cc9f20SBram Moolenaar guicolor_T color; 2718f9cc9f20SBram Moolenaar 2719f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len) 2720f9cc9f20SBram Moolenaar return 0L; 2721f9cc9f20SBram Moolenaar 2722f9cc9f20SBram Moolenaar if (fg) 2723f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_fg; 2724f9cc9f20SBram Moolenaar else 2725f9cc9f20SBram Moolenaar color = HL_TABLE()[id - 1].sg_gui_bg; 2726f9cc9f20SBram Moolenaar 2727f9cc9f20SBram Moolenaar if (color == INVALCOLOR) 2728f9cc9f20SBram Moolenaar return 0L; 2729f9cc9f20SBram Moolenaar 2730f9cc9f20SBram Moolenaar return GUI_MCH_GET_RGB(color); 2731f9cc9f20SBram Moolenaar } 2732f9cc9f20SBram Moolenaar #endif 2733f9cc9f20SBram Moolenaar 2734f9cc9f20SBram Moolenaar /* 2735f9cc9f20SBram Moolenaar * Output the syntax list header. 2736f9cc9f20SBram Moolenaar * Return TRUE when started a new line. 2737f9cc9f20SBram Moolenaar */ 2738f9cc9f20SBram Moolenaar int 2739f9cc9f20SBram Moolenaar syn_list_header( 2740f9cc9f20SBram Moolenaar int did_header, // did header already 2741f9cc9f20SBram Moolenaar int outlen, // length of string that comes 2742f9cc9f20SBram Moolenaar int id) // highlight group id 2743f9cc9f20SBram Moolenaar { 2744f9cc9f20SBram Moolenaar int endcol = 19; 2745f9cc9f20SBram Moolenaar int newline = TRUE; 2746f9cc9f20SBram Moolenaar int name_col = 0; 2747f9cc9f20SBram Moolenaar 2748f9cc9f20SBram Moolenaar if (!did_header) 2749f9cc9f20SBram Moolenaar { 2750f9cc9f20SBram Moolenaar msg_putchar('\n'); 2751f9cc9f20SBram Moolenaar if (got_int) 2752f9cc9f20SBram Moolenaar return TRUE; 2753f9cc9f20SBram Moolenaar msg_outtrans(HL_TABLE()[id - 1].sg_name); 2754f9cc9f20SBram Moolenaar name_col = msg_col; 2755f9cc9f20SBram Moolenaar endcol = 15; 2756f9cc9f20SBram Moolenaar } 2757f9cc9f20SBram Moolenaar else if (msg_col + outlen + 1 >= Columns) 2758f9cc9f20SBram Moolenaar { 2759f9cc9f20SBram Moolenaar msg_putchar('\n'); 2760f9cc9f20SBram Moolenaar if (got_int) 2761f9cc9f20SBram Moolenaar return TRUE; 2762f9cc9f20SBram Moolenaar } 2763f9cc9f20SBram Moolenaar else 2764f9cc9f20SBram Moolenaar { 2765f9cc9f20SBram Moolenaar if (msg_col >= endcol) // wrap around is like starting a new line 2766f9cc9f20SBram Moolenaar newline = FALSE; 2767f9cc9f20SBram Moolenaar } 2768f9cc9f20SBram Moolenaar 2769f9cc9f20SBram Moolenaar if (msg_col >= endcol) // output at least one space 2770f9cc9f20SBram Moolenaar endcol = msg_col + 1; 2771f9cc9f20SBram Moolenaar if (Columns <= endcol) // avoid hang for tiny window 2772f9cc9f20SBram Moolenaar endcol = Columns - 1; 2773f9cc9f20SBram Moolenaar 2774f9cc9f20SBram Moolenaar msg_advance(endcol); 2775f9cc9f20SBram Moolenaar 2776f9cc9f20SBram Moolenaar // Show "xxx" with the attributes. 2777f9cc9f20SBram Moolenaar if (!did_header) 2778f9cc9f20SBram Moolenaar { 2779f9cc9f20SBram Moolenaar if (endcol == Columns - 1 && endcol <= name_col) 2780f9cc9f20SBram Moolenaar msg_putchar(' '); 2781f9cc9f20SBram Moolenaar msg_puts_attr("xxx", syn_id2attr(id)); 2782f9cc9f20SBram Moolenaar msg_putchar(' '); 2783f9cc9f20SBram Moolenaar } 2784f9cc9f20SBram Moolenaar 2785f9cc9f20SBram Moolenaar return newline; 2786f9cc9f20SBram Moolenaar } 2787f9cc9f20SBram Moolenaar 2788f9cc9f20SBram Moolenaar /* 2789f9cc9f20SBram Moolenaar * Set the attribute numbers for a highlight group. 2790f9cc9f20SBram Moolenaar * Called after one of the attributes has changed. 2791f9cc9f20SBram Moolenaar */ 2792f9cc9f20SBram Moolenaar static void 2793f9cc9f20SBram Moolenaar set_hl_attr( 2794f9cc9f20SBram Moolenaar int idx) // index in array 2795f9cc9f20SBram Moolenaar { 2796f9cc9f20SBram Moolenaar attrentry_T at_en; 2797f9cc9f20SBram Moolenaar hl_group_T *sgp = HL_TABLE() + idx; 2798f9cc9f20SBram Moolenaar 2799f9cc9f20SBram Moolenaar // The "Normal" group doesn't need an attribute number 2800f9cc9f20SBram Moolenaar if (sgp->sg_name_u != NULL && STRCMP(sgp->sg_name_u, "NORMAL") == 0) 2801f9cc9f20SBram Moolenaar return; 2802f9cc9f20SBram Moolenaar 2803f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 2804f9cc9f20SBram Moolenaar /* 2805f9cc9f20SBram Moolenaar * For the GUI mode: If there are other than "normal" highlighting 2806f9cc9f20SBram Moolenaar * attributes, need to allocate an attr number. 2807f9cc9f20SBram Moolenaar */ 2808f9cc9f20SBram Moolenaar if (sgp->sg_gui_fg == INVALCOLOR 2809f9cc9f20SBram Moolenaar && sgp->sg_gui_bg == INVALCOLOR 2810f9cc9f20SBram Moolenaar && sgp->sg_gui_sp == INVALCOLOR 2811f9cc9f20SBram Moolenaar && sgp->sg_font == NOFONT 2812f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2813f9cc9f20SBram Moolenaar && sgp->sg_fontset == NOFONTSET 2814f9cc9f20SBram Moolenaar # endif 2815f9cc9f20SBram Moolenaar ) 2816f9cc9f20SBram Moolenaar { 2817f9cc9f20SBram Moolenaar sgp->sg_gui_attr = sgp->sg_gui; 2818f9cc9f20SBram Moolenaar } 2819f9cc9f20SBram Moolenaar else 2820f9cc9f20SBram Moolenaar { 2821f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_gui; 2822f9cc9f20SBram Moolenaar at_en.ae_u.gui.fg_color = sgp->sg_gui_fg; 2823f9cc9f20SBram Moolenaar at_en.ae_u.gui.bg_color = sgp->sg_gui_bg; 2824f9cc9f20SBram Moolenaar at_en.ae_u.gui.sp_color = sgp->sg_gui_sp; 2825f9cc9f20SBram Moolenaar at_en.ae_u.gui.font = sgp->sg_font; 2826f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 2827f9cc9f20SBram Moolenaar at_en.ae_u.gui.fontset = sgp->sg_fontset; 2828f9cc9f20SBram Moolenaar # endif 2829f9cc9f20SBram Moolenaar sgp->sg_gui_attr = get_attr_entry(&gui_attr_table, &at_en); 2830f9cc9f20SBram Moolenaar } 2831f9cc9f20SBram Moolenaar #endif 2832f9cc9f20SBram Moolenaar /* 2833f9cc9f20SBram Moolenaar * For the term mode: If there are other than "normal" highlighting 2834f9cc9f20SBram Moolenaar * attributes, need to allocate an attr number. 2835f9cc9f20SBram Moolenaar */ 2836f9cc9f20SBram Moolenaar if (sgp->sg_start == NULL && sgp->sg_stop == NULL) 2837f9cc9f20SBram Moolenaar sgp->sg_term_attr = sgp->sg_term; 2838f9cc9f20SBram Moolenaar else 2839f9cc9f20SBram Moolenaar { 2840f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_term; 2841f9cc9f20SBram Moolenaar at_en.ae_u.term.start = sgp->sg_start; 2842f9cc9f20SBram Moolenaar at_en.ae_u.term.stop = sgp->sg_stop; 2843f9cc9f20SBram Moolenaar sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en); 2844f9cc9f20SBram Moolenaar } 2845f9cc9f20SBram Moolenaar 2846f9cc9f20SBram Moolenaar /* 2847f9cc9f20SBram Moolenaar * For the color term mode: If there are other than "normal" 2848f9cc9f20SBram Moolenaar * highlighting attributes, need to allocate an attr number. 2849f9cc9f20SBram Moolenaar */ 2850f9cc9f20SBram Moolenaar if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 2851f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 2852f9cc9f20SBram Moolenaar && sgp->sg_gui_fg == INVALCOLOR 2853f9cc9f20SBram Moolenaar && sgp->sg_gui_bg == INVALCOLOR 2854f9cc9f20SBram Moolenaar # endif 2855f9cc9f20SBram Moolenaar ) 2856f9cc9f20SBram Moolenaar sgp->sg_cterm_attr = sgp->sg_cterm; 2857f9cc9f20SBram Moolenaar else 2858f9cc9f20SBram Moolenaar { 2859f9cc9f20SBram Moolenaar at_en.ae_attr = sgp->sg_cterm; 2860f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_color = sgp->sg_cterm_fg; 2861f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_color = sgp->sg_cterm_bg; 2862f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 2863f9cc9f20SBram Moolenaar # ifdef MSWIN 2864f9cc9f20SBram Moolenaar # ifdef VIMDLL 2865f9cc9f20SBram Moolenaar // Only when not using the GUI. 2866f9cc9f20SBram Moolenaar if (!gui.in_use && !gui.starting) 2867f9cc9f20SBram Moolenaar # endif 2868f9cc9f20SBram Moolenaar { 2869f9cc9f20SBram Moolenaar int id; 2870f9cc9f20SBram Moolenaar guicolor_T fg, bg; 2871f9cc9f20SBram Moolenaar 2872f9cc9f20SBram Moolenaar id = syn_name2id((char_u *)"Normal"); 2873f9cc9f20SBram Moolenaar if (id > 0) 2874f9cc9f20SBram Moolenaar { 2875f9cc9f20SBram Moolenaar syn_id2colors(id, &fg, &bg); 2876f9cc9f20SBram Moolenaar if (sgp->sg_gui_fg == INVALCOLOR) 2877f9cc9f20SBram Moolenaar sgp->sg_gui_fg = fg; 2878f9cc9f20SBram Moolenaar if (sgp->sg_gui_bg == INVALCOLOR) 2879f9cc9f20SBram Moolenaar sgp->sg_gui_bg = bg; 2880f9cc9f20SBram Moolenaar } 2881f9cc9f20SBram Moolenaar 2882f9cc9f20SBram Moolenaar } 2883f9cc9f20SBram Moolenaar # endif 2884f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_fg); 2885f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = GUI_MCH_GET_RGB2(sgp->sg_gui_bg); 2886f9cc9f20SBram Moolenaar if (at_en.ae_u.cterm.fg_rgb == INVALCOLOR 2887f9cc9f20SBram Moolenaar && at_en.ae_u.cterm.bg_rgb == INVALCOLOR) 2888f9cc9f20SBram Moolenaar { 2889f9cc9f20SBram Moolenaar // If both fg and bg are invalid fall back to the cterm colors. 2890f9cc9f20SBram Moolenaar // Helps when the GUI only uses an attribute, e.g. undercurl. 2891f9cc9f20SBram Moolenaar at_en.ae_u.cterm.fg_rgb = CTERMCOLOR; 2892f9cc9f20SBram Moolenaar at_en.ae_u.cterm.bg_rgb = CTERMCOLOR; 2893f9cc9f20SBram Moolenaar } 2894f9cc9f20SBram Moolenaar # endif 2895f9cc9f20SBram Moolenaar sgp->sg_cterm_attr = get_attr_entry(&cterm_attr_table, &at_en); 2896f9cc9f20SBram Moolenaar } 2897f9cc9f20SBram Moolenaar } 2898f9cc9f20SBram Moolenaar 2899f9cc9f20SBram Moolenaar /* 2900f9cc9f20SBram Moolenaar * Lookup a highlight group name and return its ID. 2901f9cc9f20SBram Moolenaar * If it is not found, 0 is returned. 2902f9cc9f20SBram Moolenaar */ 2903f9cc9f20SBram Moolenaar int 2904f9cc9f20SBram Moolenaar syn_name2id(char_u *name) 2905f9cc9f20SBram Moolenaar { 2906f9cc9f20SBram Moolenaar int i; 2907f9cc9f20SBram Moolenaar char_u name_u[200]; 2908f9cc9f20SBram Moolenaar 2909f9cc9f20SBram Moolenaar // Avoid using stricmp() too much, it's slow on some systems 2910f9cc9f20SBram Moolenaar // Avoid alloc()/free(), these are slow too. ID names over 200 chars 2911f9cc9f20SBram Moolenaar // don't deserve to be found! 2912f9cc9f20SBram Moolenaar vim_strncpy(name_u, name, 199); 2913f9cc9f20SBram Moolenaar vim_strup(name_u); 2914f9cc9f20SBram Moolenaar for (i = highlight_ga.ga_len; --i >= 0; ) 2915f9cc9f20SBram Moolenaar if (HL_TABLE()[i].sg_name_u != NULL 2916f9cc9f20SBram Moolenaar && STRCMP(name_u, HL_TABLE()[i].sg_name_u) == 0) 2917f9cc9f20SBram Moolenaar break; 2918f9cc9f20SBram Moolenaar return i + 1; 2919f9cc9f20SBram Moolenaar } 2920f9cc9f20SBram Moolenaar 2921f9cc9f20SBram Moolenaar /* 2922f9cc9f20SBram Moolenaar * Lookup a highlight group name and return its attributes. 2923f9cc9f20SBram Moolenaar * Return zero if not found. 2924f9cc9f20SBram Moolenaar */ 2925f9cc9f20SBram Moolenaar int 2926f9cc9f20SBram Moolenaar syn_name2attr(char_u *name) 2927f9cc9f20SBram Moolenaar { 2928f9cc9f20SBram Moolenaar int id = syn_name2id(name); 2929f9cc9f20SBram Moolenaar 2930f9cc9f20SBram Moolenaar if (id != 0) 2931f9cc9f20SBram Moolenaar return syn_id2attr(id); 2932f9cc9f20SBram Moolenaar return 0; 2933f9cc9f20SBram Moolenaar } 2934f9cc9f20SBram Moolenaar 2935f9cc9f20SBram Moolenaar #if defined(FEAT_EVAL) || defined(PROTO) 2936f9cc9f20SBram Moolenaar /* 2937f9cc9f20SBram Moolenaar * Return TRUE if highlight group "name" exists. 2938f9cc9f20SBram Moolenaar */ 2939f9cc9f20SBram Moolenaar int 2940f9cc9f20SBram Moolenaar highlight_exists(char_u *name) 2941f9cc9f20SBram Moolenaar { 2942f9cc9f20SBram Moolenaar return (syn_name2id(name) > 0); 2943f9cc9f20SBram Moolenaar } 2944f9cc9f20SBram Moolenaar 2945f9cc9f20SBram Moolenaar # if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) 2946f9cc9f20SBram Moolenaar /* 2947f9cc9f20SBram Moolenaar * Return the name of highlight group "id". 2948f9cc9f20SBram Moolenaar * When not a valid ID return an empty string. 2949f9cc9f20SBram Moolenaar */ 2950f9cc9f20SBram Moolenaar char_u * 2951f9cc9f20SBram Moolenaar syn_id2name(int id) 2952f9cc9f20SBram Moolenaar { 2953f9cc9f20SBram Moolenaar if (id <= 0 || id > highlight_ga.ga_len) 2954f9cc9f20SBram Moolenaar return (char_u *)""; 2955f9cc9f20SBram Moolenaar return HL_TABLE()[id - 1].sg_name; 2956f9cc9f20SBram Moolenaar } 2957f9cc9f20SBram Moolenaar # endif 2958f9cc9f20SBram Moolenaar #endif 2959f9cc9f20SBram Moolenaar 2960f9cc9f20SBram Moolenaar /* 2961f9cc9f20SBram Moolenaar * Like syn_name2id(), but take a pointer + length argument. 2962f9cc9f20SBram Moolenaar */ 2963f9cc9f20SBram Moolenaar int 2964f9cc9f20SBram Moolenaar syn_namen2id(char_u *linep, int len) 2965f9cc9f20SBram Moolenaar { 2966f9cc9f20SBram Moolenaar char_u *name; 2967f9cc9f20SBram Moolenaar int id = 0; 2968f9cc9f20SBram Moolenaar 2969f9cc9f20SBram Moolenaar name = vim_strnsave(linep, len); 2970f9cc9f20SBram Moolenaar if (name != NULL) 2971f9cc9f20SBram Moolenaar { 2972f9cc9f20SBram Moolenaar id = syn_name2id(name); 2973f9cc9f20SBram Moolenaar vim_free(name); 2974f9cc9f20SBram Moolenaar } 2975f9cc9f20SBram Moolenaar return id; 2976f9cc9f20SBram Moolenaar } 2977f9cc9f20SBram Moolenaar 2978f9cc9f20SBram Moolenaar /* 2979f9cc9f20SBram Moolenaar * Find highlight group name in the table and return its ID. 2980f9cc9f20SBram Moolenaar * The argument is a pointer to the name and the length of the name. 2981f9cc9f20SBram Moolenaar * If it doesn't exist yet, a new entry is created. 2982f9cc9f20SBram Moolenaar * Return 0 for failure. 2983f9cc9f20SBram Moolenaar */ 2984f9cc9f20SBram Moolenaar int 2985f9cc9f20SBram Moolenaar syn_check_group(char_u *pp, int len) 2986f9cc9f20SBram Moolenaar { 2987f9cc9f20SBram Moolenaar int id; 2988f9cc9f20SBram Moolenaar char_u *name; 2989f9cc9f20SBram Moolenaar 2990f9cc9f20SBram Moolenaar name = vim_strnsave(pp, len); 2991f9cc9f20SBram Moolenaar if (name == NULL) 2992f9cc9f20SBram Moolenaar return 0; 2993f9cc9f20SBram Moolenaar 2994f9cc9f20SBram Moolenaar id = syn_name2id(name); 2995f9cc9f20SBram Moolenaar if (id == 0) // doesn't exist yet 2996f9cc9f20SBram Moolenaar id = syn_add_group(name); 2997f9cc9f20SBram Moolenaar else 2998f9cc9f20SBram Moolenaar vim_free(name); 2999f9cc9f20SBram Moolenaar return id; 3000f9cc9f20SBram Moolenaar } 3001f9cc9f20SBram Moolenaar 3002f9cc9f20SBram Moolenaar /* 3003f9cc9f20SBram Moolenaar * Add new highlight group and return its ID. 3004f9cc9f20SBram Moolenaar * "name" must be an allocated string, it will be consumed. 3005f9cc9f20SBram Moolenaar * Return 0 for failure. 3006f9cc9f20SBram Moolenaar */ 3007f9cc9f20SBram Moolenaar static int 3008f9cc9f20SBram Moolenaar syn_add_group(char_u *name) 3009f9cc9f20SBram Moolenaar { 3010f9cc9f20SBram Moolenaar char_u *p; 30116f10c70bSBram Moolenaar char_u *name_up; 3012f9cc9f20SBram Moolenaar 3013f9cc9f20SBram Moolenaar // Check that the name is ASCII letters, digits and underscore. 3014f9cc9f20SBram Moolenaar for (p = name; *p != NUL; ++p) 3015f9cc9f20SBram Moolenaar { 3016f9cc9f20SBram Moolenaar if (!vim_isprintc(*p)) 3017f9cc9f20SBram Moolenaar { 3018f9cc9f20SBram Moolenaar emsg(_("E669: Unprintable character in group name")); 3019f9cc9f20SBram Moolenaar vim_free(name); 3020f9cc9f20SBram Moolenaar return 0; 3021f9cc9f20SBram Moolenaar } 3022f9cc9f20SBram Moolenaar else if (!ASCII_ISALNUM(*p) && *p != '_') 3023f9cc9f20SBram Moolenaar { 3024f9cc9f20SBram Moolenaar // This is an error, but since there previously was no check only 3025f9cc9f20SBram Moolenaar // give a warning. 3026f9cc9f20SBram Moolenaar msg_source(HL_ATTR(HLF_W)); 3027f9cc9f20SBram Moolenaar msg(_("W18: Invalid character in group name")); 3028f9cc9f20SBram Moolenaar break; 3029f9cc9f20SBram Moolenaar } 3030f9cc9f20SBram Moolenaar } 3031f9cc9f20SBram Moolenaar 3032f9cc9f20SBram Moolenaar /* 3033f9cc9f20SBram Moolenaar * First call for this growarray: init growing array. 3034f9cc9f20SBram Moolenaar */ 3035f9cc9f20SBram Moolenaar if (highlight_ga.ga_data == NULL) 3036f9cc9f20SBram Moolenaar { 3037f9cc9f20SBram Moolenaar highlight_ga.ga_itemsize = sizeof(hl_group_T); 3038f9cc9f20SBram Moolenaar highlight_ga.ga_growsize = 10; 3039f9cc9f20SBram Moolenaar } 3040f9cc9f20SBram Moolenaar 3041f9cc9f20SBram Moolenaar if (highlight_ga.ga_len >= MAX_HL_ID) 3042f9cc9f20SBram Moolenaar { 3043f9cc9f20SBram Moolenaar emsg(_("E849: Too many highlight and syntax groups")); 3044f9cc9f20SBram Moolenaar vim_free(name); 3045f9cc9f20SBram Moolenaar return 0; 3046f9cc9f20SBram Moolenaar } 3047f9cc9f20SBram Moolenaar 3048f9cc9f20SBram Moolenaar /* 3049f9cc9f20SBram Moolenaar * Make room for at least one other syntax_highlight entry. 3050f9cc9f20SBram Moolenaar */ 3051f9cc9f20SBram Moolenaar if (ga_grow(&highlight_ga, 1) == FAIL) 3052f9cc9f20SBram Moolenaar { 3053f9cc9f20SBram Moolenaar vim_free(name); 3054f9cc9f20SBram Moolenaar return 0; 3055f9cc9f20SBram Moolenaar } 3056f9cc9f20SBram Moolenaar 30576f10c70bSBram Moolenaar name_up = vim_strsave_up(name); 30586f10c70bSBram Moolenaar if (name_up == NULL) 30596f10c70bSBram Moolenaar { 30606f10c70bSBram Moolenaar vim_free(name); 30616f10c70bSBram Moolenaar return 0; 30626f10c70bSBram Moolenaar } 30636f10c70bSBram Moolenaar 3064a80faa89SBram Moolenaar CLEAR_POINTER(&(HL_TABLE()[highlight_ga.ga_len])); 3065f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_name = name; 30666f10c70bSBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_name_u = name_up; 3067f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) 3068f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_bg = INVALCOLOR; 3069f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_fg = INVALCOLOR; 3070f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 3071f9cc9f20SBram Moolenaar HL_TABLE()[highlight_ga.ga_len].sg_gui_sp = INVALCOLOR; 3072f9cc9f20SBram Moolenaar # endif 3073f9cc9f20SBram Moolenaar #endif 3074f9cc9f20SBram Moolenaar ++highlight_ga.ga_len; 3075f9cc9f20SBram Moolenaar 3076f9cc9f20SBram Moolenaar return highlight_ga.ga_len; // ID is index plus one 3077f9cc9f20SBram Moolenaar } 3078f9cc9f20SBram Moolenaar 3079f9cc9f20SBram Moolenaar /* 3080f9cc9f20SBram Moolenaar * When, just after calling syn_add_group(), an error is discovered, this 3081f9cc9f20SBram Moolenaar * function deletes the new name. 3082f9cc9f20SBram Moolenaar */ 3083f9cc9f20SBram Moolenaar static void 3084f9cc9f20SBram Moolenaar syn_unadd_group(void) 3085f9cc9f20SBram Moolenaar { 3086f9cc9f20SBram Moolenaar --highlight_ga.ga_len; 3087f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name); 3088f9cc9f20SBram Moolenaar vim_free(HL_TABLE()[highlight_ga.ga_len].sg_name_u); 3089f9cc9f20SBram Moolenaar } 3090f9cc9f20SBram Moolenaar 3091f9cc9f20SBram Moolenaar /* 3092f9cc9f20SBram Moolenaar * Translate a group ID to highlight attributes. 3093f9cc9f20SBram Moolenaar */ 3094f9cc9f20SBram Moolenaar int 3095f9cc9f20SBram Moolenaar syn_id2attr(int hl_id) 3096f9cc9f20SBram Moolenaar { 3097f9cc9f20SBram Moolenaar int attr; 3098f9cc9f20SBram Moolenaar hl_group_T *sgp; 3099f9cc9f20SBram Moolenaar 3100f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id); 3101f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one 3102f9cc9f20SBram Moolenaar 3103f9cc9f20SBram Moolenaar #ifdef FEAT_GUI 3104f9cc9f20SBram Moolenaar /* 3105f9cc9f20SBram Moolenaar * Only use GUI attr when the GUI is being used. 3106f9cc9f20SBram Moolenaar */ 3107f9cc9f20SBram Moolenaar if (gui.in_use) 3108f9cc9f20SBram Moolenaar attr = sgp->sg_gui_attr; 3109f9cc9f20SBram Moolenaar else 3110f9cc9f20SBram Moolenaar #endif 3111f9cc9f20SBram Moolenaar if (IS_CTERM) 3112f9cc9f20SBram Moolenaar attr = sgp->sg_cterm_attr; 3113f9cc9f20SBram Moolenaar else 3114f9cc9f20SBram Moolenaar attr = sgp->sg_term_attr; 3115f9cc9f20SBram Moolenaar 3116f9cc9f20SBram Moolenaar return attr; 3117f9cc9f20SBram Moolenaar } 3118f9cc9f20SBram Moolenaar 3119f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) 3120f9cc9f20SBram Moolenaar /* 3121f9cc9f20SBram Moolenaar * Get the GUI colors and attributes for a group ID. 3122f9cc9f20SBram Moolenaar * NOTE: the colors will be INVALCOLOR when not set, the color otherwise. 3123f9cc9f20SBram Moolenaar */ 3124f9cc9f20SBram Moolenaar int 3125f9cc9f20SBram Moolenaar syn_id2colors(int hl_id, guicolor_T *fgp, guicolor_T *bgp) 3126f9cc9f20SBram Moolenaar { 3127f9cc9f20SBram Moolenaar hl_group_T *sgp; 3128f9cc9f20SBram Moolenaar 3129f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id); 3130f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one 3131f9cc9f20SBram Moolenaar 3132f9cc9f20SBram Moolenaar *fgp = sgp->sg_gui_fg; 3133f9cc9f20SBram Moolenaar *bgp = sgp->sg_gui_bg; 3134f9cc9f20SBram Moolenaar return sgp->sg_gui; 3135f9cc9f20SBram Moolenaar } 3136f9cc9f20SBram Moolenaar #endif 3137f9cc9f20SBram Moolenaar 3138f9cc9f20SBram Moolenaar #if (defined(MSWIN) \ 3139f9cc9f20SBram Moolenaar && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \ 3140219c7d06SBram Moolenaar && defined(FEAT_TERMGUICOLORS)) \ 3141219c7d06SBram Moolenaar || defined(FEAT_TERMINAL) || defined(PROTO) 3142f9cc9f20SBram Moolenaar void 3143f9cc9f20SBram Moolenaar syn_id2cterm_bg(int hl_id, int *fgp, int *bgp) 3144f9cc9f20SBram Moolenaar { 3145f9cc9f20SBram Moolenaar hl_group_T *sgp; 3146f9cc9f20SBram Moolenaar 3147f9cc9f20SBram Moolenaar hl_id = syn_get_final_id(hl_id); 3148f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one 3149f9cc9f20SBram Moolenaar *fgp = sgp->sg_cterm_fg - 1; 3150f9cc9f20SBram Moolenaar *bgp = sgp->sg_cterm_bg - 1; 3151f9cc9f20SBram Moolenaar } 3152f9cc9f20SBram Moolenaar #endif 3153f9cc9f20SBram Moolenaar 3154f9cc9f20SBram Moolenaar /* 3155f9cc9f20SBram Moolenaar * Translate a group ID to the final group ID (following links). 3156f9cc9f20SBram Moolenaar */ 3157f9cc9f20SBram Moolenaar int 3158f9cc9f20SBram Moolenaar syn_get_final_id(int hl_id) 3159f9cc9f20SBram Moolenaar { 3160f9cc9f20SBram Moolenaar int count; 3161f9cc9f20SBram Moolenaar hl_group_T *sgp; 3162f9cc9f20SBram Moolenaar 3163f9cc9f20SBram Moolenaar if (hl_id > highlight_ga.ga_len || hl_id < 1) 3164f9cc9f20SBram Moolenaar return 0; // Can be called from eval!! 3165f9cc9f20SBram Moolenaar 3166f9cc9f20SBram Moolenaar /* 3167f9cc9f20SBram Moolenaar * Follow links until there is no more. 3168f9cc9f20SBram Moolenaar * Look out for loops! Break after 100 links. 3169f9cc9f20SBram Moolenaar */ 3170f9cc9f20SBram Moolenaar for (count = 100; --count >= 0; ) 3171f9cc9f20SBram Moolenaar { 3172f9cc9f20SBram Moolenaar sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one 3173f9cc9f20SBram Moolenaar if (sgp->sg_link == 0 || sgp->sg_link > highlight_ga.ga_len) 3174f9cc9f20SBram Moolenaar break; 3175f9cc9f20SBram Moolenaar hl_id = sgp->sg_link; 3176f9cc9f20SBram Moolenaar } 3177f9cc9f20SBram Moolenaar 3178f9cc9f20SBram Moolenaar return hl_id; 3179f9cc9f20SBram Moolenaar } 3180f9cc9f20SBram Moolenaar 3181f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) || defined(PROTO) 3182f9cc9f20SBram Moolenaar /* 3183f9cc9f20SBram Moolenaar * Call this function just after the GUI has started. 3184f9cc9f20SBram Moolenaar * Also called when 'termguicolors' was set, gui.in_use will be FALSE then. 3185f9cc9f20SBram Moolenaar * It finds the font and color handles for the highlighting groups. 3186f9cc9f20SBram Moolenaar */ 3187f9cc9f20SBram Moolenaar void 3188f9cc9f20SBram Moolenaar highlight_gui_started(void) 3189f9cc9f20SBram Moolenaar { 3190f9cc9f20SBram Moolenaar int idx; 3191f9cc9f20SBram Moolenaar 3192f9cc9f20SBram Moolenaar // First get the colors from the "Normal" and "Menu" group, if set 3193f9cc9f20SBram Moolenaar if (USE_24BIT) 3194f9cc9f20SBram Moolenaar set_normal_colors(); 3195f9cc9f20SBram Moolenaar 3196f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx) 3197f9cc9f20SBram Moolenaar gui_do_one_color(idx, FALSE, FALSE); 3198f9cc9f20SBram Moolenaar 3199f9cc9f20SBram Moolenaar highlight_changed(); 3200f9cc9f20SBram Moolenaar } 3201f9cc9f20SBram Moolenaar 3202f9cc9f20SBram Moolenaar static void 3203f9cc9f20SBram Moolenaar gui_do_one_color( 3204f9cc9f20SBram Moolenaar int idx, 3205f9cc9f20SBram Moolenaar int do_menu UNUSED, // TRUE: might set the menu font 3206f9cc9f20SBram Moolenaar int do_tooltip UNUSED) // TRUE: might set the tooltip font 3207f9cc9f20SBram Moolenaar { 3208f9cc9f20SBram Moolenaar int didit = FALSE; 3209f9cc9f20SBram Moolenaar 3210f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 3211f9cc9f20SBram Moolenaar # ifdef FEAT_TERMGUICOLORS 3212f9cc9f20SBram Moolenaar if (gui.in_use) 3213f9cc9f20SBram Moolenaar # endif 3214f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_font_name != NULL) 3215f9cc9f20SBram Moolenaar { 3216f9cc9f20SBram Moolenaar hl_do_font(idx, HL_TABLE()[idx].sg_font_name, FALSE, do_menu, 3217f9cc9f20SBram Moolenaar do_tooltip, TRUE); 3218f9cc9f20SBram Moolenaar didit = TRUE; 3219f9cc9f20SBram Moolenaar } 3220f9cc9f20SBram Moolenaar # endif 3221f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_fg_name != NULL) 3222f9cc9f20SBram Moolenaar { 3223f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_fg = 3224f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_fg_name); 3225f9cc9f20SBram Moolenaar didit = TRUE; 3226f9cc9f20SBram Moolenaar } 3227f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_bg_name != NULL) 3228f9cc9f20SBram Moolenaar { 3229f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_bg = 3230f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_bg_name); 3231f9cc9f20SBram Moolenaar didit = TRUE; 3232f9cc9f20SBram Moolenaar } 3233f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 3234f9cc9f20SBram Moolenaar if (HL_TABLE()[idx].sg_gui_sp_name != NULL) 3235f9cc9f20SBram Moolenaar { 3236f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_gui_sp = 3237f9cc9f20SBram Moolenaar color_name2handle(HL_TABLE()[idx].sg_gui_sp_name); 3238f9cc9f20SBram Moolenaar didit = TRUE; 3239f9cc9f20SBram Moolenaar } 3240f9cc9f20SBram Moolenaar # endif 3241f9cc9f20SBram Moolenaar if (didit) // need to get a new attr number 3242f9cc9f20SBram Moolenaar set_hl_attr(idx); 3243f9cc9f20SBram Moolenaar } 3244f9cc9f20SBram Moolenaar #endif 3245f9cc9f20SBram Moolenaar 3246f9cc9f20SBram Moolenaar #if defined(USER_HIGHLIGHT) && defined(FEAT_STL_OPT) 3247f9cc9f20SBram Moolenaar /* 3248f9cc9f20SBram Moolenaar * Apply difference between User[1-9] and HLF_S to HLF_SNC, HLF_ST or HLF_STNC. 3249f9cc9f20SBram Moolenaar */ 3250f9cc9f20SBram Moolenaar static void 3251f9cc9f20SBram Moolenaar combine_stl_hlt( 3252f9cc9f20SBram Moolenaar int id, 3253f9cc9f20SBram Moolenaar int id_S, 3254f9cc9f20SBram Moolenaar int id_alt, 3255f9cc9f20SBram Moolenaar int hlcnt, 3256f9cc9f20SBram Moolenaar int i, 3257f9cc9f20SBram Moolenaar int hlf, 3258f9cc9f20SBram Moolenaar int *table) 3259f9cc9f20SBram Moolenaar { 3260f9cc9f20SBram Moolenaar hl_group_T *hlt = HL_TABLE(); 3261f9cc9f20SBram Moolenaar 3262f9cc9f20SBram Moolenaar if (id_alt == 0) 3263f9cc9f20SBram Moolenaar { 3264a80faa89SBram Moolenaar CLEAR_POINTER(&hlt[hlcnt + i]); 3265f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_term = highlight_attr[hlf]; 3266f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm = highlight_attr[hlf]; 3267f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_EVAL) 3268f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui = highlight_attr[hlf]; 3269f9cc9f20SBram Moolenaar # endif 3270f9cc9f20SBram Moolenaar } 3271f9cc9f20SBram Moolenaar else 3272f9cc9f20SBram Moolenaar mch_memmove(&hlt[hlcnt + i], 3273f9cc9f20SBram Moolenaar &hlt[id_alt - 1], 3274f9cc9f20SBram Moolenaar sizeof(hl_group_T)); 3275f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_link = 0; 3276f9cc9f20SBram Moolenaar 3277f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_term ^= 3278f9cc9f20SBram Moolenaar hlt[id - 1].sg_term ^ hlt[id_S - 1].sg_term; 3279f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_start != hlt[id_S - 1].sg_start) 3280f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_start = hlt[id - 1].sg_start; 3281f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_stop != hlt[id_S - 1].sg_stop) 3282f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_stop = hlt[id - 1].sg_stop; 3283f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm ^= 3284f9cc9f20SBram Moolenaar hlt[id - 1].sg_cterm ^ hlt[id_S - 1].sg_cterm; 3285f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_cterm_fg != hlt[id_S - 1].sg_cterm_fg) 3286f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm_fg = hlt[id - 1].sg_cterm_fg; 3287f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_cterm_bg != hlt[id_S - 1].sg_cterm_bg) 3288f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_cterm_bg = hlt[id - 1].sg_cterm_bg; 3289f9cc9f20SBram Moolenaar # if defined(FEAT_GUI) || defined(FEAT_EVAL) 3290f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui ^= 3291f9cc9f20SBram Moolenaar hlt[id - 1].sg_gui ^ hlt[id_S - 1].sg_gui; 3292f9cc9f20SBram Moolenaar # endif 3293f9cc9f20SBram Moolenaar # ifdef FEAT_GUI 3294f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_fg != hlt[id_S - 1].sg_gui_fg) 3295f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_fg = hlt[id - 1].sg_gui_fg; 3296f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_bg != hlt[id_S - 1].sg_gui_bg) 3297f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_bg = hlt[id - 1].sg_gui_bg; 3298f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_gui_sp != hlt[id_S - 1].sg_gui_sp) 3299f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_gui_sp = hlt[id - 1].sg_gui_sp; 3300f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_font != hlt[id_S - 1].sg_font) 3301f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_font = hlt[id - 1].sg_font; 3302f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 3303f9cc9f20SBram Moolenaar if (hlt[id - 1].sg_fontset != hlt[id_S - 1].sg_fontset) 3304f9cc9f20SBram Moolenaar hlt[hlcnt + i].sg_fontset = hlt[id - 1].sg_fontset; 3305f9cc9f20SBram Moolenaar # endif 3306f9cc9f20SBram Moolenaar # endif 3307f9cc9f20SBram Moolenaar highlight_ga.ga_len = hlcnt + i + 1; 3308f9cc9f20SBram Moolenaar set_hl_attr(hlcnt + i); // At long last we can apply 3309f9cc9f20SBram Moolenaar table[i] = syn_id2attr(hlcnt + i + 1); 3310f9cc9f20SBram Moolenaar } 3311f9cc9f20SBram Moolenaar #endif 3312f9cc9f20SBram Moolenaar 3313f9cc9f20SBram Moolenaar /* 3314f9cc9f20SBram Moolenaar * Translate the 'highlight' option into attributes in highlight_attr[] and 3315f9cc9f20SBram Moolenaar * set up the user highlights User1..9. If FEAT_STL_OPT is in use, a set of 3316f9cc9f20SBram Moolenaar * corresponding highlights to use on top of HLF_SNC is computed. 3317f9cc9f20SBram Moolenaar * Called only when the 'highlight' option has been changed and upon first 3318f9cc9f20SBram Moolenaar * screen redraw after any :highlight command. 3319f9cc9f20SBram Moolenaar * Return FAIL when an invalid flag is found in 'highlight'. OK otherwise. 3320f9cc9f20SBram Moolenaar */ 3321f9cc9f20SBram Moolenaar int 3322f9cc9f20SBram Moolenaar highlight_changed(void) 3323f9cc9f20SBram Moolenaar { 3324f9cc9f20SBram Moolenaar int hlf; 3325f9cc9f20SBram Moolenaar int i; 3326f9cc9f20SBram Moolenaar char_u *p; 3327f9cc9f20SBram Moolenaar int attr; 3328f9cc9f20SBram Moolenaar char_u *end; 3329f9cc9f20SBram Moolenaar int id; 3330f9cc9f20SBram Moolenaar #ifdef USER_HIGHLIGHT 3331f9cc9f20SBram Moolenaar char_u userhl[30]; // use 30 to avoid compiler warning 3332f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3333f9cc9f20SBram Moolenaar int id_S = -1; 3334f9cc9f20SBram Moolenaar int id_SNC = 0; 3335f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL 3336f9cc9f20SBram Moolenaar int id_ST = 0; 3337f9cc9f20SBram Moolenaar int id_STNC = 0; 3338f9cc9f20SBram Moolenaar # endif 3339f9cc9f20SBram Moolenaar int hlcnt; 3340f9cc9f20SBram Moolenaar # endif 3341f9cc9f20SBram Moolenaar #endif 3342f9cc9f20SBram Moolenaar static int hl_flags[HLF_COUNT] = HL_FLAGS; 3343f9cc9f20SBram Moolenaar 3344f9cc9f20SBram Moolenaar need_highlight_changed = FALSE; 3345f9cc9f20SBram Moolenaar 3346f9cc9f20SBram Moolenaar /* 3347f9cc9f20SBram Moolenaar * Clear all attributes. 3348f9cc9f20SBram Moolenaar */ 3349f9cc9f20SBram Moolenaar for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf) 3350f9cc9f20SBram Moolenaar highlight_attr[hlf] = 0; 3351f9cc9f20SBram Moolenaar 3352f9cc9f20SBram Moolenaar /* 3353f9cc9f20SBram Moolenaar * First set all attributes to their default value. 3354f9cc9f20SBram Moolenaar * Then use the attributes from the 'highlight' option. 3355f9cc9f20SBram Moolenaar */ 3356f9cc9f20SBram Moolenaar for (i = 0; i < 2; ++i) 3357f9cc9f20SBram Moolenaar { 3358f9cc9f20SBram Moolenaar if (i) 3359f9cc9f20SBram Moolenaar p = p_hl; 3360f9cc9f20SBram Moolenaar else 3361f9cc9f20SBram Moolenaar p = get_highlight_default(); 3362f9cc9f20SBram Moolenaar if (p == NULL) // just in case 3363f9cc9f20SBram Moolenaar continue; 3364f9cc9f20SBram Moolenaar 3365f9cc9f20SBram Moolenaar while (*p) 3366f9cc9f20SBram Moolenaar { 3367f9cc9f20SBram Moolenaar for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf) 3368f9cc9f20SBram Moolenaar if (hl_flags[hlf] == *p) 3369f9cc9f20SBram Moolenaar break; 3370f9cc9f20SBram Moolenaar ++p; 3371f9cc9f20SBram Moolenaar if (hlf == (int)HLF_COUNT || *p == NUL) 3372f9cc9f20SBram Moolenaar return FAIL; 3373f9cc9f20SBram Moolenaar 3374f9cc9f20SBram Moolenaar /* 3375f9cc9f20SBram Moolenaar * Allow several hl_flags to be combined, like "bu" for 3376f9cc9f20SBram Moolenaar * bold-underlined. 3377f9cc9f20SBram Moolenaar */ 3378f9cc9f20SBram Moolenaar attr = 0; 3379f9cc9f20SBram Moolenaar for ( ; *p && *p != ','; ++p) // parse up to comma 3380f9cc9f20SBram Moolenaar { 3381f9cc9f20SBram Moolenaar if (VIM_ISWHITE(*p)) // ignore white space 3382f9cc9f20SBram Moolenaar continue; 3383f9cc9f20SBram Moolenaar 3384f9cc9f20SBram Moolenaar if (attr > HL_ALL) // Combination with ':' is not allowed. 3385f9cc9f20SBram Moolenaar return FAIL; 3386f9cc9f20SBram Moolenaar 3387f9cc9f20SBram Moolenaar switch (*p) 3388f9cc9f20SBram Moolenaar { 3389f9cc9f20SBram Moolenaar case 'b': attr |= HL_BOLD; 3390f9cc9f20SBram Moolenaar break; 3391f9cc9f20SBram Moolenaar case 'i': attr |= HL_ITALIC; 3392f9cc9f20SBram Moolenaar break; 3393f9cc9f20SBram Moolenaar case '-': 3394f9cc9f20SBram Moolenaar case 'n': // no highlighting 3395f9cc9f20SBram Moolenaar break; 3396f9cc9f20SBram Moolenaar case 'r': attr |= HL_INVERSE; 3397f9cc9f20SBram Moolenaar break; 3398f9cc9f20SBram Moolenaar case 's': attr |= HL_STANDOUT; 3399f9cc9f20SBram Moolenaar break; 3400f9cc9f20SBram Moolenaar case 'u': attr |= HL_UNDERLINE; 3401f9cc9f20SBram Moolenaar break; 3402f9cc9f20SBram Moolenaar case 'c': attr |= HL_UNDERCURL; 3403f9cc9f20SBram Moolenaar break; 3404f9cc9f20SBram Moolenaar case 't': attr |= HL_STRIKETHROUGH; 3405f9cc9f20SBram Moolenaar break; 3406f9cc9f20SBram Moolenaar case ':': ++p; // highlight group name 3407f9cc9f20SBram Moolenaar if (attr || *p == NUL) // no combinations 3408f9cc9f20SBram Moolenaar return FAIL; 3409f9cc9f20SBram Moolenaar end = vim_strchr(p, ','); 3410f9cc9f20SBram Moolenaar if (end == NULL) 3411f9cc9f20SBram Moolenaar end = p + STRLEN(p); 3412f9cc9f20SBram Moolenaar id = syn_check_group(p, (int)(end - p)); 3413f9cc9f20SBram Moolenaar if (id == 0) 3414f9cc9f20SBram Moolenaar return FAIL; 3415f9cc9f20SBram Moolenaar attr = syn_id2attr(id); 3416f9cc9f20SBram Moolenaar p = end - 1; 3417f9cc9f20SBram Moolenaar #if defined(FEAT_STL_OPT) && defined(USER_HIGHLIGHT) 3418f9cc9f20SBram Moolenaar if (hlf == (int)HLF_SNC) 3419f9cc9f20SBram Moolenaar id_SNC = syn_get_final_id(id); 3420f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL 3421f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_ST) 3422f9cc9f20SBram Moolenaar id_ST = syn_get_final_id(id); 3423f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_STNC) 3424f9cc9f20SBram Moolenaar id_STNC = syn_get_final_id(id); 3425f9cc9f20SBram Moolenaar # endif 3426f9cc9f20SBram Moolenaar else if (hlf == (int)HLF_S) 3427f9cc9f20SBram Moolenaar id_S = syn_get_final_id(id); 3428f9cc9f20SBram Moolenaar #endif 3429f9cc9f20SBram Moolenaar break; 3430f9cc9f20SBram Moolenaar default: return FAIL; 3431f9cc9f20SBram Moolenaar } 3432f9cc9f20SBram Moolenaar } 3433f9cc9f20SBram Moolenaar highlight_attr[hlf] = attr; 3434f9cc9f20SBram Moolenaar 3435f9cc9f20SBram Moolenaar p = skip_to_option_part(p); // skip comma and spaces 3436f9cc9f20SBram Moolenaar } 3437f9cc9f20SBram Moolenaar } 3438f9cc9f20SBram Moolenaar 3439f9cc9f20SBram Moolenaar #ifdef USER_HIGHLIGHT 3440f9cc9f20SBram Moolenaar /* 3441f9cc9f20SBram Moolenaar * Setup the user highlights 3442f9cc9f20SBram Moolenaar * 3443f9cc9f20SBram Moolenaar * Temporarily utilize 28 more hl entries: 3444f9cc9f20SBram Moolenaar * 9 for User1-User9 combined with StatusLineNC 3445f9cc9f20SBram Moolenaar * 9 for User1-User9 combined with StatusLineTerm 3446f9cc9f20SBram Moolenaar * 9 for User1-User9 combined with StatusLineTermNC 3447f9cc9f20SBram Moolenaar * 1 for StatusLine default 3448f9cc9f20SBram Moolenaar * Have to be in there simultaneously in case of table overflows in 3449f9cc9f20SBram Moolenaar * get_attr_entry() 3450f9cc9f20SBram Moolenaar */ 3451f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3452f9cc9f20SBram Moolenaar if (ga_grow(&highlight_ga, 28) == FAIL) 3453f9cc9f20SBram Moolenaar return FAIL; 3454f9cc9f20SBram Moolenaar hlcnt = highlight_ga.ga_len; 3455f9cc9f20SBram Moolenaar if (id_S == -1) 3456f9cc9f20SBram Moolenaar { 3457f9cc9f20SBram Moolenaar // Make sure id_S is always valid to simplify code below. Use the last 3458f9cc9f20SBram Moolenaar // entry. 3459a80faa89SBram Moolenaar CLEAR_POINTER(&HL_TABLE()[hlcnt + 27]); 3460f9cc9f20SBram Moolenaar HL_TABLE()[hlcnt + 18].sg_term = highlight_attr[HLF_S]; 3461f9cc9f20SBram Moolenaar id_S = hlcnt + 19; 3462f9cc9f20SBram Moolenaar } 3463f9cc9f20SBram Moolenaar # endif 3464f9cc9f20SBram Moolenaar for (i = 0; i < 9; i++) 3465f9cc9f20SBram Moolenaar { 3466f9cc9f20SBram Moolenaar sprintf((char *)userhl, "User%d", i + 1); 3467f9cc9f20SBram Moolenaar id = syn_name2id(userhl); 3468f9cc9f20SBram Moolenaar if (id == 0) 3469f9cc9f20SBram Moolenaar { 3470f9cc9f20SBram Moolenaar highlight_user[i] = 0; 3471f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3472f9cc9f20SBram Moolenaar highlight_stlnc[i] = 0; 3473f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL 3474f9cc9f20SBram Moolenaar highlight_stlterm[i] = 0; 3475f9cc9f20SBram Moolenaar highlight_stltermnc[i] = 0; 3476f9cc9f20SBram Moolenaar # endif 3477f9cc9f20SBram Moolenaar # endif 3478f9cc9f20SBram Moolenaar } 3479f9cc9f20SBram Moolenaar else 3480f9cc9f20SBram Moolenaar { 3481f9cc9f20SBram Moolenaar highlight_user[i] = syn_id2attr(id); 3482f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3483f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_SNC, hlcnt, i, 3484f9cc9f20SBram Moolenaar HLF_SNC, highlight_stlnc); 3485f9cc9f20SBram Moolenaar # ifdef FEAT_TERMINAL 3486f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_ST, hlcnt + 9, i, 3487f9cc9f20SBram Moolenaar HLF_ST, highlight_stlterm); 3488f9cc9f20SBram Moolenaar combine_stl_hlt(id, id_S, id_STNC, hlcnt + 18, i, 3489f9cc9f20SBram Moolenaar HLF_STNC, highlight_stltermnc); 3490f9cc9f20SBram Moolenaar # endif 3491f9cc9f20SBram Moolenaar # endif 3492f9cc9f20SBram Moolenaar } 3493f9cc9f20SBram Moolenaar } 3494f9cc9f20SBram Moolenaar # ifdef FEAT_STL_OPT 3495f9cc9f20SBram Moolenaar highlight_ga.ga_len = hlcnt; 3496f9cc9f20SBram Moolenaar # endif 3497f9cc9f20SBram Moolenaar 3498f9cc9f20SBram Moolenaar #endif // USER_HIGHLIGHT 3499f9cc9f20SBram Moolenaar 3500f9cc9f20SBram Moolenaar return OK; 3501f9cc9f20SBram Moolenaar } 3502f9cc9f20SBram Moolenaar 3503f9cc9f20SBram Moolenaar static void highlight_list(void); 3504f9cc9f20SBram Moolenaar static void highlight_list_two(int cnt, int attr); 3505f9cc9f20SBram Moolenaar 3506f9cc9f20SBram Moolenaar /* 3507f9cc9f20SBram Moolenaar * Handle command line completion for :highlight command. 3508f9cc9f20SBram Moolenaar */ 3509f9cc9f20SBram Moolenaar void 3510f9cc9f20SBram Moolenaar set_context_in_highlight_cmd(expand_T *xp, char_u *arg) 3511f9cc9f20SBram Moolenaar { 3512f9cc9f20SBram Moolenaar char_u *p; 3513f9cc9f20SBram Moolenaar 3514f9cc9f20SBram Moolenaar // Default: expand group names 3515f9cc9f20SBram Moolenaar xp->xp_context = EXPAND_HIGHLIGHT; 3516f9cc9f20SBram Moolenaar xp->xp_pattern = arg; 3517f9cc9f20SBram Moolenaar include_link = 2; 3518f9cc9f20SBram Moolenaar include_default = 1; 3519f9cc9f20SBram Moolenaar 3520f9cc9f20SBram Moolenaar // (part of) subcommand already typed 3521f9cc9f20SBram Moolenaar if (*arg != NUL) 3522f9cc9f20SBram Moolenaar { 3523f9cc9f20SBram Moolenaar p = skiptowhite(arg); 3524f9cc9f20SBram Moolenaar if (*p != NUL) // past "default" or group name 3525f9cc9f20SBram Moolenaar { 3526f9cc9f20SBram Moolenaar include_default = 0; 3527f9cc9f20SBram Moolenaar if (STRNCMP("default", arg, p - arg) == 0) 3528f9cc9f20SBram Moolenaar { 3529f9cc9f20SBram Moolenaar arg = skipwhite(p); 3530f9cc9f20SBram Moolenaar xp->xp_pattern = arg; 3531f9cc9f20SBram Moolenaar p = skiptowhite(arg); 3532f9cc9f20SBram Moolenaar } 3533f9cc9f20SBram Moolenaar if (*p != NUL) // past group name 3534f9cc9f20SBram Moolenaar { 3535f9cc9f20SBram Moolenaar include_link = 0; 3536f9cc9f20SBram Moolenaar if (arg[1] == 'i' && arg[0] == 'N') 3537f9cc9f20SBram Moolenaar highlight_list(); 3538f9cc9f20SBram Moolenaar if (STRNCMP("link", arg, p - arg) == 0 3539f9cc9f20SBram Moolenaar || STRNCMP("clear", arg, p - arg) == 0) 3540f9cc9f20SBram Moolenaar { 3541f9cc9f20SBram Moolenaar xp->xp_pattern = skipwhite(p); 3542f9cc9f20SBram Moolenaar p = skiptowhite(xp->xp_pattern); 3543f9cc9f20SBram Moolenaar if (*p != NUL) // past first group name 3544f9cc9f20SBram Moolenaar { 3545f9cc9f20SBram Moolenaar xp->xp_pattern = skipwhite(p); 3546f9cc9f20SBram Moolenaar p = skiptowhite(xp->xp_pattern); 3547f9cc9f20SBram Moolenaar } 3548f9cc9f20SBram Moolenaar } 3549f9cc9f20SBram Moolenaar if (*p != NUL) // past group name(s) 3550f9cc9f20SBram Moolenaar xp->xp_context = EXPAND_NOTHING; 3551f9cc9f20SBram Moolenaar } 3552f9cc9f20SBram Moolenaar } 3553f9cc9f20SBram Moolenaar } 3554f9cc9f20SBram Moolenaar } 3555f9cc9f20SBram Moolenaar 3556f9cc9f20SBram Moolenaar /* 3557f9cc9f20SBram Moolenaar * List highlighting matches in a nice way. 3558f9cc9f20SBram Moolenaar */ 3559f9cc9f20SBram Moolenaar static void 3560f9cc9f20SBram Moolenaar highlight_list(void) 3561f9cc9f20SBram Moolenaar { 3562f9cc9f20SBram Moolenaar int i; 3563f9cc9f20SBram Moolenaar 3564f9cc9f20SBram Moolenaar for (i = 10; --i >= 0; ) 3565f9cc9f20SBram Moolenaar highlight_list_two(i, HL_ATTR(HLF_D)); 3566f9cc9f20SBram Moolenaar for (i = 40; --i >= 0; ) 3567f9cc9f20SBram Moolenaar highlight_list_two(99, 0); 3568f9cc9f20SBram Moolenaar } 3569f9cc9f20SBram Moolenaar 3570f9cc9f20SBram Moolenaar static void 3571f9cc9f20SBram Moolenaar highlight_list_two(int cnt, int attr) 3572f9cc9f20SBram Moolenaar { 3573f9cc9f20SBram Moolenaar msg_puts_attr(&("N \bI \b! \b"[cnt / 11]), attr); 3574f9cc9f20SBram Moolenaar msg_clr_eos(); 3575f9cc9f20SBram Moolenaar out_flush(); 3576f9cc9f20SBram Moolenaar ui_delay(cnt == 99 ? 40L : (long)cnt * 50L, FALSE); 3577f9cc9f20SBram Moolenaar } 3578f9cc9f20SBram Moolenaar 3579f9cc9f20SBram Moolenaar /* 3580f9cc9f20SBram Moolenaar * Function given to ExpandGeneric() to obtain the list of group names. 3581f9cc9f20SBram Moolenaar */ 3582f9cc9f20SBram Moolenaar char_u * 3583f9cc9f20SBram Moolenaar get_highlight_name(expand_T *xp UNUSED, int idx) 3584f9cc9f20SBram Moolenaar { 3585f9cc9f20SBram Moolenaar return get_highlight_name_ext(xp, idx, TRUE); 3586f9cc9f20SBram Moolenaar } 3587f9cc9f20SBram Moolenaar 3588f9cc9f20SBram Moolenaar /* 3589f9cc9f20SBram Moolenaar * Obtain a highlight group name. 3590f9cc9f20SBram Moolenaar * When "skip_cleared" is TRUE don't return a cleared entry. 3591f9cc9f20SBram Moolenaar */ 3592f9cc9f20SBram Moolenaar char_u * 3593f9cc9f20SBram Moolenaar get_highlight_name_ext(expand_T *xp UNUSED, int idx, int skip_cleared) 3594f9cc9f20SBram Moolenaar { 3595f9cc9f20SBram Moolenaar if (idx < 0) 3596f9cc9f20SBram Moolenaar return NULL; 3597f9cc9f20SBram Moolenaar 3598f9cc9f20SBram Moolenaar // Items are never removed from the table, skip the ones that were 3599f9cc9f20SBram Moolenaar // cleared. 3600f9cc9f20SBram Moolenaar if (skip_cleared && idx < highlight_ga.ga_len && HL_TABLE()[idx].sg_cleared) 3601f9cc9f20SBram Moolenaar return (char_u *)""; 3602f9cc9f20SBram Moolenaar 3603f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len && include_none != 0) 3604f9cc9f20SBram Moolenaar return (char_u *)"none"; 3605f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none && include_default != 0) 3606f9cc9f20SBram Moolenaar return (char_u *)"default"; 3607f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none + include_default 3608f9cc9f20SBram Moolenaar && include_link != 0) 3609f9cc9f20SBram Moolenaar return (char_u *)"link"; 3610f9cc9f20SBram Moolenaar if (idx == highlight_ga.ga_len + include_none + include_default + 1 3611f9cc9f20SBram Moolenaar && include_link != 0) 3612f9cc9f20SBram Moolenaar return (char_u *)"clear"; 3613f9cc9f20SBram Moolenaar if (idx >= highlight_ga.ga_len) 3614f9cc9f20SBram Moolenaar return NULL; 3615f9cc9f20SBram Moolenaar return HL_TABLE()[idx].sg_name; 3616f9cc9f20SBram Moolenaar } 3617f9cc9f20SBram Moolenaar 3618f9cc9f20SBram Moolenaar #if defined(FEAT_GUI) || defined(PROTO) 3619f9cc9f20SBram Moolenaar /* 3620f9cc9f20SBram Moolenaar * Free all the highlight group fonts. 3621f9cc9f20SBram Moolenaar * Used when quitting for systems which need it. 3622f9cc9f20SBram Moolenaar */ 3623f9cc9f20SBram Moolenaar void 3624f9cc9f20SBram Moolenaar free_highlight_fonts(void) 3625f9cc9f20SBram Moolenaar { 3626f9cc9f20SBram Moolenaar int idx; 3627f9cc9f20SBram Moolenaar 3628f9cc9f20SBram Moolenaar for (idx = 0; idx < highlight_ga.ga_len; ++idx) 3629f9cc9f20SBram Moolenaar { 3630f9cc9f20SBram Moolenaar gui_mch_free_font(HL_TABLE()[idx].sg_font); 3631f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_font = NOFONT; 3632f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 3633f9cc9f20SBram Moolenaar gui_mch_free_fontset(HL_TABLE()[idx].sg_fontset); 3634f9cc9f20SBram Moolenaar HL_TABLE()[idx].sg_fontset = NOFONTSET; 3635f9cc9f20SBram Moolenaar # endif 3636f9cc9f20SBram Moolenaar } 3637f9cc9f20SBram Moolenaar 3638f9cc9f20SBram Moolenaar gui_mch_free_font(gui.norm_font); 3639f9cc9f20SBram Moolenaar # ifdef FEAT_XFONTSET 3640f9cc9f20SBram Moolenaar gui_mch_free_fontset(gui.fontset); 3641f9cc9f20SBram Moolenaar # endif 3642f9cc9f20SBram Moolenaar # ifndef FEAT_GUI_GTK 3643f9cc9f20SBram Moolenaar gui_mch_free_font(gui.bold_font); 3644f9cc9f20SBram Moolenaar gui_mch_free_font(gui.ital_font); 3645f9cc9f20SBram Moolenaar gui_mch_free_font(gui.boldital_font); 3646f9cc9f20SBram Moolenaar # endif 3647f9cc9f20SBram Moolenaar } 3648f9cc9f20SBram Moolenaar #endif 364929b7d7a9SBram Moolenaar 365029b7d7a9SBram Moolenaar 365129b7d7a9SBram Moolenaar #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) 3652bbca7732SBram Moolenaar 3653bbca7732SBram Moolenaar # define SEARCH_HL_PRIORITY 0 3654bbca7732SBram Moolenaar 365529b7d7a9SBram Moolenaar /* 365629b7d7a9SBram Moolenaar * Add match to the match list of window 'wp'. The pattern 'pat' will be 365729b7d7a9SBram Moolenaar * highlighted with the group 'grp' with priority 'prio'. 365829b7d7a9SBram Moolenaar * Optionally, a desired ID 'id' can be specified (greater than or equal to 1). 365929b7d7a9SBram Moolenaar * If no particular ID is desired, -1 must be specified for 'id'. 366029b7d7a9SBram Moolenaar * Return ID of added match, -1 on failure. 366129b7d7a9SBram Moolenaar */ 36627dfb016dSBram Moolenaar static int 366329b7d7a9SBram Moolenaar match_add( 366429b7d7a9SBram Moolenaar win_T *wp, 366529b7d7a9SBram Moolenaar char_u *grp, 366629b7d7a9SBram Moolenaar char_u *pat, 366729b7d7a9SBram Moolenaar int prio, 366829b7d7a9SBram Moolenaar int id, 366929b7d7a9SBram Moolenaar list_T *pos_list, 36701f164b19SBram Moolenaar char_u *conceal_char UNUSED) // pointer to conceal replacement char 367129b7d7a9SBram Moolenaar { 367229b7d7a9SBram Moolenaar matchitem_T *cur; 367329b7d7a9SBram Moolenaar matchitem_T *prev; 367429b7d7a9SBram Moolenaar matchitem_T *m; 367529b7d7a9SBram Moolenaar int hlg_id; 367629b7d7a9SBram Moolenaar regprog_T *regprog = NULL; 367729b7d7a9SBram Moolenaar int rtype = SOME_VALID; 367829b7d7a9SBram Moolenaar 367929b7d7a9SBram Moolenaar if (*grp == NUL || (pat != NULL && *pat == NUL)) 368029b7d7a9SBram Moolenaar return -1; 368129b7d7a9SBram Moolenaar if (id < -1 || id == 0) 368229b7d7a9SBram Moolenaar { 368332aa1020SBram Moolenaar semsg(_("E799: Invalid ID: %d (must be greater than or equal to 1)"), 368432aa1020SBram Moolenaar id); 368529b7d7a9SBram Moolenaar return -1; 368629b7d7a9SBram Moolenaar } 368729b7d7a9SBram Moolenaar if (id != -1) 368829b7d7a9SBram Moolenaar { 368929b7d7a9SBram Moolenaar cur = wp->w_match_head; 369029b7d7a9SBram Moolenaar while (cur != NULL) 369129b7d7a9SBram Moolenaar { 369229b7d7a9SBram Moolenaar if (cur->id == id) 369329b7d7a9SBram Moolenaar { 369429b7d7a9SBram Moolenaar semsg(_("E801: ID already taken: %d"), id); 369529b7d7a9SBram Moolenaar return -1; 369629b7d7a9SBram Moolenaar } 369729b7d7a9SBram Moolenaar cur = cur->next; 369829b7d7a9SBram Moolenaar } 369929b7d7a9SBram Moolenaar } 370029b7d7a9SBram Moolenaar if ((hlg_id = syn_namen2id(grp, (int)STRLEN(grp))) == 0) 370129b7d7a9SBram Moolenaar { 370229b7d7a9SBram Moolenaar semsg(_(e_nogroup), grp); 370329b7d7a9SBram Moolenaar return -1; 370429b7d7a9SBram Moolenaar } 370529b7d7a9SBram Moolenaar if (pat != NULL && (regprog = vim_regcomp(pat, RE_MAGIC)) == NULL) 370629b7d7a9SBram Moolenaar { 370729b7d7a9SBram Moolenaar semsg(_(e_invarg2), pat); 370829b7d7a9SBram Moolenaar return -1; 370929b7d7a9SBram Moolenaar } 371029b7d7a9SBram Moolenaar 37111f164b19SBram Moolenaar // Find available match ID. 371229b7d7a9SBram Moolenaar while (id == -1) 371329b7d7a9SBram Moolenaar { 371429b7d7a9SBram Moolenaar cur = wp->w_match_head; 371529b7d7a9SBram Moolenaar while (cur != NULL && cur->id != wp->w_next_match_id) 371629b7d7a9SBram Moolenaar cur = cur->next; 371729b7d7a9SBram Moolenaar if (cur == NULL) 371829b7d7a9SBram Moolenaar id = wp->w_next_match_id; 371929b7d7a9SBram Moolenaar wp->w_next_match_id++; 372029b7d7a9SBram Moolenaar } 372129b7d7a9SBram Moolenaar 37221f164b19SBram Moolenaar // Build new match. 372329b7d7a9SBram Moolenaar m = ALLOC_CLEAR_ONE(matchitem_T); 372429b7d7a9SBram Moolenaar m->id = id; 372529b7d7a9SBram Moolenaar m->priority = prio; 372629b7d7a9SBram Moolenaar m->pattern = pat == NULL ? NULL : vim_strsave(pat); 372729b7d7a9SBram Moolenaar m->hlg_id = hlg_id; 372829b7d7a9SBram Moolenaar m->match.regprog = regprog; 372929b7d7a9SBram Moolenaar m->match.rmm_ic = FALSE; 373029b7d7a9SBram Moolenaar m->match.rmm_maxcol = 0; 373129b7d7a9SBram Moolenaar # if defined(FEAT_CONCEAL) 373229b7d7a9SBram Moolenaar m->conceal_char = 0; 373329b7d7a9SBram Moolenaar if (conceal_char != NULL) 373429b7d7a9SBram Moolenaar m->conceal_char = (*mb_ptr2char)(conceal_char); 373529b7d7a9SBram Moolenaar # endif 373629b7d7a9SBram Moolenaar 37371f164b19SBram Moolenaar // Set up position matches 373829b7d7a9SBram Moolenaar if (pos_list != NULL) 373929b7d7a9SBram Moolenaar { 374029b7d7a9SBram Moolenaar linenr_T toplnum = 0; 374129b7d7a9SBram Moolenaar linenr_T botlnum = 0; 374229b7d7a9SBram Moolenaar listitem_T *li; 374329b7d7a9SBram Moolenaar int i; 374429b7d7a9SBram Moolenaar 37457e9f351bSBram Moolenaar CHECK_LIST_MATERIALIZE(pos_list); 374629b7d7a9SBram Moolenaar for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH; 374729b7d7a9SBram Moolenaar i++, li = li->li_next) 374829b7d7a9SBram Moolenaar { 374929b7d7a9SBram Moolenaar linenr_T lnum = 0; 375029b7d7a9SBram Moolenaar colnr_T col = 0; 375129b7d7a9SBram Moolenaar int len = 1; 375229b7d7a9SBram Moolenaar list_T *subl; 375329b7d7a9SBram Moolenaar listitem_T *subli; 375429b7d7a9SBram Moolenaar int error = FALSE; 375529b7d7a9SBram Moolenaar 375629b7d7a9SBram Moolenaar if (li->li_tv.v_type == VAR_LIST) 375729b7d7a9SBram Moolenaar { 375829b7d7a9SBram Moolenaar subl = li->li_tv.vval.v_list; 375929b7d7a9SBram Moolenaar if (subl == NULL) 376029b7d7a9SBram Moolenaar goto fail; 376129b7d7a9SBram Moolenaar subli = subl->lv_first; 376229b7d7a9SBram Moolenaar if (subli == NULL) 376329b7d7a9SBram Moolenaar goto fail; 376429b7d7a9SBram Moolenaar lnum = tv_get_number_chk(&subli->li_tv, &error); 376529b7d7a9SBram Moolenaar if (error == TRUE) 376629b7d7a9SBram Moolenaar goto fail; 376729b7d7a9SBram Moolenaar if (lnum == 0) 376829b7d7a9SBram Moolenaar { 376929b7d7a9SBram Moolenaar --i; 377029b7d7a9SBram Moolenaar continue; 377129b7d7a9SBram Moolenaar } 377229b7d7a9SBram Moolenaar m->pos.pos[i].lnum = lnum; 377329b7d7a9SBram Moolenaar subli = subli->li_next; 377429b7d7a9SBram Moolenaar if (subli != NULL) 377529b7d7a9SBram Moolenaar { 377629b7d7a9SBram Moolenaar col = tv_get_number_chk(&subli->li_tv, &error); 377729b7d7a9SBram Moolenaar if (error == TRUE) 377829b7d7a9SBram Moolenaar goto fail; 377929b7d7a9SBram Moolenaar subli = subli->li_next; 378029b7d7a9SBram Moolenaar if (subli != NULL) 378129b7d7a9SBram Moolenaar { 378229b7d7a9SBram Moolenaar len = tv_get_number_chk(&subli->li_tv, &error); 378329b7d7a9SBram Moolenaar if (error == TRUE) 378429b7d7a9SBram Moolenaar goto fail; 378529b7d7a9SBram Moolenaar } 378629b7d7a9SBram Moolenaar } 378729b7d7a9SBram Moolenaar m->pos.pos[i].col = col; 378829b7d7a9SBram Moolenaar m->pos.pos[i].len = len; 378929b7d7a9SBram Moolenaar } 379029b7d7a9SBram Moolenaar else if (li->li_tv.v_type == VAR_NUMBER) 379129b7d7a9SBram Moolenaar { 379229b7d7a9SBram Moolenaar if (li->li_tv.vval.v_number == 0) 379329b7d7a9SBram Moolenaar { 379429b7d7a9SBram Moolenaar --i; 379529b7d7a9SBram Moolenaar continue; 379629b7d7a9SBram Moolenaar } 379729b7d7a9SBram Moolenaar m->pos.pos[i].lnum = li->li_tv.vval.v_number; 379829b7d7a9SBram Moolenaar m->pos.pos[i].col = 0; 379929b7d7a9SBram Moolenaar m->pos.pos[i].len = 0; 380029b7d7a9SBram Moolenaar } 380129b7d7a9SBram Moolenaar else 380229b7d7a9SBram Moolenaar { 38031500a42cSBram Moolenaar emsg(_("E290: List or number required")); 380429b7d7a9SBram Moolenaar goto fail; 380529b7d7a9SBram Moolenaar } 380629b7d7a9SBram Moolenaar if (toplnum == 0 || lnum < toplnum) 380729b7d7a9SBram Moolenaar toplnum = lnum; 380829b7d7a9SBram Moolenaar if (botlnum == 0 || lnum >= botlnum) 380929b7d7a9SBram Moolenaar botlnum = lnum + 1; 381029b7d7a9SBram Moolenaar } 381129b7d7a9SBram Moolenaar 38121f164b19SBram Moolenaar // Calculate top and bottom lines for redrawing area 381329b7d7a9SBram Moolenaar if (toplnum != 0) 381429b7d7a9SBram Moolenaar { 381529b7d7a9SBram Moolenaar if (wp->w_buffer->b_mod_set) 381629b7d7a9SBram Moolenaar { 381729b7d7a9SBram Moolenaar if (wp->w_buffer->b_mod_top > toplnum) 381829b7d7a9SBram Moolenaar wp->w_buffer->b_mod_top = toplnum; 381929b7d7a9SBram Moolenaar if (wp->w_buffer->b_mod_bot < botlnum) 382029b7d7a9SBram Moolenaar wp->w_buffer->b_mod_bot = botlnum; 382129b7d7a9SBram Moolenaar } 382229b7d7a9SBram Moolenaar else 382329b7d7a9SBram Moolenaar { 382429b7d7a9SBram Moolenaar wp->w_buffer->b_mod_set = TRUE; 382529b7d7a9SBram Moolenaar wp->w_buffer->b_mod_top = toplnum; 382629b7d7a9SBram Moolenaar wp->w_buffer->b_mod_bot = botlnum; 382729b7d7a9SBram Moolenaar wp->w_buffer->b_mod_xlines = 0; 382829b7d7a9SBram Moolenaar } 382929b7d7a9SBram Moolenaar m->pos.toplnum = toplnum; 383029b7d7a9SBram Moolenaar m->pos.botlnum = botlnum; 383129b7d7a9SBram Moolenaar rtype = VALID; 383229b7d7a9SBram Moolenaar } 383329b7d7a9SBram Moolenaar } 383429b7d7a9SBram Moolenaar 38351f164b19SBram Moolenaar // Insert new match. The match list is in ascending order with regard to 38361f164b19SBram Moolenaar // the match priorities. 383729b7d7a9SBram Moolenaar cur = wp->w_match_head; 383829b7d7a9SBram Moolenaar prev = cur; 383929b7d7a9SBram Moolenaar while (cur != NULL && prio >= cur->priority) 384029b7d7a9SBram Moolenaar { 384129b7d7a9SBram Moolenaar prev = cur; 384229b7d7a9SBram Moolenaar cur = cur->next; 384329b7d7a9SBram Moolenaar } 384429b7d7a9SBram Moolenaar if (cur == prev) 384529b7d7a9SBram Moolenaar wp->w_match_head = m; 384629b7d7a9SBram Moolenaar else 384729b7d7a9SBram Moolenaar prev->next = m; 384829b7d7a9SBram Moolenaar m->next = cur; 384929b7d7a9SBram Moolenaar 38504ef18dccSBram Moolenaar redraw_win_later(wp, rtype); 385129b7d7a9SBram Moolenaar return id; 385229b7d7a9SBram Moolenaar 385329b7d7a9SBram Moolenaar fail: 385429b7d7a9SBram Moolenaar vim_free(m); 385529b7d7a9SBram Moolenaar return -1; 385629b7d7a9SBram Moolenaar } 385729b7d7a9SBram Moolenaar 385829b7d7a9SBram Moolenaar /* 385929b7d7a9SBram Moolenaar * Delete match with ID 'id' in the match list of window 'wp'. 386029b7d7a9SBram Moolenaar * Print error messages if 'perr' is TRUE. 386129b7d7a9SBram Moolenaar */ 38627dfb016dSBram Moolenaar static int 386329b7d7a9SBram Moolenaar match_delete(win_T *wp, int id, int perr) 386429b7d7a9SBram Moolenaar { 386529b7d7a9SBram Moolenaar matchitem_T *cur = wp->w_match_head; 386629b7d7a9SBram Moolenaar matchitem_T *prev = cur; 386729b7d7a9SBram Moolenaar int rtype = SOME_VALID; 386829b7d7a9SBram Moolenaar 386929b7d7a9SBram Moolenaar if (id < 1) 387029b7d7a9SBram Moolenaar { 387129b7d7a9SBram Moolenaar if (perr == TRUE) 387229b7d7a9SBram Moolenaar semsg(_("E802: Invalid ID: %d (must be greater than or equal to 1)"), 387329b7d7a9SBram Moolenaar id); 387429b7d7a9SBram Moolenaar return -1; 387529b7d7a9SBram Moolenaar } 387629b7d7a9SBram Moolenaar while (cur != NULL && cur->id != id) 387729b7d7a9SBram Moolenaar { 387829b7d7a9SBram Moolenaar prev = cur; 387929b7d7a9SBram Moolenaar cur = cur->next; 388029b7d7a9SBram Moolenaar } 388129b7d7a9SBram Moolenaar if (cur == NULL) 388229b7d7a9SBram Moolenaar { 388329b7d7a9SBram Moolenaar if (perr == TRUE) 388429b7d7a9SBram Moolenaar semsg(_("E803: ID not found: %d"), id); 388529b7d7a9SBram Moolenaar return -1; 388629b7d7a9SBram Moolenaar } 388729b7d7a9SBram Moolenaar if (cur == prev) 388829b7d7a9SBram Moolenaar wp->w_match_head = cur->next; 388929b7d7a9SBram Moolenaar else 389029b7d7a9SBram Moolenaar prev->next = cur->next; 389129b7d7a9SBram Moolenaar vim_regfree(cur->match.regprog); 389229b7d7a9SBram Moolenaar vim_free(cur->pattern); 389329b7d7a9SBram Moolenaar if (cur->pos.toplnum != 0) 389429b7d7a9SBram Moolenaar { 389529b7d7a9SBram Moolenaar if (wp->w_buffer->b_mod_set) 389629b7d7a9SBram Moolenaar { 389729b7d7a9SBram Moolenaar if (wp->w_buffer->b_mod_top > cur->pos.toplnum) 389829b7d7a9SBram Moolenaar wp->w_buffer->b_mod_top = cur->pos.toplnum; 389929b7d7a9SBram Moolenaar if (wp->w_buffer->b_mod_bot < cur->pos.botlnum) 390029b7d7a9SBram Moolenaar wp->w_buffer->b_mod_bot = cur->pos.botlnum; 390129b7d7a9SBram Moolenaar } 390229b7d7a9SBram Moolenaar else 390329b7d7a9SBram Moolenaar { 390429b7d7a9SBram Moolenaar wp->w_buffer->b_mod_set = TRUE; 390529b7d7a9SBram Moolenaar wp->w_buffer->b_mod_top = cur->pos.toplnum; 390629b7d7a9SBram Moolenaar wp->w_buffer->b_mod_bot = cur->pos.botlnum; 390729b7d7a9SBram Moolenaar wp->w_buffer->b_mod_xlines = 0; 390829b7d7a9SBram Moolenaar } 390929b7d7a9SBram Moolenaar rtype = VALID; 391029b7d7a9SBram Moolenaar } 391129b7d7a9SBram Moolenaar vim_free(cur); 391206029a85SBram Moolenaar redraw_win_later(wp, rtype); 391329b7d7a9SBram Moolenaar return 0; 391429b7d7a9SBram Moolenaar } 391529b7d7a9SBram Moolenaar 391629b7d7a9SBram Moolenaar /* 391729b7d7a9SBram Moolenaar * Delete all matches in the match list of window 'wp'. 391829b7d7a9SBram Moolenaar */ 391929b7d7a9SBram Moolenaar void 392029b7d7a9SBram Moolenaar clear_matches(win_T *wp) 392129b7d7a9SBram Moolenaar { 392229b7d7a9SBram Moolenaar matchitem_T *m; 392329b7d7a9SBram Moolenaar 392429b7d7a9SBram Moolenaar while (wp->w_match_head != NULL) 392529b7d7a9SBram Moolenaar { 392629b7d7a9SBram Moolenaar m = wp->w_match_head->next; 392729b7d7a9SBram Moolenaar vim_regfree(wp->w_match_head->match.regprog); 392829b7d7a9SBram Moolenaar vim_free(wp->w_match_head->pattern); 392929b7d7a9SBram Moolenaar vim_free(wp->w_match_head); 393029b7d7a9SBram Moolenaar wp->w_match_head = m; 393129b7d7a9SBram Moolenaar } 39324ef18dccSBram Moolenaar redraw_win_later(wp, SOME_VALID); 393329b7d7a9SBram Moolenaar } 393429b7d7a9SBram Moolenaar 393529b7d7a9SBram Moolenaar /* 393629b7d7a9SBram Moolenaar * Get match from ID 'id' in window 'wp'. 393729b7d7a9SBram Moolenaar * Return NULL if match not found. 393829b7d7a9SBram Moolenaar */ 39397dfb016dSBram Moolenaar static matchitem_T * 394029b7d7a9SBram Moolenaar get_match(win_T *wp, int id) 394129b7d7a9SBram Moolenaar { 394229b7d7a9SBram Moolenaar matchitem_T *cur = wp->w_match_head; 394329b7d7a9SBram Moolenaar 394429b7d7a9SBram Moolenaar while (cur != NULL && cur->id != id) 394529b7d7a9SBram Moolenaar cur = cur->next; 394629b7d7a9SBram Moolenaar return cur; 394729b7d7a9SBram Moolenaar } 3948bbca7732SBram Moolenaar 3949bbca7732SBram Moolenaar /* 3950bbca7732SBram Moolenaar * Init for calling prepare_search_hl(). 3951bbca7732SBram Moolenaar */ 3952bbca7732SBram Moolenaar void 3953bbca7732SBram Moolenaar init_search_hl(win_T *wp, match_T *search_hl) 3954bbca7732SBram Moolenaar { 3955bbca7732SBram Moolenaar matchitem_T *cur; 3956bbca7732SBram Moolenaar 39571f164b19SBram Moolenaar // Setup for match and 'hlsearch' highlighting. Disable any previous 39581f164b19SBram Moolenaar // match 3959bbca7732SBram Moolenaar cur = wp->w_match_head; 3960bbca7732SBram Moolenaar while (cur != NULL) 3961bbca7732SBram Moolenaar { 3962bbca7732SBram Moolenaar cur->hl.rm = cur->match; 3963bbca7732SBram Moolenaar if (cur->hlg_id == 0) 3964bbca7732SBram Moolenaar cur->hl.attr = 0; 3965bbca7732SBram Moolenaar else 3966bbca7732SBram Moolenaar cur->hl.attr = syn_id2attr(cur->hlg_id); 3967bbca7732SBram Moolenaar cur->hl.buf = wp->w_buffer; 3968bbca7732SBram Moolenaar cur->hl.lnum = 0; 3969bbca7732SBram Moolenaar cur->hl.first_lnum = 0; 3970bbca7732SBram Moolenaar # ifdef FEAT_RELTIME 39711f164b19SBram Moolenaar // Set the time limit to 'redrawtime'. 3972bbca7732SBram Moolenaar profile_setlimit(p_rdt, &(cur->hl.tm)); 3973c61a48d2SBram Moolenaar # endif 3974bbca7732SBram Moolenaar cur = cur->next; 3975bbca7732SBram Moolenaar } 3976bbca7732SBram Moolenaar search_hl->buf = wp->w_buffer; 3977bbca7732SBram Moolenaar search_hl->lnum = 0; 3978bbca7732SBram Moolenaar search_hl->first_lnum = 0; 39791f164b19SBram Moolenaar // time limit is set at the toplevel, for all windows 3980bbca7732SBram Moolenaar } 3981bbca7732SBram Moolenaar 3982bbca7732SBram Moolenaar /* 3983bbca7732SBram Moolenaar * If there is a match fill "shl" and return one. 3984bbca7732SBram Moolenaar * Return zero otherwise. 3985bbca7732SBram Moolenaar */ 3986bbca7732SBram Moolenaar static int 3987bbca7732SBram Moolenaar next_search_hl_pos( 39881f164b19SBram Moolenaar match_T *shl, // points to a match 3989bbca7732SBram Moolenaar linenr_T lnum, 39901f164b19SBram Moolenaar posmatch_T *posmatch, // match positions 39911f164b19SBram Moolenaar colnr_T mincol) // minimal column for a match 3992bbca7732SBram Moolenaar { 3993bbca7732SBram Moolenaar int i; 3994bbca7732SBram Moolenaar int found = -1; 3995bbca7732SBram Moolenaar 3996bbca7732SBram Moolenaar for (i = posmatch->cur; i < MAXPOSMATCH; i++) 3997bbca7732SBram Moolenaar { 3998bbca7732SBram Moolenaar llpos_T *pos = &posmatch->pos[i]; 3999bbca7732SBram Moolenaar 4000bbca7732SBram Moolenaar if (pos->lnum == 0) 4001bbca7732SBram Moolenaar break; 4002bbca7732SBram Moolenaar if (pos->len == 0 && pos->col < mincol) 4003bbca7732SBram Moolenaar continue; 4004bbca7732SBram Moolenaar if (pos->lnum == lnum) 4005bbca7732SBram Moolenaar { 4006bbca7732SBram Moolenaar if (found >= 0) 4007bbca7732SBram Moolenaar { 40081f164b19SBram Moolenaar // if this match comes before the one at "found" then swap 40091f164b19SBram Moolenaar // them 4010bbca7732SBram Moolenaar if (pos->col < posmatch->pos[found].col) 4011bbca7732SBram Moolenaar { 4012bbca7732SBram Moolenaar llpos_T tmp = *pos; 4013bbca7732SBram Moolenaar 4014bbca7732SBram Moolenaar *pos = posmatch->pos[found]; 4015bbca7732SBram Moolenaar posmatch->pos[found] = tmp; 4016bbca7732SBram Moolenaar } 4017bbca7732SBram Moolenaar } 4018bbca7732SBram Moolenaar else 4019bbca7732SBram Moolenaar found = i; 4020bbca7732SBram Moolenaar } 4021bbca7732SBram Moolenaar } 4022bbca7732SBram Moolenaar posmatch->cur = 0; 4023bbca7732SBram Moolenaar if (found >= 0) 4024bbca7732SBram Moolenaar { 4025bbca7732SBram Moolenaar colnr_T start = posmatch->pos[found].col == 0 4026bbca7732SBram Moolenaar ? 0 : posmatch->pos[found].col - 1; 4027bbca7732SBram Moolenaar colnr_T end = posmatch->pos[found].col == 0 4028bbca7732SBram Moolenaar ? MAXCOL : start + posmatch->pos[found].len; 4029bbca7732SBram Moolenaar 4030bbca7732SBram Moolenaar shl->lnum = lnum; 4031bbca7732SBram Moolenaar shl->rm.startpos[0].lnum = 0; 4032bbca7732SBram Moolenaar shl->rm.startpos[0].col = start; 4033bbca7732SBram Moolenaar shl->rm.endpos[0].lnum = 0; 4034bbca7732SBram Moolenaar shl->rm.endpos[0].col = end; 4035bbca7732SBram Moolenaar shl->is_addpos = TRUE; 4036bbca7732SBram Moolenaar posmatch->cur = found + 1; 4037bbca7732SBram Moolenaar return 1; 4038bbca7732SBram Moolenaar } 4039bbca7732SBram Moolenaar return 0; 4040bbca7732SBram Moolenaar } 4041bbca7732SBram Moolenaar 4042bbca7732SBram Moolenaar /* 4043bbca7732SBram Moolenaar * Search for a next 'hlsearch' or match. 4044bbca7732SBram Moolenaar * Uses shl->buf. 4045bbca7732SBram Moolenaar * Sets shl->lnum and shl->rm contents. 4046bbca7732SBram Moolenaar * Note: Assumes a previous match is always before "lnum", unless 4047bbca7732SBram Moolenaar * shl->lnum is zero. 4048bbca7732SBram Moolenaar * Careful: Any pointers for buffer lines will become invalid. 4049bbca7732SBram Moolenaar */ 4050bbca7732SBram Moolenaar static void 4051bbca7732SBram Moolenaar next_search_hl( 4052bbca7732SBram Moolenaar win_T *win, 4053bbca7732SBram Moolenaar match_T *search_hl, 4054bbca7732SBram Moolenaar match_T *shl, // points to search_hl or a match 4055bbca7732SBram Moolenaar linenr_T lnum, 4056bbca7732SBram Moolenaar colnr_T mincol, // minimal column for a match 4057bbca7732SBram Moolenaar matchitem_T *cur) // to retrieve match positions if any 4058bbca7732SBram Moolenaar { 4059bbca7732SBram Moolenaar linenr_T l; 4060bbca7732SBram Moolenaar colnr_T matchcol; 4061bbca7732SBram Moolenaar long nmatched; 406253989554SBram Moolenaar int called_emsg_before = called_emsg; 4063bbca7732SBram Moolenaar 4064bbca7732SBram Moolenaar // for :{range}s/pat only highlight inside the range 4065bbca7732SBram Moolenaar if (lnum < search_first_line || lnum > search_last_line) 4066bbca7732SBram Moolenaar { 4067bbca7732SBram Moolenaar shl->lnum = 0; 4068bbca7732SBram Moolenaar return; 4069bbca7732SBram Moolenaar } 4070bbca7732SBram Moolenaar 4071bbca7732SBram Moolenaar if (shl->lnum != 0) 4072bbca7732SBram Moolenaar { 40731f164b19SBram Moolenaar // Check for three situations: 40741f164b19SBram Moolenaar // 1. If the "lnum" is below a previous match, start a new search. 40751f164b19SBram Moolenaar // 2. If the previous match includes "mincol", use it. 40761f164b19SBram Moolenaar // 3. Continue after the previous match. 4077bbca7732SBram Moolenaar l = shl->lnum + shl->rm.endpos[0].lnum - shl->rm.startpos[0].lnum; 4078bbca7732SBram Moolenaar if (lnum > l) 4079bbca7732SBram Moolenaar shl->lnum = 0; 4080bbca7732SBram Moolenaar else if (lnum < l || shl->rm.endpos[0].col > mincol) 4081bbca7732SBram Moolenaar return; 4082bbca7732SBram Moolenaar } 4083bbca7732SBram Moolenaar 4084bbca7732SBram Moolenaar /* 4085bbca7732SBram Moolenaar * Repeat searching for a match until one is found that includes "mincol" 4086bbca7732SBram Moolenaar * or none is found in this line. 4087bbca7732SBram Moolenaar */ 4088bbca7732SBram Moolenaar for (;;) 4089bbca7732SBram Moolenaar { 4090bbca7732SBram Moolenaar # ifdef FEAT_RELTIME 40911f164b19SBram Moolenaar // Stop searching after passing the time limit. 4092bbca7732SBram Moolenaar if (profile_passed_limit(&(shl->tm))) 4093bbca7732SBram Moolenaar { 40941f164b19SBram Moolenaar shl->lnum = 0; // no match found in time 4095bbca7732SBram Moolenaar break; 4096bbca7732SBram Moolenaar } 4097bbca7732SBram Moolenaar # endif 40981f164b19SBram Moolenaar // Three situations: 40991f164b19SBram Moolenaar // 1. No useful previous match: search from start of line. 41001f164b19SBram Moolenaar // 2. Not Vi compatible or empty match: continue at next character. 41011f164b19SBram Moolenaar // Break the loop if this is beyond the end of the line. 41021f164b19SBram Moolenaar // 3. Vi compatible searching: continue at end of previous match. 4103bbca7732SBram Moolenaar if (shl->lnum == 0) 4104bbca7732SBram Moolenaar matchcol = 0; 4105bbca7732SBram Moolenaar else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL 4106bbca7732SBram Moolenaar || (shl->rm.endpos[0].lnum == 0 4107bbca7732SBram Moolenaar && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) 4108bbca7732SBram Moolenaar { 4109bbca7732SBram Moolenaar char_u *ml; 4110bbca7732SBram Moolenaar 4111bbca7732SBram Moolenaar matchcol = shl->rm.startpos[0].col; 4112bbca7732SBram Moolenaar ml = ml_get_buf(shl->buf, lnum, FALSE) + matchcol; 4113bbca7732SBram Moolenaar if (*ml == NUL) 4114bbca7732SBram Moolenaar { 4115bbca7732SBram Moolenaar ++matchcol; 4116bbca7732SBram Moolenaar shl->lnum = 0; 4117bbca7732SBram Moolenaar break; 4118bbca7732SBram Moolenaar } 4119bbca7732SBram Moolenaar if (has_mbyte) 4120bbca7732SBram Moolenaar matchcol += mb_ptr2len(ml); 4121bbca7732SBram Moolenaar else 4122bbca7732SBram Moolenaar ++matchcol; 4123bbca7732SBram Moolenaar } 4124bbca7732SBram Moolenaar else 4125bbca7732SBram Moolenaar matchcol = shl->rm.endpos[0].col; 4126bbca7732SBram Moolenaar 4127bbca7732SBram Moolenaar shl->lnum = lnum; 4128bbca7732SBram Moolenaar if (shl->rm.regprog != NULL) 4129bbca7732SBram Moolenaar { 41301f164b19SBram Moolenaar // Remember whether shl->rm is using a copy of the regprog in 41311f164b19SBram Moolenaar // cur->match. 4132bbca7732SBram Moolenaar int regprog_is_copy = (shl != search_hl && cur != NULL 4133bbca7732SBram Moolenaar && shl == &cur->hl 4134bbca7732SBram Moolenaar && cur->match.regprog == cur->hl.rm.regprog); 4135bbca7732SBram Moolenaar int timed_out = FALSE; 4136bbca7732SBram Moolenaar 4137bbca7732SBram Moolenaar nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, 4138bbca7732SBram Moolenaar matchcol, 4139bbca7732SBram Moolenaar #ifdef FEAT_RELTIME 4140bbca7732SBram Moolenaar &(shl->tm), &timed_out 4141bbca7732SBram Moolenaar #else 4142bbca7732SBram Moolenaar NULL, NULL 4143bbca7732SBram Moolenaar #endif 4144bbca7732SBram Moolenaar ); 41451f164b19SBram Moolenaar // Copy the regprog, in case it got freed and recompiled. 4146bbca7732SBram Moolenaar if (regprog_is_copy) 4147bbca7732SBram Moolenaar cur->match.regprog = cur->hl.rm.regprog; 4148bbca7732SBram Moolenaar 414953989554SBram Moolenaar if (called_emsg > called_emsg_before || got_int || timed_out) 4150bbca7732SBram Moolenaar { 41511f164b19SBram Moolenaar // Error while handling regexp: stop using this regexp. 4152bbca7732SBram Moolenaar if (shl == search_hl) 4153bbca7732SBram Moolenaar { 41541f164b19SBram Moolenaar // don't free regprog in the match list, it's a copy 4155bbca7732SBram Moolenaar vim_regfree(shl->rm.regprog); 4156bbca7732SBram Moolenaar set_no_hlsearch(TRUE); 4157bbca7732SBram Moolenaar } 4158bbca7732SBram Moolenaar shl->rm.regprog = NULL; 4159bbca7732SBram Moolenaar shl->lnum = 0; 41601f164b19SBram Moolenaar got_int = FALSE; // avoid the "Type :quit to exit Vim" message 4161bbca7732SBram Moolenaar break; 4162bbca7732SBram Moolenaar } 4163bbca7732SBram Moolenaar } 4164bbca7732SBram Moolenaar else if (cur != NULL) 4165bbca7732SBram Moolenaar nmatched = next_search_hl_pos(shl, lnum, &(cur->pos), matchcol); 4166bbca7732SBram Moolenaar else 4167bbca7732SBram Moolenaar nmatched = 0; 4168bbca7732SBram Moolenaar if (nmatched == 0) 4169bbca7732SBram Moolenaar { 41701f164b19SBram Moolenaar shl->lnum = 0; // no match found 4171bbca7732SBram Moolenaar break; 4172bbca7732SBram Moolenaar } 4173bbca7732SBram Moolenaar if (shl->rm.startpos[0].lnum > 0 4174bbca7732SBram Moolenaar || shl->rm.startpos[0].col >= mincol 4175bbca7732SBram Moolenaar || nmatched > 1 4176bbca7732SBram Moolenaar || shl->rm.endpos[0].col > mincol) 4177bbca7732SBram Moolenaar { 4178bbca7732SBram Moolenaar shl->lnum += shl->rm.startpos[0].lnum; 41791f164b19SBram Moolenaar break; // useful match found 4180bbca7732SBram Moolenaar } 4181bbca7732SBram Moolenaar } 4182bbca7732SBram Moolenaar } 4183bbca7732SBram Moolenaar 4184bbca7732SBram Moolenaar /* 4185bbca7732SBram Moolenaar * Advance to the match in window "wp" line "lnum" or past it. 4186bbca7732SBram Moolenaar */ 4187bbca7732SBram Moolenaar void 4188bbca7732SBram Moolenaar prepare_search_hl(win_T *wp, match_T *search_hl, linenr_T lnum) 4189bbca7732SBram Moolenaar { 41901f164b19SBram Moolenaar matchitem_T *cur; // points to the match list 41911f164b19SBram Moolenaar match_T *shl; // points to search_hl or a match 41921f164b19SBram Moolenaar int shl_flag; // flag to indicate whether search_hl 41931f164b19SBram Moolenaar // has been processed or not 41941f164b19SBram Moolenaar int pos_inprogress; // marks that position match search is 41951f164b19SBram Moolenaar // in progress 4196bbca7732SBram Moolenaar int n; 4197bbca7732SBram Moolenaar 41981f164b19SBram Moolenaar // When using a multi-line pattern, start searching at the top 41991f164b19SBram Moolenaar // of the window or just after a closed fold. 42001f164b19SBram Moolenaar // Do this both for search_hl and the match list. 4201bbca7732SBram Moolenaar cur = wp->w_match_head; 4202bbca7732SBram Moolenaar shl_flag = WIN_IS_POPUP(wp); // skip search_hl in a popup window 4203bbca7732SBram Moolenaar while (cur != NULL || shl_flag == FALSE) 4204bbca7732SBram Moolenaar { 4205bbca7732SBram Moolenaar if (shl_flag == FALSE) 4206bbca7732SBram Moolenaar { 4207bbca7732SBram Moolenaar shl = search_hl; 4208bbca7732SBram Moolenaar shl_flag = TRUE; 4209bbca7732SBram Moolenaar } 4210bbca7732SBram Moolenaar else 4211bbca7732SBram Moolenaar shl = &cur->hl; 4212bbca7732SBram Moolenaar if (shl->rm.regprog != NULL 4213bbca7732SBram Moolenaar && shl->lnum == 0 4214bbca7732SBram Moolenaar && re_multiline(shl->rm.regprog)) 4215bbca7732SBram Moolenaar { 4216bbca7732SBram Moolenaar if (shl->first_lnum == 0) 4217bbca7732SBram Moolenaar { 4218bbca7732SBram Moolenaar # ifdef FEAT_FOLDING 4219bbca7732SBram Moolenaar for (shl->first_lnum = lnum; 4220bbca7732SBram Moolenaar shl->first_lnum > wp->w_topline; --shl->first_lnum) 4221bbca7732SBram Moolenaar if (hasFoldingWin(wp, shl->first_lnum - 1, 4222bbca7732SBram Moolenaar NULL, NULL, TRUE, NULL)) 4223bbca7732SBram Moolenaar break; 4224bbca7732SBram Moolenaar # else 4225bbca7732SBram Moolenaar shl->first_lnum = wp->w_topline; 4226bbca7732SBram Moolenaar # endif 4227bbca7732SBram Moolenaar } 4228bbca7732SBram Moolenaar if (cur != NULL) 4229bbca7732SBram Moolenaar cur->pos.cur = 0; 4230bbca7732SBram Moolenaar pos_inprogress = TRUE; 4231bbca7732SBram Moolenaar n = 0; 4232bbca7732SBram Moolenaar while (shl->first_lnum < lnum && (shl->rm.regprog != NULL 4233bbca7732SBram Moolenaar || (cur != NULL && pos_inprogress))) 4234bbca7732SBram Moolenaar { 4235bbca7732SBram Moolenaar next_search_hl(wp, search_hl, shl, shl->first_lnum, (colnr_T)n, 4236bbca7732SBram Moolenaar shl == search_hl ? NULL : cur); 4237bbca7732SBram Moolenaar pos_inprogress = cur == NULL || cur->pos.cur == 0 4238bbca7732SBram Moolenaar ? FALSE : TRUE; 4239bbca7732SBram Moolenaar if (shl->lnum != 0) 4240bbca7732SBram Moolenaar { 4241bbca7732SBram Moolenaar shl->first_lnum = shl->lnum 4242bbca7732SBram Moolenaar + shl->rm.endpos[0].lnum 4243bbca7732SBram Moolenaar - shl->rm.startpos[0].lnum; 4244bbca7732SBram Moolenaar n = shl->rm.endpos[0].col; 4245bbca7732SBram Moolenaar } 4246bbca7732SBram Moolenaar else 4247bbca7732SBram Moolenaar { 4248bbca7732SBram Moolenaar ++shl->first_lnum; 4249bbca7732SBram Moolenaar n = 0; 4250bbca7732SBram Moolenaar } 4251bbca7732SBram Moolenaar } 4252bbca7732SBram Moolenaar } 4253bbca7732SBram Moolenaar if (shl != search_hl && cur != NULL) 4254bbca7732SBram Moolenaar cur = cur->next; 4255bbca7732SBram Moolenaar } 4256bbca7732SBram Moolenaar } 4257bbca7732SBram Moolenaar 4258bbca7732SBram Moolenaar /* 4259bbca7732SBram Moolenaar * Prepare for 'hlsearch' and match highlighting in one window line. 4260bbca7732SBram Moolenaar * Return TRUE if there is such highlighting and set "search_attr" to the 4261bbca7732SBram Moolenaar * current highlight attribute. 4262bbca7732SBram Moolenaar */ 4263bbca7732SBram Moolenaar int 4264bbca7732SBram Moolenaar prepare_search_hl_line( 4265bbca7732SBram Moolenaar win_T *wp, 4266bbca7732SBram Moolenaar linenr_T lnum, 4267bbca7732SBram Moolenaar colnr_T mincol, 4268bbca7732SBram Moolenaar char_u **line, 4269bbca7732SBram Moolenaar match_T *search_hl, 4270bbca7732SBram Moolenaar int *search_attr) 4271bbca7732SBram Moolenaar { 4272bbca7732SBram Moolenaar matchitem_T *cur; // points to the match list 4273bbca7732SBram Moolenaar match_T *shl; // points to search_hl or a match 4274bbca7732SBram Moolenaar int shl_flag; // flag to indicate whether search_hl 4275bbca7732SBram Moolenaar // has been processed or not 4276bbca7732SBram Moolenaar int area_highlighting = FALSE; 4277bbca7732SBram Moolenaar 4278bbca7732SBram Moolenaar /* 4279bbca7732SBram Moolenaar * Handle highlighting the last used search pattern and matches. 4280bbca7732SBram Moolenaar * Do this for both search_hl and the match list. 4281bbca7732SBram Moolenaar * Do not use search_hl in a popup window. 4282bbca7732SBram Moolenaar */ 4283bbca7732SBram Moolenaar cur = wp->w_match_head; 4284bbca7732SBram Moolenaar shl_flag = WIN_IS_POPUP(wp); 4285bbca7732SBram Moolenaar while (cur != NULL || shl_flag == FALSE) 4286bbca7732SBram Moolenaar { 4287bbca7732SBram Moolenaar if (shl_flag == FALSE) 4288bbca7732SBram Moolenaar { 4289bbca7732SBram Moolenaar shl = search_hl; 4290bbca7732SBram Moolenaar shl_flag = TRUE; 4291bbca7732SBram Moolenaar } 4292bbca7732SBram Moolenaar else 4293bbca7732SBram Moolenaar shl = &cur->hl; 4294bbca7732SBram Moolenaar shl->startcol = MAXCOL; 4295bbca7732SBram Moolenaar shl->endcol = MAXCOL; 4296bbca7732SBram Moolenaar shl->attr_cur = 0; 4297bbca7732SBram Moolenaar shl->is_addpos = FALSE; 4298bbca7732SBram Moolenaar if (cur != NULL) 4299bbca7732SBram Moolenaar cur->pos.cur = 0; 4300bbca7732SBram Moolenaar next_search_hl(wp, search_hl, shl, lnum, mincol, 4301bbca7732SBram Moolenaar shl == search_hl ? NULL : cur); 4302bbca7732SBram Moolenaar 4303bbca7732SBram Moolenaar // Need to get the line again, a multi-line regexp may have made it 4304bbca7732SBram Moolenaar // invalid. 4305bbca7732SBram Moolenaar *line = ml_get_buf(wp->w_buffer, lnum, FALSE); 4306bbca7732SBram Moolenaar 4307bbca7732SBram Moolenaar if (shl->lnum != 0 && shl->lnum <= lnum) 4308bbca7732SBram Moolenaar { 4309bbca7732SBram Moolenaar if (shl->lnum == lnum) 4310bbca7732SBram Moolenaar shl->startcol = shl->rm.startpos[0].col; 4311bbca7732SBram Moolenaar else 4312bbca7732SBram Moolenaar shl->startcol = 0; 4313bbca7732SBram Moolenaar if (lnum == shl->lnum + shl->rm.endpos[0].lnum 4314bbca7732SBram Moolenaar - shl->rm.startpos[0].lnum) 4315bbca7732SBram Moolenaar shl->endcol = shl->rm.endpos[0].col; 4316bbca7732SBram Moolenaar else 4317bbca7732SBram Moolenaar shl->endcol = MAXCOL; 4318bbca7732SBram Moolenaar // Highlight one character for an empty match. 4319bbca7732SBram Moolenaar if (shl->startcol == shl->endcol) 4320bbca7732SBram Moolenaar { 4321bbca7732SBram Moolenaar if (has_mbyte && (*line)[shl->endcol] != NUL) 4322bbca7732SBram Moolenaar shl->endcol += (*mb_ptr2len)((*line) + shl->endcol); 4323bbca7732SBram Moolenaar else 4324bbca7732SBram Moolenaar ++shl->endcol; 4325bbca7732SBram Moolenaar } 43261f164b19SBram Moolenaar if ((long)shl->startcol < mincol) // match at leftcol 4327bbca7732SBram Moolenaar { 4328bbca7732SBram Moolenaar shl->attr_cur = shl->attr; 4329bbca7732SBram Moolenaar *search_attr = shl->attr; 4330bbca7732SBram Moolenaar } 4331bbca7732SBram Moolenaar area_highlighting = TRUE; 4332bbca7732SBram Moolenaar } 4333bbca7732SBram Moolenaar if (shl != search_hl && cur != NULL) 4334bbca7732SBram Moolenaar cur = cur->next; 4335bbca7732SBram Moolenaar } 4336bbca7732SBram Moolenaar return area_highlighting; 4337bbca7732SBram Moolenaar } 4338bbca7732SBram Moolenaar 4339bbca7732SBram Moolenaar /* 4340bbca7732SBram Moolenaar * For a position in a line: Check for start/end of 'hlsearch' and other 4341bbca7732SBram Moolenaar * matches. 4342bbca7732SBram Moolenaar * After end, check for start/end of next match. 4343bbca7732SBram Moolenaar * When another match, have to check for start again. 4344bbca7732SBram Moolenaar * Watch out for matching an empty string! 434532aa1020SBram Moolenaar * Return the updated search_attr. 4346bbca7732SBram Moolenaar */ 4347bbca7732SBram Moolenaar int 4348bbca7732SBram Moolenaar update_search_hl( 4349bbca7732SBram Moolenaar win_T *wp, 4350bbca7732SBram Moolenaar linenr_T lnum, 4351bbca7732SBram Moolenaar colnr_T col, 4352bbca7732SBram Moolenaar char_u **line, 4353bbca7732SBram Moolenaar match_T *search_hl, 43541f164b19SBram Moolenaar int *has_match_conc UNUSED, 43551f164b19SBram Moolenaar int *match_conc UNUSED, 4356bbca7732SBram Moolenaar int did_line_attr, 4357bbca7732SBram Moolenaar int lcs_eol_one) 4358bbca7732SBram Moolenaar { 4359bbca7732SBram Moolenaar matchitem_T *cur; // points to the match list 4360bbca7732SBram Moolenaar match_T *shl; // points to search_hl or a match 4361bbca7732SBram Moolenaar int shl_flag; // flag to indicate whether search_hl 4362bbca7732SBram Moolenaar // has been processed or not 4363bbca7732SBram Moolenaar int pos_inprogress; // marks that position match search is in 4364bbca7732SBram Moolenaar // progress 4365bbca7732SBram Moolenaar int search_attr = 0; 4366bbca7732SBram Moolenaar 4367bbca7732SBram Moolenaar 4368bbca7732SBram Moolenaar // Do this for 'search_hl' and the match list (ordered by priority). 4369bbca7732SBram Moolenaar cur = wp->w_match_head; 4370bbca7732SBram Moolenaar shl_flag = WIN_IS_POPUP(wp); 4371bbca7732SBram Moolenaar while (cur != NULL || shl_flag == FALSE) 4372bbca7732SBram Moolenaar { 4373bbca7732SBram Moolenaar if (shl_flag == FALSE 4374bbca7732SBram Moolenaar && ((cur != NULL 4375bbca7732SBram Moolenaar && cur->priority > SEARCH_HL_PRIORITY) 4376bbca7732SBram Moolenaar || cur == NULL)) 4377bbca7732SBram Moolenaar { 4378bbca7732SBram Moolenaar shl = search_hl; 4379bbca7732SBram Moolenaar shl_flag = TRUE; 4380bbca7732SBram Moolenaar } 4381bbca7732SBram Moolenaar else 4382bbca7732SBram Moolenaar shl = &cur->hl; 4383bbca7732SBram Moolenaar if (cur != NULL) 4384bbca7732SBram Moolenaar cur->pos.cur = 0; 4385bbca7732SBram Moolenaar pos_inprogress = TRUE; 4386bbca7732SBram Moolenaar while (shl->rm.regprog != NULL || (cur != NULL && pos_inprogress)) 4387bbca7732SBram Moolenaar { 4388bbca7732SBram Moolenaar if (shl->startcol != MAXCOL 4389bbca7732SBram Moolenaar && col >= shl->startcol 4390bbca7732SBram Moolenaar && col < shl->endcol) 4391bbca7732SBram Moolenaar { 43921614a149SBram Moolenaar int next_col = col + mb_ptr2len(*line + col); 4393bbca7732SBram Moolenaar 4394bbca7732SBram Moolenaar if (shl->endcol < next_col) 4395bbca7732SBram Moolenaar shl->endcol = next_col; 4396bbca7732SBram Moolenaar shl->attr_cur = shl->attr; 4397bbca7732SBram Moolenaar # ifdef FEAT_CONCEAL 4398bbca7732SBram Moolenaar // Match with the "Conceal" group results in hiding 4399bbca7732SBram Moolenaar // the match. 4400bbca7732SBram Moolenaar if (cur != NULL 4401bbca7732SBram Moolenaar && shl != search_hl 4402bbca7732SBram Moolenaar && syn_name2id((char_u *)"Conceal") == cur->hlg_id) 4403bbca7732SBram Moolenaar { 4404bbca7732SBram Moolenaar *has_match_conc = col == shl->startcol ? 2 : 1; 4405bbca7732SBram Moolenaar *match_conc = cur->conceal_char; 4406bbca7732SBram Moolenaar } 4407bbca7732SBram Moolenaar else 4408bbca7732SBram Moolenaar *has_match_conc = *match_conc = 0; 4409bbca7732SBram Moolenaar # endif 4410bbca7732SBram Moolenaar } 4411bbca7732SBram Moolenaar else if (col == shl->endcol) 4412bbca7732SBram Moolenaar { 4413bbca7732SBram Moolenaar shl->attr_cur = 0; 4414bbca7732SBram Moolenaar next_search_hl(wp, search_hl, shl, lnum, col, 4415bbca7732SBram Moolenaar shl == search_hl ? NULL : cur); 4416bbca7732SBram Moolenaar pos_inprogress = !(cur == NULL || cur->pos.cur == 0); 4417bbca7732SBram Moolenaar 4418bbca7732SBram Moolenaar // Need to get the line again, a multi-line regexp may have 4419bbca7732SBram Moolenaar // made it invalid. 4420bbca7732SBram Moolenaar *line = ml_get_buf(wp->w_buffer, lnum, FALSE); 4421bbca7732SBram Moolenaar 4422bbca7732SBram Moolenaar if (shl->lnum == lnum) 4423bbca7732SBram Moolenaar { 4424bbca7732SBram Moolenaar shl->startcol = shl->rm.startpos[0].col; 4425bbca7732SBram Moolenaar if (shl->rm.endpos[0].lnum == 0) 4426bbca7732SBram Moolenaar shl->endcol = shl->rm.endpos[0].col; 4427bbca7732SBram Moolenaar else 4428bbca7732SBram Moolenaar shl->endcol = MAXCOL; 4429bbca7732SBram Moolenaar 4430bbca7732SBram Moolenaar if (shl->startcol == shl->endcol) 4431bbca7732SBram Moolenaar { 44321f164b19SBram Moolenaar // highlight empty match, try again after 44331f164b19SBram Moolenaar // it 4434bbca7732SBram Moolenaar if (has_mbyte) 4435bbca7732SBram Moolenaar shl->endcol += (*mb_ptr2len)(*line + shl->endcol); 4436bbca7732SBram Moolenaar else 4437bbca7732SBram Moolenaar ++shl->endcol; 4438bbca7732SBram Moolenaar } 4439bbca7732SBram Moolenaar 44401f164b19SBram Moolenaar // Loop to check if the match starts at the 44411f164b19SBram Moolenaar // current position 4442bbca7732SBram Moolenaar continue; 4443bbca7732SBram Moolenaar } 4444bbca7732SBram Moolenaar } 4445bbca7732SBram Moolenaar break; 4446bbca7732SBram Moolenaar } 4447bbca7732SBram Moolenaar if (shl != search_hl && cur != NULL) 4448bbca7732SBram Moolenaar cur = cur->next; 4449bbca7732SBram Moolenaar } 4450bbca7732SBram Moolenaar 4451bbca7732SBram Moolenaar // Use attributes from match with highest priority among 'search_hl' and 4452bbca7732SBram Moolenaar // the match list. 4453bbca7732SBram Moolenaar cur = wp->w_match_head; 4454bbca7732SBram Moolenaar shl_flag = WIN_IS_POPUP(wp); 4455bbca7732SBram Moolenaar while (cur != NULL || shl_flag == FALSE) 4456bbca7732SBram Moolenaar { 4457bbca7732SBram Moolenaar if (shl_flag == FALSE 4458bbca7732SBram Moolenaar && ((cur != NULL 4459bbca7732SBram Moolenaar && cur->priority > SEARCH_HL_PRIORITY) 4460bbca7732SBram Moolenaar || cur == NULL)) 4461bbca7732SBram Moolenaar { 4462bbca7732SBram Moolenaar shl = search_hl; 4463bbca7732SBram Moolenaar shl_flag = TRUE; 4464bbca7732SBram Moolenaar } 4465bbca7732SBram Moolenaar else 4466bbca7732SBram Moolenaar shl = &cur->hl; 4467bbca7732SBram Moolenaar if (shl->attr_cur != 0) 4468bbca7732SBram Moolenaar search_attr = shl->attr_cur; 4469bbca7732SBram Moolenaar if (shl != search_hl && cur != NULL) 4470bbca7732SBram Moolenaar cur = cur->next; 4471bbca7732SBram Moolenaar } 44721f164b19SBram Moolenaar // Only highlight one character after the last column. 4473bbca7732SBram Moolenaar if (*(*line + col) == NUL && (did_line_attr >= 1 4474bbca7732SBram Moolenaar || (wp->w_p_list && lcs_eol_one == -1))) 4475bbca7732SBram Moolenaar search_attr = 0; 4476bbca7732SBram Moolenaar return search_attr; 4477bbca7732SBram Moolenaar } 4478bbca7732SBram Moolenaar 4479bbca7732SBram Moolenaar int 4480bbca7732SBram Moolenaar get_prevcol_hl_flag(win_T *wp, match_T *search_hl, long curcol) 4481bbca7732SBram Moolenaar { 4482bbca7732SBram Moolenaar long prevcol = curcol; 4483bbca7732SBram Moolenaar int prevcol_hl_flag = FALSE; 4484bbca7732SBram Moolenaar matchitem_T *cur; // points to the match list 4485bbca7732SBram Moolenaar 4486bbca7732SBram Moolenaar // we're not really at that column when skipping some text 4487bbca7732SBram Moolenaar if ((long)(wp->w_p_wrap ? wp->w_skipcol : wp->w_leftcol) > prevcol) 4488bbca7732SBram Moolenaar ++prevcol; 4489bbca7732SBram Moolenaar 4490bbca7732SBram Moolenaar if (!search_hl->is_addpos && prevcol == (long)search_hl->startcol) 4491bbca7732SBram Moolenaar prevcol_hl_flag = TRUE; 4492bbca7732SBram Moolenaar else 4493bbca7732SBram Moolenaar { 4494bbca7732SBram Moolenaar cur = wp->w_match_head; 4495bbca7732SBram Moolenaar while (cur != NULL) 4496bbca7732SBram Moolenaar { 4497bbca7732SBram Moolenaar if (!cur->hl.is_addpos && prevcol == (long)cur->hl.startcol) 4498bbca7732SBram Moolenaar { 4499bbca7732SBram Moolenaar prevcol_hl_flag = TRUE; 4500bbca7732SBram Moolenaar break; 4501bbca7732SBram Moolenaar } 4502bbca7732SBram Moolenaar cur = cur->next; 4503bbca7732SBram Moolenaar } 4504bbca7732SBram Moolenaar } 4505bbca7732SBram Moolenaar return prevcol_hl_flag; 4506bbca7732SBram Moolenaar } 4507bbca7732SBram Moolenaar 4508bbca7732SBram Moolenaar /* 4509bbca7732SBram Moolenaar * Get highlighting for the char after the text in "char_attr" from 'hlsearch' 4510bbca7732SBram Moolenaar * or match highlighting. 4511bbca7732SBram Moolenaar */ 4512bbca7732SBram Moolenaar void 4513bbca7732SBram Moolenaar get_search_match_hl(win_T *wp, match_T *search_hl, long col, int *char_attr) 4514bbca7732SBram Moolenaar { 4515bbca7732SBram Moolenaar matchitem_T *cur; // points to the match list 4516bbca7732SBram Moolenaar match_T *shl; // points to search_hl or a match 4517bbca7732SBram Moolenaar int shl_flag; // flag to indicate whether search_hl 4518bbca7732SBram Moolenaar // has been processed or not 4519bbca7732SBram Moolenaar 4520bbca7732SBram Moolenaar cur = wp->w_match_head; 4521bbca7732SBram Moolenaar shl_flag = WIN_IS_POPUP(wp); 4522bbca7732SBram Moolenaar while (cur != NULL || shl_flag == FALSE) 4523bbca7732SBram Moolenaar { 4524bbca7732SBram Moolenaar if (shl_flag == FALSE 4525bbca7732SBram Moolenaar && ((cur != NULL 4526bbca7732SBram Moolenaar && cur->priority > SEARCH_HL_PRIORITY) 4527bbca7732SBram Moolenaar || cur == NULL)) 4528bbca7732SBram Moolenaar { 4529bbca7732SBram Moolenaar shl = search_hl; 4530bbca7732SBram Moolenaar shl_flag = TRUE; 4531bbca7732SBram Moolenaar } 4532bbca7732SBram Moolenaar else 4533bbca7732SBram Moolenaar shl = &cur->hl; 4534bbca7732SBram Moolenaar if (col - 1 == (long)shl->startcol 4535bbca7732SBram Moolenaar && (shl == search_hl || !shl->is_addpos)) 4536bbca7732SBram Moolenaar *char_attr = shl->attr; 4537bbca7732SBram Moolenaar if (shl != search_hl && cur != NULL) 4538bbca7732SBram Moolenaar cur = cur->next; 4539bbca7732SBram Moolenaar } 4540bbca7732SBram Moolenaar } 4541bbca7732SBram Moolenaar 4542bbca7732SBram Moolenaar #endif // FEAT_SEARCH_EXTRA 454329b7d7a9SBram Moolenaar 4544c61a48d2SBram Moolenaar #if defined(FEAT_EVAL) || defined(PROTO) 4545c61a48d2SBram Moolenaar # ifdef FEAT_SEARCH_EXTRA 454629b7d7a9SBram Moolenaar static int 454729b7d7a9SBram Moolenaar matchadd_dict_arg(typval_T *tv, char_u **conceal_char, win_T **win) 454829b7d7a9SBram Moolenaar { 454929b7d7a9SBram Moolenaar dictitem_T *di; 455029b7d7a9SBram Moolenaar 455129b7d7a9SBram Moolenaar if (tv->v_type != VAR_DICT) 455229b7d7a9SBram Moolenaar { 455329b7d7a9SBram Moolenaar emsg(_(e_dictreq)); 455429b7d7a9SBram Moolenaar return FAIL; 455529b7d7a9SBram Moolenaar } 455629b7d7a9SBram Moolenaar 455729b7d7a9SBram Moolenaar if (dict_find(tv->vval.v_dict, (char_u *)"conceal", -1) != NULL) 455829b7d7a9SBram Moolenaar *conceal_char = dict_get_string(tv->vval.v_dict, 455929b7d7a9SBram Moolenaar (char_u *)"conceal", FALSE); 456029b7d7a9SBram Moolenaar 456129b7d7a9SBram Moolenaar if ((di = dict_find(tv->vval.v_dict, (char_u *)"window", -1)) != NULL) 456229b7d7a9SBram Moolenaar { 456329b7d7a9SBram Moolenaar *win = find_win_by_nr_or_id(&di->di_tv); 456429b7d7a9SBram Moolenaar if (*win == NULL) 456529b7d7a9SBram Moolenaar { 456629b7d7a9SBram Moolenaar emsg(_(e_invalwindow)); 456729b7d7a9SBram Moolenaar return FAIL; 456829b7d7a9SBram Moolenaar } 456929b7d7a9SBram Moolenaar } 457029b7d7a9SBram Moolenaar 457129b7d7a9SBram Moolenaar return OK; 457229b7d7a9SBram Moolenaar } 457329b7d7a9SBram Moolenaar #endif 457429b7d7a9SBram Moolenaar 457529b7d7a9SBram Moolenaar /* 45767dfb016dSBram Moolenaar * "clearmatches()" function 45777dfb016dSBram Moolenaar */ 45787dfb016dSBram Moolenaar void 45797dfb016dSBram Moolenaar f_clearmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 45807dfb016dSBram Moolenaar { 45817dfb016dSBram Moolenaar #ifdef FEAT_SEARCH_EXTRA 45827dfb016dSBram Moolenaar win_T *win = get_optional_window(argvars, 0); 45837dfb016dSBram Moolenaar 45847dfb016dSBram Moolenaar if (win != NULL) 45857dfb016dSBram Moolenaar clear_matches(win); 45867dfb016dSBram Moolenaar #endif 45877dfb016dSBram Moolenaar } 45887dfb016dSBram Moolenaar 45897dfb016dSBram Moolenaar /* 459029b7d7a9SBram Moolenaar * "getmatches()" function 459129b7d7a9SBram Moolenaar */ 459229b7d7a9SBram Moolenaar void 459329b7d7a9SBram Moolenaar f_getmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 459429b7d7a9SBram Moolenaar { 459529b7d7a9SBram Moolenaar # ifdef FEAT_SEARCH_EXTRA 459629b7d7a9SBram Moolenaar dict_T *dict; 459729b7d7a9SBram Moolenaar matchitem_T *cur; 459829b7d7a9SBram Moolenaar int i; 459929b7d7a9SBram Moolenaar win_T *win = get_optional_window(argvars, 0); 460029b7d7a9SBram Moolenaar 460129b7d7a9SBram Moolenaar if (rettv_list_alloc(rettv) == FAIL || win == NULL) 460229b7d7a9SBram Moolenaar return; 460329b7d7a9SBram Moolenaar 460429b7d7a9SBram Moolenaar cur = win->w_match_head; 460529b7d7a9SBram Moolenaar while (cur != NULL) 460629b7d7a9SBram Moolenaar { 460729b7d7a9SBram Moolenaar dict = dict_alloc(); 460829b7d7a9SBram Moolenaar if (dict == NULL) 460929b7d7a9SBram Moolenaar return; 461029b7d7a9SBram Moolenaar if (cur->match.regprog == NULL) 461129b7d7a9SBram Moolenaar { 46121f164b19SBram Moolenaar // match added with matchaddpos() 461329b7d7a9SBram Moolenaar for (i = 0; i < MAXPOSMATCH; ++i) 461429b7d7a9SBram Moolenaar { 461529b7d7a9SBram Moolenaar llpos_T *llpos; 461629b7d7a9SBram Moolenaar char buf[30]; // use 30 to avoid compiler warning 461729b7d7a9SBram Moolenaar list_T *l; 461829b7d7a9SBram Moolenaar 461929b7d7a9SBram Moolenaar llpos = &cur->pos.pos[i]; 462029b7d7a9SBram Moolenaar if (llpos->lnum == 0) 462129b7d7a9SBram Moolenaar break; 462229b7d7a9SBram Moolenaar l = list_alloc(); 462329b7d7a9SBram Moolenaar if (l == NULL) 462429b7d7a9SBram Moolenaar break; 462529b7d7a9SBram Moolenaar list_append_number(l, (varnumber_T)llpos->lnum); 462629b7d7a9SBram Moolenaar if (llpos->col > 0) 462729b7d7a9SBram Moolenaar { 462829b7d7a9SBram Moolenaar list_append_number(l, (varnumber_T)llpos->col); 462929b7d7a9SBram Moolenaar list_append_number(l, (varnumber_T)llpos->len); 463029b7d7a9SBram Moolenaar } 463129b7d7a9SBram Moolenaar sprintf(buf, "pos%d", i + 1); 463229b7d7a9SBram Moolenaar dict_add_list(dict, buf, l); 463329b7d7a9SBram Moolenaar } 463429b7d7a9SBram Moolenaar } 463529b7d7a9SBram Moolenaar else 463629b7d7a9SBram Moolenaar { 463729b7d7a9SBram Moolenaar dict_add_string(dict, "pattern", cur->pattern); 463829b7d7a9SBram Moolenaar } 463929b7d7a9SBram Moolenaar dict_add_string(dict, "group", syn_id2name(cur->hlg_id)); 464029b7d7a9SBram Moolenaar dict_add_number(dict, "priority", (long)cur->priority); 464129b7d7a9SBram Moolenaar dict_add_number(dict, "id", (long)cur->id); 464229b7d7a9SBram Moolenaar # if defined(FEAT_CONCEAL) 464329b7d7a9SBram Moolenaar if (cur->conceal_char) 464429b7d7a9SBram Moolenaar { 464529b7d7a9SBram Moolenaar char_u buf[MB_MAXBYTES + 1]; 464629b7d7a9SBram Moolenaar 464729b7d7a9SBram Moolenaar buf[(*mb_char2bytes)((int)cur->conceal_char, buf)] = NUL; 464829b7d7a9SBram Moolenaar dict_add_string(dict, "conceal", (char_u *)&buf); 464929b7d7a9SBram Moolenaar } 465029b7d7a9SBram Moolenaar # endif 465129b7d7a9SBram Moolenaar list_append_dict(rettv->vval.v_list, dict); 465229b7d7a9SBram Moolenaar cur = cur->next; 465329b7d7a9SBram Moolenaar } 465429b7d7a9SBram Moolenaar # endif 465529b7d7a9SBram Moolenaar } 465629b7d7a9SBram Moolenaar 465729b7d7a9SBram Moolenaar /* 46587dfb016dSBram Moolenaar * "setmatches()" function 46597dfb016dSBram Moolenaar */ 46607dfb016dSBram Moolenaar void 46617dfb016dSBram Moolenaar f_setmatches(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 46627dfb016dSBram Moolenaar { 46637dfb016dSBram Moolenaar #ifdef FEAT_SEARCH_EXTRA 46647dfb016dSBram Moolenaar list_T *l; 46657dfb016dSBram Moolenaar listitem_T *li; 46667dfb016dSBram Moolenaar dict_T *d; 46677dfb016dSBram Moolenaar list_T *s = NULL; 46687dfb016dSBram Moolenaar win_T *win = get_optional_window(argvars, 1); 46697dfb016dSBram Moolenaar 46707dfb016dSBram Moolenaar rettv->vval.v_number = -1; 46717dfb016dSBram Moolenaar if (argvars[0].v_type != VAR_LIST) 46727dfb016dSBram Moolenaar { 46737dfb016dSBram Moolenaar emsg(_(e_listreq)); 46747dfb016dSBram Moolenaar return; 46757dfb016dSBram Moolenaar } 46767dfb016dSBram Moolenaar if (win == NULL) 46777dfb016dSBram Moolenaar return; 46787dfb016dSBram Moolenaar 46797dfb016dSBram Moolenaar if ((l = argvars[0].vval.v_list) != NULL) 46807dfb016dSBram Moolenaar { 46811f164b19SBram Moolenaar // To some extent make sure that we are dealing with a list from 46821f164b19SBram Moolenaar // "getmatches()". 46837dfb016dSBram Moolenaar li = l->lv_first; 46847dfb016dSBram Moolenaar while (li != NULL) 46857dfb016dSBram Moolenaar { 46867dfb016dSBram Moolenaar if (li->li_tv.v_type != VAR_DICT 46877dfb016dSBram Moolenaar || (d = li->li_tv.vval.v_dict) == NULL) 46887dfb016dSBram Moolenaar { 46897dfb016dSBram Moolenaar emsg(_(e_invarg)); 46907dfb016dSBram Moolenaar return; 46917dfb016dSBram Moolenaar } 46927dfb016dSBram Moolenaar if (!(dict_find(d, (char_u *)"group", -1) != NULL 46937dfb016dSBram Moolenaar && (dict_find(d, (char_u *)"pattern", -1) != NULL 46947dfb016dSBram Moolenaar || dict_find(d, (char_u *)"pos1", -1) != NULL) 46957dfb016dSBram Moolenaar && dict_find(d, (char_u *)"priority", -1) != NULL 46967dfb016dSBram Moolenaar && dict_find(d, (char_u *)"id", -1) != NULL)) 46977dfb016dSBram Moolenaar { 46987dfb016dSBram Moolenaar emsg(_(e_invarg)); 46997dfb016dSBram Moolenaar return; 47007dfb016dSBram Moolenaar } 47017dfb016dSBram Moolenaar li = li->li_next; 47027dfb016dSBram Moolenaar } 47037dfb016dSBram Moolenaar 47047dfb016dSBram Moolenaar clear_matches(win); 47057dfb016dSBram Moolenaar li = l->lv_first; 47067dfb016dSBram Moolenaar while (li != NULL) 47077dfb016dSBram Moolenaar { 47087dfb016dSBram Moolenaar int i = 0; 47097dfb016dSBram Moolenaar char buf[30]; // use 30 to avoid compiler warning 47107dfb016dSBram Moolenaar dictitem_T *di; 47117dfb016dSBram Moolenaar char_u *group; 47127dfb016dSBram Moolenaar int priority; 47137dfb016dSBram Moolenaar int id; 47147dfb016dSBram Moolenaar char_u *conceal; 47157dfb016dSBram Moolenaar 47167dfb016dSBram Moolenaar d = li->li_tv.vval.v_dict; 47177dfb016dSBram Moolenaar if (dict_find(d, (char_u *)"pattern", -1) == NULL) 47187dfb016dSBram Moolenaar { 47197dfb016dSBram Moolenaar if (s == NULL) 47207dfb016dSBram Moolenaar { 47217dfb016dSBram Moolenaar s = list_alloc(); 47227dfb016dSBram Moolenaar if (s == NULL) 47237dfb016dSBram Moolenaar return; 47247dfb016dSBram Moolenaar } 47257dfb016dSBram Moolenaar 47261f164b19SBram Moolenaar // match from matchaddpos() 47277dfb016dSBram Moolenaar for (i = 1; i < 9; i++) 47287dfb016dSBram Moolenaar { 47297dfb016dSBram Moolenaar sprintf((char *)buf, (char *)"pos%d", i); 47307dfb016dSBram Moolenaar if ((di = dict_find(d, (char_u *)buf, -1)) != NULL) 47317dfb016dSBram Moolenaar { 47327dfb016dSBram Moolenaar if (di->di_tv.v_type != VAR_LIST) 47337dfb016dSBram Moolenaar return; 47347dfb016dSBram Moolenaar 47357dfb016dSBram Moolenaar list_append_tv(s, &di->di_tv); 47367dfb016dSBram Moolenaar s->lv_refcount++; 47377dfb016dSBram Moolenaar } 47387dfb016dSBram Moolenaar else 47397dfb016dSBram Moolenaar break; 47407dfb016dSBram Moolenaar } 47417dfb016dSBram Moolenaar } 47427dfb016dSBram Moolenaar 47437dfb016dSBram Moolenaar group = dict_get_string(d, (char_u *)"group", TRUE); 47447dfb016dSBram Moolenaar priority = (int)dict_get_number(d, (char_u *)"priority"); 47457dfb016dSBram Moolenaar id = (int)dict_get_number(d, (char_u *)"id"); 47467dfb016dSBram Moolenaar conceal = dict_find(d, (char_u *)"conceal", -1) != NULL 47477dfb016dSBram Moolenaar ? dict_get_string(d, (char_u *)"conceal", TRUE) 47487dfb016dSBram Moolenaar : NULL; 47497dfb016dSBram Moolenaar if (i == 0) 47507dfb016dSBram Moolenaar { 47517dfb016dSBram Moolenaar match_add(win, group, 47527dfb016dSBram Moolenaar dict_get_string(d, (char_u *)"pattern", FALSE), 47537dfb016dSBram Moolenaar priority, id, NULL, conceal); 47547dfb016dSBram Moolenaar } 47557dfb016dSBram Moolenaar else 47567dfb016dSBram Moolenaar { 47577dfb016dSBram Moolenaar match_add(win, group, NULL, priority, id, s, conceal); 47587dfb016dSBram Moolenaar list_unref(s); 47597dfb016dSBram Moolenaar s = NULL; 47607dfb016dSBram Moolenaar } 47617dfb016dSBram Moolenaar vim_free(group); 47627dfb016dSBram Moolenaar vim_free(conceal); 47637dfb016dSBram Moolenaar 47647dfb016dSBram Moolenaar li = li->li_next; 47657dfb016dSBram Moolenaar } 47667dfb016dSBram Moolenaar rettv->vval.v_number = 0; 47677dfb016dSBram Moolenaar } 47687dfb016dSBram Moolenaar #endif 47697dfb016dSBram Moolenaar } 47707dfb016dSBram Moolenaar 47717dfb016dSBram Moolenaar /* 477229b7d7a9SBram Moolenaar * "matchadd()" function 477329b7d7a9SBram Moolenaar */ 477429b7d7a9SBram Moolenaar void 477529b7d7a9SBram Moolenaar f_matchadd(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 477629b7d7a9SBram Moolenaar { 477729b7d7a9SBram Moolenaar # ifdef FEAT_SEARCH_EXTRA 477829b7d7a9SBram Moolenaar char_u buf[NUMBUFLEN]; 47791f164b19SBram Moolenaar char_u *grp = tv_get_string_buf_chk(&argvars[0], buf); // group 47801f164b19SBram Moolenaar char_u *pat = tv_get_string_buf_chk(&argvars[1], buf); // pattern 47811f164b19SBram Moolenaar int prio = 10; // default priority 478229b7d7a9SBram Moolenaar int id = -1; 478329b7d7a9SBram Moolenaar int error = FALSE; 478429b7d7a9SBram Moolenaar char_u *conceal_char = NULL; 478529b7d7a9SBram Moolenaar win_T *win = curwin; 478629b7d7a9SBram Moolenaar 478729b7d7a9SBram Moolenaar rettv->vval.v_number = -1; 478829b7d7a9SBram Moolenaar 478929b7d7a9SBram Moolenaar if (grp == NULL || pat == NULL) 479029b7d7a9SBram Moolenaar return; 479129b7d7a9SBram Moolenaar if (argvars[2].v_type != VAR_UNKNOWN) 479229b7d7a9SBram Moolenaar { 479329b7d7a9SBram Moolenaar prio = (int)tv_get_number_chk(&argvars[2], &error); 479429b7d7a9SBram Moolenaar if (argvars[3].v_type != VAR_UNKNOWN) 479529b7d7a9SBram Moolenaar { 479629b7d7a9SBram Moolenaar id = (int)tv_get_number_chk(&argvars[3], &error); 479729b7d7a9SBram Moolenaar if (argvars[4].v_type != VAR_UNKNOWN 479829b7d7a9SBram Moolenaar && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL) 479929b7d7a9SBram Moolenaar return; 480029b7d7a9SBram Moolenaar } 480129b7d7a9SBram Moolenaar } 480229b7d7a9SBram Moolenaar if (error == TRUE) 480329b7d7a9SBram Moolenaar return; 480429b7d7a9SBram Moolenaar if (id >= 1 && id <= 3) 480529b7d7a9SBram Moolenaar { 480629b7d7a9SBram Moolenaar semsg(_("E798: ID is reserved for \":match\": %d"), id); 480729b7d7a9SBram Moolenaar return; 480829b7d7a9SBram Moolenaar } 480929b7d7a9SBram Moolenaar 481029b7d7a9SBram Moolenaar rettv->vval.v_number = match_add(win, grp, pat, prio, id, NULL, 481129b7d7a9SBram Moolenaar conceal_char); 481229b7d7a9SBram Moolenaar # endif 481329b7d7a9SBram Moolenaar } 481429b7d7a9SBram Moolenaar 481529b7d7a9SBram Moolenaar /* 481629b7d7a9SBram Moolenaar * "matchaddpos()" function 481729b7d7a9SBram Moolenaar */ 481829b7d7a9SBram Moolenaar void 481929b7d7a9SBram Moolenaar f_matchaddpos(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 482029b7d7a9SBram Moolenaar { 482129b7d7a9SBram Moolenaar # ifdef FEAT_SEARCH_EXTRA 482229b7d7a9SBram Moolenaar char_u buf[NUMBUFLEN]; 482329b7d7a9SBram Moolenaar char_u *group; 482429b7d7a9SBram Moolenaar int prio = 10; 482529b7d7a9SBram Moolenaar int id = -1; 482629b7d7a9SBram Moolenaar int error = FALSE; 482729b7d7a9SBram Moolenaar list_T *l; 482829b7d7a9SBram Moolenaar char_u *conceal_char = NULL; 482929b7d7a9SBram Moolenaar win_T *win = curwin; 483029b7d7a9SBram Moolenaar 483129b7d7a9SBram Moolenaar rettv->vval.v_number = -1; 483229b7d7a9SBram Moolenaar 483329b7d7a9SBram Moolenaar group = tv_get_string_buf_chk(&argvars[0], buf); 483429b7d7a9SBram Moolenaar if (group == NULL) 483529b7d7a9SBram Moolenaar return; 483629b7d7a9SBram Moolenaar 483729b7d7a9SBram Moolenaar if (argvars[1].v_type != VAR_LIST) 483829b7d7a9SBram Moolenaar { 483929b7d7a9SBram Moolenaar semsg(_(e_listarg), "matchaddpos()"); 484029b7d7a9SBram Moolenaar return; 484129b7d7a9SBram Moolenaar } 484229b7d7a9SBram Moolenaar l = argvars[1].vval.v_list; 484329b7d7a9SBram Moolenaar if (l == NULL) 484429b7d7a9SBram Moolenaar return; 484529b7d7a9SBram Moolenaar 484629b7d7a9SBram Moolenaar if (argvars[2].v_type != VAR_UNKNOWN) 484729b7d7a9SBram Moolenaar { 484829b7d7a9SBram Moolenaar prio = (int)tv_get_number_chk(&argvars[2], &error); 484929b7d7a9SBram Moolenaar if (argvars[3].v_type != VAR_UNKNOWN) 485029b7d7a9SBram Moolenaar { 485129b7d7a9SBram Moolenaar id = (int)tv_get_number_chk(&argvars[3], &error); 485229b7d7a9SBram Moolenaar 485329b7d7a9SBram Moolenaar if (argvars[4].v_type != VAR_UNKNOWN 485429b7d7a9SBram Moolenaar && matchadd_dict_arg(&argvars[4], &conceal_char, &win) == FAIL) 485529b7d7a9SBram Moolenaar return; 485629b7d7a9SBram Moolenaar } 485729b7d7a9SBram Moolenaar } 485829b7d7a9SBram Moolenaar if (error == TRUE) 485929b7d7a9SBram Moolenaar return; 486029b7d7a9SBram Moolenaar 48611f164b19SBram Moolenaar // id == 3 is ok because matchaddpos() is supposed to substitute :3match 486229b7d7a9SBram Moolenaar if (id == 1 || id == 2) 486329b7d7a9SBram Moolenaar { 486429b7d7a9SBram Moolenaar semsg(_("E798: ID is reserved for \":match\": %d"), id); 486529b7d7a9SBram Moolenaar return; 486629b7d7a9SBram Moolenaar } 486729b7d7a9SBram Moolenaar 486829b7d7a9SBram Moolenaar rettv->vval.v_number = match_add(win, group, NULL, prio, id, l, 486929b7d7a9SBram Moolenaar conceal_char); 487029b7d7a9SBram Moolenaar # endif 487129b7d7a9SBram Moolenaar } 487229b7d7a9SBram Moolenaar 487329b7d7a9SBram Moolenaar /* 487429b7d7a9SBram Moolenaar * "matcharg()" function 487529b7d7a9SBram Moolenaar */ 487629b7d7a9SBram Moolenaar void 487729b7d7a9SBram Moolenaar f_matcharg(typval_T *argvars UNUSED, typval_T *rettv) 487829b7d7a9SBram Moolenaar { 487929b7d7a9SBram Moolenaar if (rettv_list_alloc(rettv) == OK) 488029b7d7a9SBram Moolenaar { 488129b7d7a9SBram Moolenaar # ifdef FEAT_SEARCH_EXTRA 488229b7d7a9SBram Moolenaar int id = (int)tv_get_number(&argvars[0]); 488329b7d7a9SBram Moolenaar matchitem_T *m; 488429b7d7a9SBram Moolenaar 488529b7d7a9SBram Moolenaar if (id >= 1 && id <= 3) 488629b7d7a9SBram Moolenaar { 488729b7d7a9SBram Moolenaar if ((m = (matchitem_T *)get_match(curwin, id)) != NULL) 488829b7d7a9SBram Moolenaar { 488929b7d7a9SBram Moolenaar list_append_string(rettv->vval.v_list, 489029b7d7a9SBram Moolenaar syn_id2name(m->hlg_id), -1); 489129b7d7a9SBram Moolenaar list_append_string(rettv->vval.v_list, m->pattern, -1); 489229b7d7a9SBram Moolenaar } 489329b7d7a9SBram Moolenaar else 489429b7d7a9SBram Moolenaar { 489529b7d7a9SBram Moolenaar list_append_string(rettv->vval.v_list, NULL, -1); 489629b7d7a9SBram Moolenaar list_append_string(rettv->vval.v_list, NULL, -1); 489729b7d7a9SBram Moolenaar } 489829b7d7a9SBram Moolenaar } 489929b7d7a9SBram Moolenaar # endif 490029b7d7a9SBram Moolenaar } 490129b7d7a9SBram Moolenaar } 490229b7d7a9SBram Moolenaar 490329b7d7a9SBram Moolenaar /* 490429b7d7a9SBram Moolenaar * "matchdelete()" function 490529b7d7a9SBram Moolenaar */ 490629b7d7a9SBram Moolenaar void 490729b7d7a9SBram Moolenaar f_matchdelete(typval_T *argvars UNUSED, typval_T *rettv UNUSED) 490829b7d7a9SBram Moolenaar { 490929b7d7a9SBram Moolenaar # ifdef FEAT_SEARCH_EXTRA 491029b7d7a9SBram Moolenaar win_T *win = get_optional_window(argvars, 1); 491129b7d7a9SBram Moolenaar 491229b7d7a9SBram Moolenaar if (win == NULL) 491329b7d7a9SBram Moolenaar rettv->vval.v_number = -1; 491429b7d7a9SBram Moolenaar else 491529b7d7a9SBram Moolenaar rettv->vval.v_number = match_delete(win, 491629b7d7a9SBram Moolenaar (int)tv_get_number(&argvars[0]), TRUE); 491729b7d7a9SBram Moolenaar # endif 491829b7d7a9SBram Moolenaar } 4919c61a48d2SBram Moolenaar #endif 49207dfb016dSBram Moolenaar 49217dfb016dSBram Moolenaar #if defined(FEAT_SEARCH_EXTRA) || defined(PROTO) 49227dfb016dSBram Moolenaar /* 49237dfb016dSBram Moolenaar * ":[N]match {group} {pattern}" 49247dfb016dSBram Moolenaar * Sets nextcmd to the start of the next command, if any. Also called when 49257dfb016dSBram Moolenaar * skipping commands to find the next command. 49267dfb016dSBram Moolenaar */ 49277dfb016dSBram Moolenaar void 49287dfb016dSBram Moolenaar ex_match(exarg_T *eap) 49297dfb016dSBram Moolenaar { 49307dfb016dSBram Moolenaar char_u *p; 49317dfb016dSBram Moolenaar char_u *g = NULL; 49327dfb016dSBram Moolenaar char_u *end; 49337dfb016dSBram Moolenaar int c; 49347dfb016dSBram Moolenaar int id; 49357dfb016dSBram Moolenaar 49367dfb016dSBram Moolenaar if (eap->line2 <= 3) 49377dfb016dSBram Moolenaar id = eap->line2; 49387dfb016dSBram Moolenaar else 49397dfb016dSBram Moolenaar { 49407dfb016dSBram Moolenaar emsg(_(e_invcmd)); 49417dfb016dSBram Moolenaar return; 49427dfb016dSBram Moolenaar } 49437dfb016dSBram Moolenaar 49441f164b19SBram Moolenaar // First clear any old pattern. 49457dfb016dSBram Moolenaar if (!eap->skip) 49467dfb016dSBram Moolenaar match_delete(curwin, id, FALSE); 49477dfb016dSBram Moolenaar 49481966c248SBram Moolenaar if (ends_excmd2(eap->cmd, eap->arg)) 49497dfb016dSBram Moolenaar end = eap->arg; 49507dfb016dSBram Moolenaar else if ((STRNICMP(eap->arg, "none", 4) == 0 49511966c248SBram Moolenaar && (VIM_ISWHITE(eap->arg[4]) 49521966c248SBram Moolenaar || ends_excmd2(eap->arg, eap->arg + 4)))) 49537dfb016dSBram Moolenaar end = eap->arg + 4; 49547dfb016dSBram Moolenaar else 49557dfb016dSBram Moolenaar { 49567dfb016dSBram Moolenaar p = skiptowhite(eap->arg); 49577dfb016dSBram Moolenaar if (!eap->skip) 49587dfb016dSBram Moolenaar g = vim_strnsave(eap->arg, (int)(p - eap->arg)); 49597dfb016dSBram Moolenaar p = skipwhite(p); 49607dfb016dSBram Moolenaar if (*p == NUL) 49617dfb016dSBram Moolenaar { 49621f164b19SBram Moolenaar // There must be two arguments. 49637dfb016dSBram Moolenaar vim_free(g); 49647dfb016dSBram Moolenaar semsg(_(e_invarg2), eap->arg); 49657dfb016dSBram Moolenaar return; 49667dfb016dSBram Moolenaar } 4967e8c4abbbSBram Moolenaar end = skip_regexp(p + 1, *p, TRUE); 49687dfb016dSBram Moolenaar if (!eap->skip) 49697dfb016dSBram Moolenaar { 49701966c248SBram Moolenaar if (*end != NUL && !ends_excmd2(end, skipwhite(end + 1))) 49717dfb016dSBram Moolenaar { 49727dfb016dSBram Moolenaar vim_free(g); 49737dfb016dSBram Moolenaar eap->errmsg = e_trailing; 49747dfb016dSBram Moolenaar return; 49757dfb016dSBram Moolenaar } 49767dfb016dSBram Moolenaar if (*end != *p) 49777dfb016dSBram Moolenaar { 49787dfb016dSBram Moolenaar vim_free(g); 49797dfb016dSBram Moolenaar semsg(_(e_invarg2), p); 49807dfb016dSBram Moolenaar return; 49817dfb016dSBram Moolenaar } 49827dfb016dSBram Moolenaar 49837dfb016dSBram Moolenaar c = *end; 49847dfb016dSBram Moolenaar *end = NUL; 49857dfb016dSBram Moolenaar match_add(curwin, g, p + 1, 10, id, NULL, NULL); 49867dfb016dSBram Moolenaar vim_free(g); 49877dfb016dSBram Moolenaar *end = c; 49887dfb016dSBram Moolenaar } 49897dfb016dSBram Moolenaar } 49907dfb016dSBram Moolenaar eap->nextcmd = find_nextcmd(end); 49917dfb016dSBram Moolenaar } 49927dfb016dSBram Moolenaar #endif 4993