Patch 8.2.3536
Problem: The do_highlight() function is way too long.
Solution: Split it into several functions. (Yegappan Lakshmanan,
closes #9011)
Files: src/highlight.c
*** ../vim-8.2.3535/src/highlight.c 2021-10-15 22:25:37.785385044 +0100
--- src/highlight.c 2021-10-18 22:12:59.041516541 +0100
***************
*** 377,386 ****
#ifdef FEAT_EVAL
char_u *p;
! /*
! * Try finding the color scheme file. Used when a color file was loaded
! * and 'background' or 't_Co' is changed.
! */
p = get_var_value((char_u *)"g:colors_name");
if (p != NULL)
{
--- 377,384 ----
#ifdef FEAT_EVAL
char_u *p;
! // Try finding the color scheme file. Used when a color file was loaded
! // and 'background' or 't_Co' is changed.
p = get_var_value((char_u *)"g:colors_name");
if (p != NULL)
{
***************
*** 400,408 ****
#endif
! /*
! * Didn't use a color file, use the compiled-in colors.
! */
if (both)
{
had_both = TRUE;
--- 398,404 ----
#endif
! // Didn't use a color file, use the compiled-in colors.
if (both)
{
had_both = TRUE;
***************
*** 441,449 ****
}
#ifdef FEAT_SYN_HL
! /*
! * If syntax highlighting is enabled load the highlighting for it.
! */
if (get_var_value((char_u *)"g:syntax_on") != NULL)
{
static int recursive = 0;
--- 437,443 ----
}
#ifdef FEAT_SYN_HL
! // If syntax highlighting is enabled load the highlighting for it.
if (get_var_value((char_u *)"g:syntax_on") != NULL)
{
static int recursive = 0;
***************
*** 581,591 ****
else if (t_colors == 16 || t_colors == 88
|| t_colors >= 256)
{
! /*
! * Guess: if the termcap entry ends in 'm', it is
! * probably an xterm-like terminal. Use the changed
! * order for colors.
! */
if (*T_CAF != NUL)
p = T_CAF;
else
--- 575,583 ----
else if (t_colors == 16 || t_colors == 88
|| t_colors >= 256)
{
! // Guess: if the termcap entry ends in 'm', it is
! // probably an xterm-like terminal. Use the changed
! // order for colors.
if (*T_CAF != NUL)
p = T_CAF;
else
***************
*** 611,616 ****
--- 603,1360 ----
}
/*
+ * Link highlight group 'from_hg' to 'to_hg'.
+ * 'dodefault' is set to TRUE for ":highlight default link".
+ * 'forceit' is set to TRUE for ":higlight! link"
+ * 'init' is set to TRUE when initializing all the highlight groups.
+ */
+ static void
+ highlight_group_link(
+ char_u *from_hg,
+ int from_len,
+ char_u *to_hg,
+ int to_len,
+ int dodefault,
+ int forceit,
+ int init)
+ {
+ int from_id;
+ int to_id;
+ hl_group_T *hlgroup = NULL;
+
+ from_id = syn_check_group(from_hg, from_len);
+ if (STRNCMP(to_hg, "NONE", 4) == 0)
+ to_id = 0;
+ else
+ to_id = syn_check_group(to_hg, to_len);
+
+ if (from_id > 0)
+ {
+ hlgroup = &HL_TABLE()[from_id - 1];
+ if (dodefault && (forceit || hlgroup->sg_deflink == 0))
+ {
+ hlgroup->sg_deflink = to_id;
+ #ifdef FEAT_EVAL
+ hlgroup->sg_deflink_sctx = current_sctx;
+ hlgroup->sg_deflink_sctx.sc_lnum += SOURCING_LNUM;
+ #endif
+ }
+ }
+
+ if (from_id > 0 && (!init || hlgroup->sg_set == 0))
+ {
+ // Don't allow a link when there already is some highlighting
+ // for the group, unless '!' is used
+ if (to_id > 0 && !forceit && !init
+ && hl_has_settings(from_id - 1, dodefault))
+ {
+ if (SOURCING_NAME == NULL && !dodefault)
+ emsg(_("E414: group has settings, highlight link ignored"));
+ }
+ else if (hlgroup->sg_link != to_id
+ #ifdef FEAT_EVAL
+ || hlgroup->sg_script_ctx.sc_sid != current_sctx.sc_sid
+ #endif
+ || hlgroup->sg_cleared)
+ {
+ if (!init)
+ hlgroup->sg_set |= SG_LINK;
+ hlgroup->sg_link = to_id;
+ #ifdef FEAT_EVAL
+ hlgroup->sg_script_ctx = current_sctx;
+ hlgroup->sg_script_ctx.sc_lnum += SOURCING_LNUM;
+ #endif
+ hlgroup->sg_cleared = FALSE;
+ redraw_all_later(SOME_VALID);
+
+ // Only call highlight_changed() once after multiple changes.
+ need_highlight_changed = TRUE;
+ }
+ }
+
+ }
+
+ /*
+ * Reset all highlighting to the defaults. Removes all highlighting for the
+ * groups added by the user.
+ */
+ static void
+ highlight_reset_all(void)
+ {
+ int idx;
+
+ #ifdef FEAT_GUI
+ // First, we do not destroy the old values, but allocate the new
+ // ones and update the display. THEN we destroy the old values.
+ // If we destroy the old values first, then the old values
+ // (such as GuiFont's or GuiFontset's) will still be displayed but
+ // invalid because they were free'd.
+ if (gui.in_use)
+ {
+ # ifdef FEAT_BEVAL_TIP
+ gui_init_tooltip_font();
+ # endif
+ # if defined(FEAT_MENU) && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF))
+ gui_init_menu_font();
+ # endif
+ }
+ # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_X11)
+ gui_mch_def_colors();
+ # endif
+ # ifdef FEAT_GUI_X11
+ # ifdef FEAT_MENU
+
+ // This only needs to be done when there is no Menu highlight
+ // group defined by default, which IS currently the case.
+ gui_mch_new_menu_colors();
+ # endif
+ if (gui.in_use)
+ {
+ gui_new_scrollbar_colors();
+ # ifdef FEAT_BEVAL_GUI
+ gui_mch_new_tooltip_colors();
+ # endif
+ # ifdef FEAT_MENU
+ gui_mch_new_menu_font();
+ # endif
+ }
+ # endif
+
+ // Ok, we're done allocating the new default graphics items.
+ // The screen should already be refreshed at this point.
+ // It is now Ok to clear out the old data.
+ #endif
+ #ifdef FEAT_EVAL
+ do_unlet((char_u *)"g:colors_name", TRUE);
+ #endif
+ restore_cterm_colors();
+
+ // Clear all default highlight groups and load the defaults.
+ for (idx = 0; idx < highlight_ga.ga_len; ++idx)
+ highlight_clear(idx);
+ init_highlight(TRUE, TRUE);
+ #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ if (USE_24BIT)
+ highlight_gui_started();
+ else
+ #endif
+ highlight_changed();
+ redraw_later_clear();
+ }
+
+ /*
+ * Set the 'term' or 'cterm' or 'gui' attributes for the highlight group at
+ * index 'idx'.
+ * 'key' is one of 'TERM' or 'CTERM' or 'GUI'
+ * 'arg' is the list of attribute names separated by comma.
+ * 'init' is set to TRUE when initializing all the highlight groups.
+ * Returns TRUE if the attributes are set.
+ */
+ static int
+ highlight_set_termgui_attr(int idx, char_u *key, char_u *arg, int init)
+ {
+ int attr;
+ int off;
+ long i;
+ int len;
+
+ attr = 0;
+ off = 0;
+ while (arg[off] != NUL)
+ {
+ for (i = ARRAY_LENGTH(hl_attr_table); --i >= 0; )
+ {
+ len = (int)STRLEN(hl_name_table[i]);
+ if (STRNICMP(arg + off, hl_name_table[i], len) == 0)
+ {
+ attr |= hl_attr_table[i];
+ off += len;
+ break;
+ }
+ }
+ if (i < 0)
+ {
+ semsg(_("E418: Illegal value: %s"), arg);
+ return FALSE;
+ }
+ if (arg[off] == ',') // another one follows
+ ++off;
+ }
+ if (*key == 'T')
+ {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM))
+ {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_TERM;
+ HL_TABLE()[idx].sg_term = attr;
+ }
+ }
+ else if (*key == 'C')
+ {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
+ {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_CTERM;
+ HL_TABLE()[idx].sg_cterm = attr;
+ HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ }
+ }
+ #if defined(FEAT_GUI) || defined(FEAT_EVAL)
+ else
+ {
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
+ {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_GUI;
+ HL_TABLE()[idx].sg_gui = attr;
+ }
+ }
+ #endif
+
+ return TRUE;
+ }
+
+ #ifdef FEAT_GUI
+ /*
+ * Set the font for the highlight group at 'idx'.
+ * 'arg' is the font name.
+ * Returns TRUE if the font is changed.
+ */
+ static int
+ highlight_set_font(
+ int idx,
+ char_u *arg,
+ int is_normal_group,
+ int is_menu_group,
+ int is_tooltip_group)
+ {
+ int did_change = FALSE;
+
+ // in non-GUI fonts are simply ignored
+ if (HL_TABLE()[idx].sg_font_name != NULL
+ && STRCMP(HL_TABLE()[idx].sg_font_name, arg) == 0)
+ {
+ // Font name didn't change, ignore.
+ }
+ else if (!gui.shell_created)
+ {
+ // GUI not started yet, always accept the name.
+ vim_free(HL_TABLE()[idx].sg_font_name);
+ HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
+ did_change = TRUE;
+ }
+ else
+ {
+ GuiFont temp_sg_font = HL_TABLE()[idx].sg_font;
+ # ifdef FEAT_XFONTSET
+ GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset;
+ # endif
+ // First, save the current font/fontset.
+ // Then try to allocate the font/fontset.
+ // If the allocation fails, HL_TABLE()[idx].sg_font OR
+ // sg_fontset will be set to NOFONT or NOFONTSET respectively.
+
+ HL_TABLE()[idx].sg_font = NOFONT;
+ # ifdef FEAT_XFONTSET
+ HL_TABLE()[idx].sg_fontset = NOFONTSET;
+ # endif
+ hl_do_font(idx, arg, is_normal_group, is_menu_group,
+ is_tooltip_group, FALSE);
+
+ # ifdef FEAT_XFONTSET
+ if (HL_TABLE()[idx].sg_fontset != NOFONTSET)
+ {
+ // New fontset was accepted. Free the old one, if there
+ // was one.
+ gui_mch_free_fontset(temp_sg_fontset);
+ vim_free(HL_TABLE()[idx].sg_font_name);
+ HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
+ did_change = TRUE;
+ }
+ else
+ HL_TABLE()[idx].sg_fontset = temp_sg_fontset;
+ # endif
+ if (HL_TABLE()[idx].sg_font != NOFONT)
+ {
+ // New font was accepted. Free the old one, if there was
+ // one.
+ gui_mch_free_font(temp_sg_font);
+ vim_free(HL_TABLE()[idx].sg_font_name);
+ HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
+ did_change = TRUE;
+ }
+ else
+ HL_TABLE()[idx].sg_font = temp_sg_font;
+ }
+
+ return did_change;
+ }
+ #endif
+
+ /*
+ * Set the cterm foreground color for the highlight group at 'idx' to 'color'.
+ * Returns TRUE if the foreground color is set.
+ */
+ static void
+ highlight_set_ctermfg(int idx, int color, int is_normal_group)
+ {
+ HL_TABLE()[idx].sg_cterm_fg = color + 1;
+ if (is_normal_group)
+ {
+ cterm_normal_fg_color = color + 1;
+ cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD);
+ #ifdef FEAT_GUI
+ // Don't do this if the GUI is used.
+ if (!gui.in_use && !gui.starting)
+ #endif
+ {
+ must_redraw = CLEAR;
+ if (termcap_active && color >= 0)
+ term_fg_color(color);
+ }
+ }
+ }
+
+ /*
+ * Set the cterm background color for the highlight group at 'idx' to 'color'.
+ * Returns TRUE if the background color is set.
+ */
+ static void
+ highlight_set_ctermbg(int idx, int color, int is_normal_group)
+ {
+ HL_TABLE()[idx].sg_cterm_bg = color + 1;
+ if (is_normal_group)
+ {
+ cterm_normal_bg_color = color + 1;
+ #ifdef FEAT_GUI
+ // Don't mess with 'background' if the GUI is used.
+ if (!gui.in_use && !gui.starting)
+ #endif
+ {
+ must_redraw = CLEAR;
+ if (color >= 0)
+ {
+ int dark = -1;
+
+ if (termcap_active)
+ term_bg_color(color);
+ if (t_colors < 16)
+ dark = (color == 0 || color == 4);
+ // Limit the heuristic to the standard 16 colors
+ else if (color < 16)
+ dark = (color < 7 || color == 8);
+ // Set the 'background' option if the value is
+ // wrong.
+ if (dark != -1
+ && dark != (*p_bg == 'd')
+ && !option_was_set((char_u *)"bg"))
+ {
+ set_option_value((char_u *)"bg", 0L,
+ (char_u *)(dark ? "dark" : "light"), 0);
+ reset_option_was_set((char_u *)"bg");
+ }
+ }
+ }
+ }
+ }
+
+ /*
+ * Set the cterm underline color for the highlight group at 'idx' to 'color'.
+ * Returns TRUE if the underline color is set.
+ */
+ static void
+ highlight_set_ctermul(int idx, int color, int is_normal_group)
+ {
+ HL_TABLE()[idx].sg_cterm_ul = color + 1;
+ if (is_normal_group)
+ {
+ cterm_normal_ul_color = color + 1;
+ #ifdef FEAT_GUI
+ // Don't do this if the GUI is used.
+ if (!gui.in_use && !gui.starting)
+ #endif
+ {
+ must_redraw = CLEAR;
+ if (termcap_active && color >= 0)
+ term_ul_color(color);
+ }
+ }
+ }
+
+ /*
+ * Set the cterm fg/bg/ul color for the highlight group at 'idx'.
+ * 'key' is one of 'CTERMFG' or 'CTERMBG' or 'CTERMUL'.
+ * 'keystart' is the color name/value.
+ * 'arg' is the color name or the numeric value as a string.
+ * 'is_normal_group' is set if the highlight group is 'NORMAL'
+ * 'init' is set to TRUE when initializing highlighting.
+ * Called for the ":highlight" command and the "hlset()" function.
+ *
+ * Returns TRUE if the color is set.
+ */
+ static int
+ highlight_set_cterm_color(
+ int idx,
+ char_u *key,
+ char_u *key_start,
+ char_u *arg,
+ int is_normal_group,
+ int init)
+ {
+ int color;
+ long i;
+ int off;
+
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
+ {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_CTERM;
+
+ // When setting the foreground color, and previously the "bold"
+ // flag was set for a light color, reset it now
+ if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold)
+ {
+ HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
+ HL_TABLE()[idx].sg_cterm_bold = FALSE;
+ }
+
+ if (VIM_ISDIGIT(*arg))
+ color = atoi((char *)arg);
+ else if (STRICMP(arg, "fg") == 0)
+ {
+ if (cterm_normal_fg_color)
+ color = cterm_normal_fg_color - 1;
+ else
+ {
+ emsg(_("E419: FG color unknown"));
+ return FALSE;
+ }
+ }
+ else if (STRICMP(arg, "bg") == 0)
+ {
+ if (cterm_normal_bg_color > 0)
+ color = cterm_normal_bg_color - 1;
+ else
+ {
+ emsg(_("E420: BG color unknown"));
+ return FALSE;
+ }
+ }
+ else if (STRICMP(arg, "ul") == 0)
+ {
+ if (cterm_normal_ul_color > 0)
+ color = cterm_normal_ul_color - 1;
+ else
+ {
+ emsg(_("E453: UL color unknown"));
+ return FALSE;
+ }
+ }
+ else
+ {
+ int bold = MAYBE;
+
+ // reduce calls to STRICMP a bit, it can be slow
+ off = TOUPPER_ASC(*arg);
+ for (i = ARRAY_LENGTH(color_names); --i >= 0; )
+ if (off == color_names[i][0]
+ && STRICMP(arg + 1, color_names[i] + 1) == 0)
+ break;
+ if (i < 0)
+ {
+ semsg(_("E421: Color name or number not recognized: %s"),
+ key_start);
+ return FALSE;
+ }
+
+ color = lookup_color(i, key[5] == 'F', &bold);
+
+ // set/reset bold attribute to get light foreground
+ // colors (on some terminals, e.g. "linux")
+ if (bold == TRUE)
+ {
+ HL_TABLE()[idx].sg_cterm |= HL_BOLD;
+ HL_TABLE()[idx].sg_cterm_bold = TRUE;
+ }
+ else if (bold == FALSE)
+ HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
+ }
+
+ // Add one to the argument, to avoid zero. Zero is used for
+ // "NONE", then "color" is -1.
+ if (key[5] == 'F')
+ highlight_set_ctermfg(idx, color, is_normal_group);
+ else if (key[5] == 'B')
+ highlight_set_ctermbg(idx, color, is_normal_group);
+ else // ctermul
+ highlight_set_ctermul(idx, color, is_normal_group);
+ }
+
+ return TRUE;
+ }
+
+ #if defined(FEAT_GUI) || defined(FEAT_EVAL)
+ /*
+ * Set the GUI foreground color for the highlight group at 'idx'.
+ * Returns TRUE if the color is set.
+ */
+ static int
+ highlight_set_guifg(
+ int idx,
+ char_u *arg,
+ int is_menu_group UNUSED,
+ int is_scrollbar_group UNUSED,
+ int is_tooltip_group UNUSED,
+ int *do_colors UNUSED,
+ int init)
+ {
+ long i;
+ char_u **namep;
+ int did_change = FALSE;
+
+ namep = &HL_TABLE()[idx].sg_gui_fg_name;
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
+ {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_GUI;
+
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ // In GUI guifg colors are only used when recognized
+ i = color_name2handle(arg);
+ if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
+ {
+ HL_TABLE()[idx].sg_gui_fg = i;
+ # endif
+ if (*namep == NULL || STRCMP(*namep, arg) != 0)
+ {
+ vim_free(*namep);
+ if (STRCMP(arg, "NONE") != 0)
+ *namep = vim_strsave(arg);
+ else
+ *namep = NULL;
+ did_change = TRUE;
+ }
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ # ifdef FEAT_GUI_X11
+ if (is_menu_group && gui.menu_fg_pixel != i)
+ {
+ gui.menu_fg_pixel = i;
+ *do_colors = TRUE;
+ }
+ if (is_scrollbar_group && gui.scroll_fg_pixel != i)
+ {
+ gui.scroll_fg_pixel = i;
+ *do_colors = TRUE;
+ }
+ # ifdef FEAT_BEVAL_GUI
+ if (is_tooltip_group && gui.tooltip_fg_pixel != i)
+ {
+ gui.tooltip_fg_pixel = i;
+ *do_colors = TRUE;
+ }
+ # endif
+ # endif
+ }
+ # endif
+ }
+
+ return did_change;
+ }
+
+ /*
+ * Set the GUI background color for the highlight group at 'idx'.
+ * Returns TRUE if the color is set.
+ */
+ static int
+ highlight_set_guibg(
+ int idx,
+ char_u *arg,
+ int is_menu_group UNUSED,
+ int is_scrollbar_group UNUSED,
+ int is_tooltip_group UNUSED,
+ int *do_colors UNUSED,
+ int init)
+ {
+ int i;
+ char_u **namep;
+ int did_change = FALSE;
+
+ namep = &HL_TABLE()[idx].sg_gui_bg_name;
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
+ {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_GUI;
+
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ // In GUI guifg colors are only used when recognized
+ i = color_name2handle(arg);
+ if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
+ {
+ HL_TABLE()[idx].sg_gui_bg = i;
+ # endif
+ if (*namep == NULL || STRCMP(*namep, arg) != 0)
+ {
+ vim_free(*namep);
+ if (STRCMP(arg, "NONE") != 0)
+ *namep = vim_strsave(arg);
+ else
+ *namep = NULL;
+ did_change = TRUE;
+ }
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ # ifdef FEAT_GUI_X11
+ if (is_menu_group && gui.menu_bg_pixel != i)
+ {
+ gui.menu_bg_pixel = i;
+ *do_colors = TRUE;
+ }
+ if (is_scrollbar_group && gui.scroll_bg_pixel != i)
+ {
+ gui.scroll_bg_pixel = i;
+ *do_colors = TRUE;
+ }
+ # ifdef FEAT_BEVAL_GUI
+ if (is_tooltip_group && gui.tooltip_bg_pixel != i)
+ {
+ gui.tooltip_bg_pixel = i;
+ *do_colors = TRUE;
+ }
+ # endif
+ # endif
+ }
+ # endif
+ }
+
+ return did_change;
+ }
+
+ /*
+ * Set the GUI undercurl/strikethrough color for the highlight group at 'idx'.
+ * Returns TRUE if the color is set.
+ */
+ static int
+ highlight_set_guisp(int idx, char_u *arg, int init)
+ {
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ int i;
+ # endif
+ int did_change = FALSE;
+ char_u **namep;
+
+ namep = &HL_TABLE()[idx].sg_gui_sp_name;
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
+ {
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_GUI;
+
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ // In GUI guisp colors are only used when recognized
+ i = color_name2handle(arg);
+ if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
+ {
+ HL_TABLE()[idx].sg_gui_sp = i;
+ # endif
+ if (*namep == NULL || STRCMP(*namep, arg) != 0)
+ {
+ vim_free(*namep);
+ if (STRCMP(arg, "NONE") != 0)
+ *namep = vim_strsave(arg);
+ else
+ *namep = NULL;
+ did_change = TRUE;
+ }
+ # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
+ }
+ # endif
+ }
+
+ return did_change;
+ }
+ #endif
+
+ /*
+ * Set the start/stop terminal codes for a highlight group.
+ * Returns TRUE if the terminal code is set.
+ */
+ static int
+ highlight_set_startstop_termcode(int idx, char_u *key, char_u *arg, int init)
+ {
+ int off;
+ char_u buf[100];
+ int len;
+ char_u *tname;
+ char_u *p;
+
+ if (!init)
+ HL_TABLE()[idx].sg_set |= SG_TERM;
+
+ // The "start" and "stop" arguments can be a literal escape
+ // sequence, or a comma separated list of terminal codes.
+ if (STRNCMP(arg, "t_", 2) == 0)
+ {
+ off = 0;
+ buf[0] = 0;
+ while (arg[off] != NUL)
+ {
+ // Isolate one termcap name
+ for (len = 0; arg[off + len] &&
+ arg[off + len] != ','; ++len)
+ ;
+ tname = vim_strnsave(arg + off, len);
+ if (tname == NULL) // out of memory
+ return FALSE;
+ // lookup the escape sequence for the item
+ p = get_term_code(tname);
+ vim_free(tname);
+ if (p == NULL) // ignore non-existing things
+ p = (char_u *)"";
+
+ // Append it to the already found stuff
+ if ((int)(STRLEN(buf) + STRLEN(p)) >= 99)
+ {
+ semsg(_("E422: terminal code too long: %s"), arg);
+ return FALSE;
+ }
+ STRCAT(buf, p);
+
+ // Advance to the next item
+ off += len;
+ if (arg[off] == ',') // another one follows
+ ++off;
+ }
+ }
+ else
+ {
+ // Copy characters from arg[] to buf[], translating <> codes.
+ for (p = arg, off = 0; off < 100 - 6 && *p; )
+ {
+ len = trans_special(&p, buf + off, FSK_SIMPLIFY, NULL);
+ if (len > 0) // recognized special char
+ off += len;
+ else // copy as normal char
+ buf[off++] = *p++;
+ }
+ buf[off] = NUL;
+ }
+
+ if (STRCMP(buf, "NONE") == 0) // resetting the value
+ p = NULL;
+ else
+ p = vim_strsave(buf);
+ if (key[2] == 'A')
+ {
+ vim_free(HL_TABLE()[idx].sg_start);
+ HL_TABLE()[idx].sg_start = p;
+ }
+ else
+ {
+ vim_free(HL_TABLE()[idx].sg_stop);
+ HL_TABLE()[idx].sg_stop = p;
+ }
+ return TRUE;
+ }
+
+ /*
* Handle the ":highlight .." command.
* When using ":hi clear" this is called recursively for each group with
* "forceit" and "init" both TRUE.
***************
*** 622,636 ****
int init) // TRUE when called for initializing
{
char_u *name_end;
- char_u *p;
char_u *linep;
char_u *key_start;
char_u *arg_start;
char_u *key = NULL, *arg = NULL;
long i;
- int off;
- int len;
- int attr;
int id;
int idx;
hl_group_T item_before;
--- 1366,1376 ----
***************
*** 639,662 ****
int doclear = FALSE;
int dolink = FALSE;
int error = FALSE;
- int color;
int is_normal_group = FALSE; // "Normal" group
#ifdef FEAT_GUI_X11
int is_menu_group = FALSE; // "Menu" group
int is_scrollbar_group = FALSE; // "Scrollbar" group
int is_tooltip_group = FALSE; // "Tooltip" group
- int do_colors = FALSE; // need to update colors?
#else
# define is_menu_group 0
# define is_tooltip_group 0
#endif
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
int did_highlight_changed = FALSE;
#endif
! /*
! * If no argument, list current highlighting.
! */
if (!init && ends_excmd2(line - 1, line))
{
for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
--- 1379,1402 ----
int doclear = FALSE;
int dolink = FALSE;
int error = FALSE;
int is_normal_group = FALSE; // "Normal" group
#ifdef FEAT_GUI_X11
int is_menu_group = FALSE; // "Menu" group
int is_scrollbar_group = FALSE; // "Scrollbar" group
int is_tooltip_group = FALSE; // "Tooltip" group
#else
# define is_menu_group 0
# define is_tooltip_group 0
+ # define is_scrollbar_group 0
+ #endif
+ #if defined(FEAT_GUI) || defined(FEAT_EVAL)
+ int do_colors = FALSE; // need to update colors?
#endif
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
int did_highlight_changed = FALSE;
#endif
! // If no argument, list current highlighting.
if (!init && ends_excmd2(line - 1, line))
{
for (i = 1; i <= highlight_ga.ga_len && !got_int; ++i)
***************
*** 665,679 ****
return;
}
! /*
! * Isolate the name.
! */
name_end = skiptowhite(line);
linep = skipwhite(name_end);
! /*
! * Check for "default" argument.
! */
if (STRNCMP(line, "default", name_end - line) == 0)
{
dodefault = TRUE;
--- 1405,1415 ----
return;
}
! // Isolate the name.
name_end = skiptowhite(line);
linep = skipwhite(name_end);
! // Check for "default" argument.
if (STRNCMP(line, "default", name_end - line) == 0)
{
dodefault = TRUE;
***************
*** 682,698 ****
linep = skipwhite(name_end);
}
! /*
! * Check for "clear" or "link" argument.
! */
if (STRNCMP(line, "clear", name_end - line) == 0)
doclear = TRUE;
if (STRNCMP(line, "link", name_end - line) == 0)
dolink = TRUE;
! /*
! * ":highlight {group-name}": list highlighting for one group.
! */
if (!doclear && !dolink && ends_excmd2(line, linep))
{
id = syn_namen2id(line, (int)(name_end - line));
--- 1418,1430 ----
linep = skipwhite(name_end);
}
! // Check for "clear" or "link" argument.
if (STRNCMP(line, "clear", name_end - line) == 0)
doclear = TRUE;
if (STRNCMP(line, "link", name_end - line) == 0)
dolink = TRUE;
! // ":highlight {group-name}": list highlighting for one group.
if (!doclear && !dolink && ends_excmd2(line, linep))
{
id = syn_namen2id(line, (int)(name_end - line));
***************
*** 703,720 ****
return;
}
! /*
! * Handle ":highlight link {from} {to}" command.
! */
if (dolink)
{
char_u *from_start = linep;
char_u *from_end;
char_u *to_start;
char_u *to_end;
! int from_id;
! int to_id;
! hl_group_T *hlgroup = NULL;
from_end = skiptowhite(from_start);
to_start = skipwhite(from_end);
--- 1435,1449 ----
return;
}
! // Handle ":highlight link {from} {to}" command.
if (dolink)
{
char_u *from_start = linep;
char_u *from_end;
+ int from_len;
char_u *to_start;
char_u *to_end;
! int to_len;
from_end = skiptowhite(from_start);
to_start = skipwhite(from_end);
***************
*** 734,860 ****
return;
}
! from_id = syn_check_group(from_start, (int)(from_end - from_start));
! if (STRNCMP(to_start, "NONE", 4) == 0)
! to_id = 0;
! else
! to_id = syn_check_group(to_start, (int)(to_end - to_start));
!
! if (from_id > 0)
! {
! hlgroup = &HL_TABLE()[from_id - 1];
! if (dodefault && (forceit || hlgroup->sg_deflink == 0))
! {
! hlgroup->sg_deflink = to_id;
! #ifdef FEAT_EVAL
! hlgroup->sg_deflink_sctx = current_sctx;
! hlgroup->sg_deflink_sctx.sc_lnum += SOURCING_LNUM;
! #endif
! }
! }
!
! if (from_id > 0 && (!init || hlgroup->sg_set == 0))
! {
! /*
! * Don't allow a link when there already is some highlighting
! * for the group, unless '!' is used
! */
! if (to_id > 0 && !forceit && !init
! && hl_has_settings(from_id - 1, dodefault))
! {
! if (SOURCING_NAME == NULL && !dodefault)
! emsg(_("E414: group has settings, highlight link ignored"));
! }
! else if (hlgroup->sg_link != to_id
! #ifdef FEAT_EVAL
! || hlgroup->sg_script_ctx.sc_sid != current_sctx.sc_sid
! #endif
! || hlgroup->sg_cleared)
! {
! if (!init)
! hlgroup->sg_set |= SG_LINK;
! hlgroup->sg_link = to_id;
! #ifdef FEAT_EVAL
! hlgroup->sg_script_ctx = current_sctx;
! hlgroup->sg_script_ctx.sc_lnum += SOURCING_LNUM;
! #endif
! hlgroup->sg_cleared = FALSE;
! redraw_all_later(SOME_VALID);
!
! // Only call highlight_changed() once after multiple changes.
! need_highlight_changed = TRUE;
! }
! }
!
return;
}
if (doclear)
{
! /*
! * ":highlight clear [group]" command.
! */
if (ends_excmd2(line, linep))
{
! #ifdef FEAT_GUI
! // First, we do not destroy the old values, but allocate the new
! // ones and update the display. THEN we destroy the old values.
! // If we destroy the old values first, then the old values
! // (such as GuiFont's or GuiFontset's) will still be displayed but
! // invalid because they were free'd.
! if (gui.in_use)
! {
! # ifdef FEAT_BEVAL_TIP
! gui_init_tooltip_font();
! # endif
! # if defined(FEAT_MENU) && (defined(FEAT_GUI_ATHENA) || defined(FEAT_GUI_MOTIF))
! gui_init_menu_font();
! # endif
! }
! # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_X11)
! gui_mch_def_colors();
! # endif
! # ifdef FEAT_GUI_X11
! # ifdef FEAT_MENU
!
! // This only needs to be done when there is no Menu highlight
! // group defined by default, which IS currently the case.
! gui_mch_new_menu_colors();
! # endif
! if (gui.in_use)
! {
! gui_new_scrollbar_colors();
! # ifdef FEAT_BEVAL_GUI
! gui_mch_new_tooltip_colors();
! # endif
! # ifdef FEAT_MENU
! gui_mch_new_menu_font();
! # endif
! }
! # endif
!
! // Ok, we're done allocating the new default graphics items.
! // The screen should already be refreshed at this point.
! // It is now Ok to clear out the old data.
! #endif
! #ifdef FEAT_EVAL
! do_unlet((char_u *)"g:colors_name", TRUE);
! #endif
! restore_cterm_colors();
!
! /*
! * Clear all default highlight groups and load the defaults.
! */
! for (idx = 0; idx < highlight_ga.ga_len; ++idx)
! highlight_clear(idx);
! init_highlight(TRUE, TRUE);
! #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
! if (USE_24BIT)
! highlight_gui_started();
! else
! #endif
! highlight_changed();
! redraw_later_clear();
return;
}
line = linep;
--- 1463,1482 ----
return;
}
! from_len = (int)(from_end - from_start);
! to_len = (int)(to_end - to_start);
! highlight_group_link(from_start, from_len, to_start, to_len,
! dodefault, forceit, init);
return;
}
if (doclear)
{
! // ":highlight clear [group]" command.
if (ends_excmd2(line, linep))
{
! // ":highlight clear" without group name
! highlight_reset_all();
return;
}
line = linep;
***************
*** 862,874 ****
linep = skipwhite(name_end);
}
! /*
! * Find the group name in the table. If it does not exist yet, add it.
! */
id = syn_check_group(line, (int)(name_end - line));
! if (id == 0) // failed (out of memory)
return;
! idx = id - 1; // index is ID minus one
// Return if "default" was used and the group already has settings.
if (dodefault && hl_has_settings(idx, TRUE))
--- 1484,1494 ----
linep = skipwhite(name_end);
}
! // Find the group name in the table. If it does not exist yet, add it.
id = syn_check_group(line, (int)(name_end - line));
! if (id == 0) // failed (out of memory)
return;
! idx = id - 1; // index is ID minus one
// Return if "default" was used and the group already has settings.
if (dodefault && hl_has_settings(idx, TRUE))
***************
*** 897,1505 ****
}
if (!doclear)
! while (!ends_excmd2(line, linep))
! {
! key_start = linep;
! if (*linep == '=')
{
! semsg(_("E415: unexpected equal sign: %s"), key_start);
! error = TRUE;
! break;
! }
!
! /*
! * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or
! * "guibg").
! */
! while (*linep && !VIM_ISWHITE(*linep) && *linep != '=')
! ++linep;
! vim_free(key);
! key = vim_strnsave_up(key_start, linep - key_start);
! if (key == NULL)
! {
! error = TRUE;
! break;
! }
! linep = skipwhite(linep);
!
! if (STRCMP(key, "NONE") == 0)
! {
! if (!init || HL_TABLE()[idx].sg_set == 0)
{
! if (!init)
! HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI;
! highlight_clear(idx);
! }
! continue;
! }
!
! /*
! * Check for the equal sign.
! */
! if (*linep != '=')
! {
! semsg(_("E416: missing equal sign: %s"), key_start);
! error = TRUE;
! break;
! }
! ++linep;
!
! /*
! * Isolate the argument.
! */
! linep = skipwhite(linep);
! if (*linep == '\'') // guifg='color name'
! {
! arg_start = ++linep;
! linep = vim_strchr(linep, '\'');
! if (linep == NULL)
! {
! semsg(_(e_invarg2), key_start);
error = TRUE;
break;
}
- }
- else
- {
- arg_start = linep;
- linep = skiptowhite(linep);
- }
- if (linep == arg_start)
- {
- semsg(_("E417: missing argument: %s"), key_start);
- error = TRUE;
- break;
- }
- vim_free(arg);
- arg = vim_strnsave(arg_start, linep - arg_start);
- if (arg == NULL)
- {
- error = TRUE;
- break;
- }
- if (*linep == '\'')
- ++linep;
! /*
! * Store the argument.
! */
! if ( STRCMP(key, "TERM") == 0
! || STRCMP(key, "CTERM") == 0
! || STRCMP(key, "GUI") == 0)
! {
! attr = 0;
! off = 0;
! while (arg[off] != NUL)
{
! for (i = ARRAY_LENGTH(hl_attr_table); --i >= 0; )
! {
! len = (int)STRLEN(hl_name_table[i]);
! if (STRNICMP(arg + off, hl_name_table[i], len) == 0)
! {
! attr |= hl_attr_table[i];
! off += len;
! break;
! }
! }
! if (i < 0)
! {
! semsg(_("E418: Illegal value: %s"), arg);
! error = TRUE;
! break;
! }
! if (arg[off] == ',') // another one follows
! ++off;
! }
! if (error)
break;
- if (*key == 'T')
- {
- if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM))
- {
- if (!init)
- HL_TABLE()[idx].sg_set |= SG_TERM;
- HL_TABLE()[idx].sg_term = attr;
- }
}
! else if (*key == 'C')
! {
! if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
! {
! if (!init)
! HL_TABLE()[idx].sg_set |= SG_CTERM;
! HL_TABLE()[idx].sg_cterm = attr;
! HL_TABLE()[idx].sg_cterm_bold = FALSE;
! }
! }
! #if defined(FEAT_GUI) || defined(FEAT_EVAL)
! else
{
! if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
{
if (!init)
! HL_TABLE()[idx].sg_set |= SG_GUI;
! HL_TABLE()[idx].sg_gui = attr;
}
}
- #endif
- }
- else if (STRCMP(key, "FONT") == 0)
- {
- // in non-GUI fonts are simply ignored
- #ifdef FEAT_GUI
- if (HL_TABLE()[idx].sg_font_name != NULL
- && STRCMP(HL_TABLE()[idx].sg_font_name, arg) == 0)
- {
- // Font name didn't change, ignore.
- }
- else if (!gui.shell_created)
- {
- // GUI not started yet, always accept the name.
- vim_free(HL_TABLE()[idx].sg_font_name);
- HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
- did_change = TRUE;
- }
- else
- {
- GuiFont temp_sg_font = HL_TABLE()[idx].sg_font;
- # ifdef FEAT_XFONTSET
- GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset;
- # endif
- // First, save the current font/fontset.
- // Then try to allocate the font/fontset.
- // If the allocation fails, HL_TABLE()[idx].sg_font OR
- // sg_fontset will be set to NOFONT or NOFONTSET respectively.
-
- HL_TABLE()[idx].sg_font = NOFONT;
- # ifdef FEAT_XFONTSET
- HL_TABLE()[idx].sg_fontset = NOFONTSET;
- # endif
- hl_do_font(idx, arg, is_normal_group, is_menu_group,
- is_tooltip_group, FALSE);
-
- # ifdef FEAT_XFONTSET
- if (HL_TABLE()[idx].sg_fontset != NOFONTSET)
- {
- // New fontset was accepted. Free the old one, if there
- // was one.
- gui_mch_free_fontset(temp_sg_fontset);
- vim_free(HL_TABLE()[idx].sg_font_name);
- HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
- did_change = TRUE;
- }
- else
- HL_TABLE()[idx].sg_fontset = temp_sg_fontset;
- # endif
- if (HL_TABLE()[idx].sg_font != NOFONT)
- {
- // New font was accepted. Free the old one, if there was
- // one.
- gui_mch_free_font(temp_sg_font);
- vim_free(HL_TABLE()[idx].sg_font_name);
- HL_TABLE()[idx].sg_font_name = vim_strsave(arg);
- did_change = TRUE;
- }
- else
- HL_TABLE()[idx].sg_font = temp_sg_font;
- }
- #endif
- }
- else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0
- || STRCMP(key, "CTERMUL") == 0)
- {
- if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM))
- {
- if (!init)
- HL_TABLE()[idx].sg_set |= SG_CTERM;
! // When setting the foreground color, and previously the "bold"
! // flag was set for a light color, reset it now
! if (key[5] == 'F' && HL_TABLE()[idx].sg_cterm_bold)
{
! HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
! HL_TABLE()[idx].sg_cterm_bold = FALSE;
}
! if (VIM_ISDIGIT(*arg))
! color = atoi((char *)arg);
! else if (STRICMP(arg, "fg") == 0)
! {
! if (cterm_normal_fg_color)
! color = cterm_normal_fg_color - 1;
! else
{
! emsg(_("E419: FG color unknown"));
error = TRUE;
break;
}
}
! else if (STRICMP(arg, "bg") == 0)
{
! if (cterm_normal_bg_color > 0)
! color = cterm_normal_bg_color - 1;
! else
! {
! emsg(_("E420: BG color unknown"));
! error = TRUE;
! break;
! }
}
! else if (STRICMP(arg, "ul") == 0)
{
! if (cterm_normal_ul_color > 0)
! color = cterm_normal_ul_color - 1;
! else
! {
! emsg(_("E453: UL color unknown"));
! error = TRUE;
! break;
! }
}
! else
{
! int bold = MAYBE;
! // reduce calls to STRICMP a bit, it can be slow
! off = TOUPPER_ASC(*arg);
! for (i = ARRAY_LENGTH(color_names); --i >= 0; )
! if (off == color_names[i][0]
! && STRICMP(arg + 1, color_names[i] + 1) == 0)
! break;
! if (i < 0)
{
- semsg(_("E421: Color name or number not recognized: %s"), key_start);
error = TRUE;
break;
}
-
- color = lookup_color(i, key[5] == 'F', &bold);
-
- // set/reset bold attribute to get light foreground
- // colors (on some terminals, e.g. "linux")
- if (bold == TRUE)
- {
- HL_TABLE()[idx].sg_cterm |= HL_BOLD;
- HL_TABLE()[idx].sg_cterm_bold = TRUE;
- }
- else if (bold == FALSE)
- HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
}
!
! // Add one to the argument, to avoid zero. Zero is used for
! // "NONE", then "color" is -1.
! if (key[5] == 'F')
{
! HL_TABLE()[idx].sg_cterm_fg = color + 1;
! if (is_normal_group)
! {
! cterm_normal_fg_color = color + 1;
! cterm_normal_fg_bold = (HL_TABLE()[idx].sg_cterm & HL_BOLD);
#ifdef FEAT_GUI
! // Don't do this if the GUI is used.
! if (!gui.in_use && !gui.starting)
#endif
- {
- must_redraw = CLEAR;
- if (termcap_active && color >= 0)
- term_fg_color(color);
- }
- }
}
! else if (key[5] == 'B')
{
! HL_TABLE()[idx].sg_cterm_bg = color + 1;
! if (is_normal_group)
{
! cterm_normal_bg_color = color + 1;
! #ifdef FEAT_GUI
! // Don't mess with 'background' if the GUI is used.
! if (!gui.in_use && !gui.starting)
! #endif
! {
! must_redraw = CLEAR;
! if (color >= 0)
! {
! int dark = -1;
!
! if (termcap_active)
! term_bg_color(color);
! if (t_colors < 16)
! dark = (color == 0 || color == 4);
! // Limit the heuristic to the standard 16 colors
! else if (color < 16)
! dark = (color < 7 || color == 8);
! // Set the 'background' option if the value is
! // wrong.
! if (dark != -1
! && dark != (*p_bg == 'd')
! && !option_was_set((char_u *)"bg"))
! {
! set_option_value((char_u *)"bg", 0L,
! (char_u *)(dark ? "dark" : "light"), 0);
! reset_option_was_set((char_u *)"bg");
! }
! }
! }
}
}
! else // ctermul
{
! HL_TABLE()[idx].sg_cterm_ul = color + 1;
! if (is_normal_group)
! {
! cterm_normal_ul_color = color + 1;
! #ifdef FEAT_GUI
! // Don't do this if the GUI is used.
! if (!gui.in_use && !gui.starting)
#endif
- {
- must_redraw = CLEAR;
- if (termcap_active && color >= 0)
- term_ul_color(color);
- }
- }
}
! }
! }
! else if (STRCMP(key, "GUIFG") == 0)
! {
! #if defined(FEAT_GUI) || defined(FEAT_EVAL)
! char_u **namep = &HL_TABLE()[idx].sg_gui_fg_name;
!
! if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
{
- if (!init)
- HL_TABLE()[idx].sg_set |= SG_GUI;
-
- # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
- // In GUI guifg colors are only used when recognized
- i = color_name2handle(arg);
- if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
- {
- HL_TABLE()[idx].sg_gui_fg = i;
- # endif
- if (*namep == NULL || STRCMP(*namep, arg) != 0)
- {
- vim_free(*namep);
- if (STRCMP(arg, "NONE") != 0)
- *namep = vim_strsave(arg);
- else
- *namep = NULL;
- did_change = TRUE;
- }
- # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
- # ifdef FEAT_GUI_X11
- if (is_menu_group && gui.menu_fg_pixel != i)
- {
- gui.menu_fg_pixel = i;
- do_colors = TRUE;
- }
- if (is_scrollbar_group && gui.scroll_fg_pixel != i)
- {
- gui.scroll_fg_pixel = i;
- do_colors = TRUE;
- }
- # ifdef FEAT_BEVAL_GUI
- if (is_tooltip_group && gui.tooltip_fg_pixel != i)
- {
- gui.tooltip_fg_pixel = i;
- do_colors = TRUE;
- }
- # endif
- # endif
- }
- # endif
- }
- #endif
- }
- else if (STRCMP(key, "GUIBG") == 0)
- {
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
! char_u **namep = &HL_TABLE()[idx].sg_gui_bg_name;
!
! if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
! {
! if (!init)
! HL_TABLE()[idx].sg_set |= SG_GUI;
!
! # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
! // In GUI guifg colors are only used when recognized
! i = color_name2handle(arg);
! if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
! {
! HL_TABLE()[idx].sg_gui_bg = i;
! # endif
! if (*namep == NULL || STRCMP(*namep, arg) != 0)
! {
! vim_free(*namep);
! if (STRCMP(arg, "NONE") != 0)
! *namep = vim_strsave(arg);
! else
! *namep = NULL;
! did_change = TRUE;
! }
! # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
! # ifdef FEAT_GUI_X11
! if (is_menu_group && gui.menu_bg_pixel != i)
! {
! gui.menu_bg_pixel = i;
! do_colors = TRUE;
! }
! if (is_scrollbar_group && gui.scroll_bg_pixel != i)
! {
! gui.scroll_bg_pixel = i;
! do_colors = TRUE;
! }
! # ifdef FEAT_BEVAL_GUI
! if (is_tooltip_group && gui.tooltip_bg_pixel != i)
! {
! gui.tooltip_bg_pixel = i;
! do_colors = TRUE;
! }
! # endif
! # endif
! }
! # endif
! }
#endif
- }
- else if (STRCMP(key, "GUISP") == 0)
- {
- #if defined(FEAT_GUI) || defined(FEAT_EVAL)
- char_u **namep = &HL_TABLE()[idx].sg_gui_sp_name;
-
- if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI))
- {
- if (!init)
- HL_TABLE()[idx].sg_set |= SG_GUI;
-
- # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
- // In GUI guisp colors are only used when recognized
- i = color_name2handle(arg);
- if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !USE_24BIT)
- {
- HL_TABLE()[idx].sg_gui_sp = i;
- # endif
- if (*namep == NULL || STRCMP(*namep, arg) != 0)
- {
- vim_free(*namep);
- if (STRCMP(arg, "NONE") != 0)
- *namep = vim_strsave(arg);
- else
- *namep = NULL;
- did_change = TRUE;
- }
- # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
- }
- # endif
}
#endif
- }
- else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0)
- {
- char_u buf[100];
- char_u *tname;
-
- if (!init)
- HL_TABLE()[idx].sg_set |= SG_TERM;
-
- /*
- * The "start" and "stop" arguments can be a literal escape
- * sequence, or a comma separated list of terminal codes.
- */
- if (STRNCMP(arg, "t_", 2) == 0)
- {
- off = 0;
- buf[0] = 0;
- while (arg[off] != NUL)
- {
- // Isolate one termcap name
- for (len = 0; arg[off + len] &&
- arg[off + len] != ','; ++len)
- ;
- tname = vim_strnsave(arg + off, len);
- if (tname == NULL) // out of memory
- {
- error = TRUE;
- break;
- }
- // lookup the escape sequence for the item
- p = get_term_code(tname);
- vim_free(tname);
- if (p == NULL) // ignore non-existing things
- p = (char_u *)"";
-
- // Append it to the already found stuff
- if ((int)(STRLEN(buf) + STRLEN(p)) >= 99)
- {
- semsg(_("E422: terminal code too long: %s"), arg);
- error = TRUE;
- break;
- }
- STRCAT(buf, p);
-
- // Advance to the next item
- off += len;
- if (arg[off] == ',') // another one follows
- ++off;
- }
}
! else
{
! /*
! * Copy characters from arg[] to buf[], translating <> codes.
! */
! for (p = arg, off = 0; off < 100 - 6 && *p; )
{
! len = trans_special(&p, buf + off, FSK_SIMPLIFY, NULL);
! if (len > 0) // recognized special char
! off += len;
! else // copy as normal char
! buf[off++] = *p++;
}
- buf[off] = NUL;
}
- if (error)
- break;
-
- if (STRCMP(buf, "NONE") == 0) // resetting the value
- p = NULL;
else
- p = vim_strsave(buf);
- if (key[2] == 'A')
{
! vim_free(HL_TABLE()[idx].sg_start);
! HL_TABLE()[idx].sg_start = p;
! }
! else
! {
! vim_free(HL_TABLE()[idx].sg_stop);
! HL_TABLE()[idx].sg_stop = p;
}
}
- else
- {
- semsg(_("E423: Illegal argument: %s"), key_start);
- error = TRUE;
- break;
- }
- HL_TABLE()[idx].sg_cleared = FALSE;
! /*
! * When highlighting has been given for a group, don't link it.
! */
! if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
! HL_TABLE()[idx].sg_link = 0;
!
! /*
! * Continue with next argument.
! */
! linep = skipwhite(linep);
! }
!
! /*
! * If there is an error, and it's a new entry, remove it from the table.
! */
if (error && idx == highlight_ga.ga_len)
syn_unadd_group();
else
--- 1517,1680 ----
}
if (!doclear)
! while (!ends_excmd2(line, linep))
{
! key_start = linep;
! if (*linep == '=')
{
! semsg(_("E415: unexpected equal sign: %s"), key_start);
error = TRUE;
break;
}
! // Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg"
! // or "guibg").
! while (*linep && !VIM_ISWHITE(*linep) && *linep != '=')
! ++linep;
! vim_free(key);
! key = vim_strnsave_up(key_start, linep - key_start);
! if (key == NULL)
{
! error = TRUE;
break;
}
! linep = skipwhite(linep);
!
! if (STRCMP(key, "NONE") == 0)
{
! if (!init || HL_TABLE()[idx].sg_set == 0)
{
if (!init)
! HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI;
! highlight_clear(idx);
}
+ continue;
}
! // Check for the equal sign.
! if (*linep != '=')
{
! semsg(_("E416: missing equal sign: %s"), key_start);
! error = TRUE;
! break;
}
+ ++linep;
! // Isolate the argument.
! linep = skipwhite(linep);
! if (*linep == '\'') // guifg='color name'
! {
! arg_start = ++linep;
! linep = vim_strchr(linep, '\'');
! if (linep == NULL)
{
! semsg(_(e_invarg2), key_start);
error = TRUE;
break;
}
}
! else
{
! arg_start = linep;
! linep = skiptowhite(linep);
}
! if (linep == arg_start)
{
! semsg(_("E417: missing argument: %s"), key_start);
! error = TRUE;
! break;
}
! vim_free(arg);
! arg = vim_strnsave(arg_start, linep - arg_start);
! if (arg == NULL)
{
! error = TRUE;
! break;
! }
! if (*linep == '\'')
! ++linep;
! // Store the argument.
! if (STRCMP(key, "TERM") == 0
! || STRCMP(key, "CTERM") == 0
! || STRCMP(key, "GUI") == 0)
! {
! if (!highlight_set_termgui_attr(idx, key, arg, init))
{
error = TRUE;
break;
}
}
! else if (STRCMP(key, "FONT") == 0)
{
! // in non-GUI fonts are simply ignored
#ifdef FEAT_GUI
! if (highlight_set_font(idx, arg, is_normal_group,
! is_menu_group, is_tooltip_group))
! did_change = TRUE;
#endif
}
! else if (STRCMP(key, "CTERMFG") == 0
! || STRCMP(key, "CTERMBG") == 0
! || STRCMP(key, "CTERMUL") == 0)
{
! if (!highlight_set_cterm_color(idx, key, key_start, arg,
! is_normal_group, init))
{
! error = TRUE;
! break;
}
}
! else if (STRCMP(key, "GUIFG") == 0)
{
! #if defined(FEAT_GUI) || defined(FEAT_EVAL)
! if (highlight_set_guifg(idx, arg, is_menu_group,
! is_scrollbar_group, is_tooltip_group,
! &do_colors, init))
! did_change = TRUE;
#endif
}
! else if (STRCMP(key, "GUIBG") == 0)
{
#if defined(FEAT_GUI) || defined(FEAT_EVAL)
! if (highlight_set_guibg(idx, arg, is_menu_group,
! is_scrollbar_group, is_tooltip_group,
! &do_colors, init))
! did_change = TRUE;
#endif
}
+ else if (STRCMP(key, "GUISP") == 0)
+ {
+ #if defined(FEAT_GUI) || defined(FEAT_EVAL)
+ if (highlight_set_guisp(idx, arg, init))
+ did_change = TRUE;
#endif
}
! else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0)
{
! if (!highlight_set_startstop_termcode(idx, key, arg, init))
{
! error = TRUE;
! break;
}
}
else
{
! semsg(_("E423: Illegal argument: %s"), key_start);
! error = TRUE;
! break;
}
+ HL_TABLE()[idx].sg_cleared = FALSE;
+
+ // When highlighting has been given for a group, don't link it.
+ if (!init || !(HL_TABLE()[idx].sg_set & SG_LINK))
+ HL_TABLE()[idx].sg_link = 0;
+
+ // Continue with next argument.
+ linep = skipwhite(linep);
}
! // If there is an error, and it's a new entry, remove it from the table.
if (error && idx == highlight_ga.ga_len)
syn_unadd_group();
else
***************
*** 1510,1519 ****
HL_TABLE()[idx].sg_cterm_attr = 0;
#ifdef FEAT_GUI
HL_TABLE()[idx].sg_gui_attr = 0;
! /*
! * Need to update all groups, because they might be using "bg"
! * and/or "fg", which have been changed now.
! */
#endif
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
if (USE_24BIT)
--- 1685,1692 ----
HL_TABLE()[idx].sg_cterm_attr = 0;
#ifdef FEAT_GUI
HL_TABLE()[idx].sg_gui_attr = 0;
! // Need to update all groups, because they might be using "bg"
! // and/or "fg", which have been changed now.
#endif
#if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS)
if (USE_24BIT)
***************
*** 2088,2102 ****
attrentry_T *taep;
static int recursive = FALSE;
! /*
! * Init the table, in case it wasn't done yet.
! */
table->ga_itemsize = sizeof(attrentry_T);
table->ga_growsize = 7;
! /*
! * Try to find an entry with the same specifications.
! */
for (i = 0; i < table->ga_len; ++i)
{
taep = &(((attrentry_T *)table->ga_data)[i]);
--- 2261,2271 ----
attrentry_T *taep;
static int recursive = FALSE;
! // Init the table, in case it wasn't done yet.
table->ga_itemsize = sizeof(attrentry_T);
table->ga_growsize = 7;
! // Try to find an entry with the same specifications.
for (i = 0; i < table->ga_len; ++i)
{
taep = &(((attrentry_T *)table->ga_data)[i]);
***************
*** 2149,2159 ****
if (table->ga_len + ATTR_OFF > MAX_TYPENR)
{
! /*
! * Running out of attribute entries! remove all attributes, and
! * compute new ones for all groups.
! * When called recursively, we are really out of numbers.
! */
if (recursive)
{
emsg(_("E424: Too many different highlighting attributes in use"));
--- 2318,2326 ----
if (table->ga_len + ATTR_OFF > MAX_TYPENR)
{
! // Running out of attribute entries! remove all attributes, and
! // compute new ones for all groups.
! // When called recursively, we are really out of numbers.
if (recursive)
{
emsg(_("E424: Too many different highlighting attributes in use"));
***************
*** 2171,2179 ****
recursive = FALSE;
}
! /*
! * This is a new combination of colors and font, add an entry.
! */
if (ga_grow(table, 1) == FAIL)
return 0;
--- 2338,2344 ----
recursive = FALSE;
}
! // This is a new combination of colors and font, add an entry.
if (ga_grow(table, 1) == FAIL)
return 0;
***************
*** 2852,2861 ****
return;
#ifdef FEAT_GUI
! /*
! * For the GUI mode: If there are other than "normal" highlighting
! * attributes, need to allocate an attr number.
! */
if (sgp->sg_gui_fg == INVALCOLOR
&& sgp->sg_gui_bg == INVALCOLOR
&& sgp->sg_gui_sp == INVALCOLOR
--- 3017,3024 ----
return;
#ifdef FEAT_GUI
! // For the GUI mode: If there are other than "normal" highlighting
! // attributes, need to allocate an attr number.
if (sgp->sg_gui_fg == INVALCOLOR
&& sgp->sg_gui_bg == INVALCOLOR
&& sgp->sg_gui_sp == INVALCOLOR
***************
*** 2880,2889 ****
sgp->sg_gui_attr = get_attr_entry(&gui_attr_table, &at_en);
}
#endif
! /*
! * For the term mode: If there are other than "normal" highlighting
! * attributes, need to allocate an attr number.
! */
if (sgp->sg_start == NULL && sgp->sg_stop == NULL)
sgp->sg_term_attr = sgp->sg_term;
else
--- 3043,3050 ----
sgp->sg_gui_attr = get_attr_entry(&gui_attr_table, &at_en);
}
#endif
! // For the term mode: If there are other than "normal" highlighting
! // attributes, need to allocate an attr number.
if (sgp->sg_start == NULL && sgp->sg_stop == NULL)
sgp->sg_term_attr = sgp->sg_term;
else
***************
*** 2894,2903 ****
sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en);
}
! /*
! * For the color term mode: If there are other than "normal"
! * highlighting attributes, need to allocate an attr number.
! */
if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 && sgp->sg_cterm_ul == 0
# ifdef FEAT_TERMGUICOLORS
&& sgp->sg_gui_fg == INVALCOLOR
--- 3055,3062 ----
sgp->sg_term_attr = get_attr_entry(&term_attr_table, &at_en);
}
! // For the color term mode: If there are other than "normal"
! // highlighting attributes, need to allocate an attr number.
if (sgp->sg_cterm_fg == 0 && sgp->sg_cterm_bg == 0 && sgp->sg_cterm_ul == 0
# ifdef FEAT_TERMGUICOLORS
&& sgp->sg_gui_fg == INVALCOLOR
***************
*** 3088,3096 ****
}
}
! /*
! * First call for this growarray: init growing array.
! */
if (highlight_ga.ga_data == NULL)
{
highlight_ga.ga_itemsize = sizeof(hl_group_T);
--- 3247,3253 ----
}
}
! // First call for this growarray: init growing array.
if (highlight_ga.ga_data == NULL)
{
highlight_ga.ga_itemsize = sizeof(hl_group_T);
***************
*** 3104,3112 ****
return 0;
}
! /*
! * Make room for at least one other syntax_highlight entry.
! */
if (ga_grow(&highlight_ga, 1) == FAIL)
{
vim_free(name);
--- 3261,3267 ----
return 0;
}
! // Make room for at least one other syntax_highlight entry.
if (ga_grow(&highlight_ga, 1) == FAIL)
{
vim_free(name);
***************
*** 3158,3166 ****
sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one
#ifdef FEAT_GUI
! /*
! * Only use GUI attr when the GUI is being used.
! */
if (gui.in_use)
attr = sgp->sg_gui_attr;
else
--- 3313,3319 ----
sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one
#ifdef FEAT_GUI
! // Only use GUI attr when the GUI is being used.
if (gui.in_use)
attr = sgp->sg_gui_attr;
else
***************
*** 3220,3229 ****
if (hl_id > highlight_ga.ga_len || hl_id < 1)
return 0; // Can be called from eval!!
! /*
! * Follow links until there is no more.
! * Look out for loops! Break after 100 links.
! */
for (count = 100; --count >= 0; )
{
sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one
--- 3373,3380 ----
if (hl_id > highlight_ga.ga_len || hl_id < 1)
return 0; // Can be called from eval!!
! // Follow links until there is no more.
! // Look out for loops! Break after 100 links.
for (count = 100; --count >= 0; )
{
sgp = &HL_TABLE()[hl_id - 1]; // index is ID minus one
***************
*** 3398,3413 ****
need_highlight_changed = FALSE;
! /*
! * Clear all attributes.
! */
for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
highlight_attr[hlf] = 0;
! /*
! * First set all attributes to their default value.
! * Then use the attributes from the 'highlight' option.
! */
for (i = 0; i < 2; ++i)
{
if (i)
--- 3549,3560 ----
need_highlight_changed = FALSE;
! // Clear all attributes.
for (hlf = 0; hlf < (int)HLF_COUNT; ++hlf)
highlight_attr[hlf] = 0;
! // First set all attributes to their default value.
! // Then use the attributes from the 'highlight' option.
for (i = 0; i < 2; ++i)
{
if (i)
***************
*** 3426,3435 ****
if (hlf == (int)HLF_COUNT || *p == NUL)
return FAIL;
! /*
! * Allow several hl_flags to be combined, like "bu" for
! * bold-underlined.
! */
attr = 0;
for ( ; *p && *p != ','; ++p) // parse up to comma
{
--- 3573,3580 ----
if (hlf == (int)HLF_COUNT || *p == NUL)
return FAIL;
! // Allow several hl_flags to be combined, like "bu" for
! // bold-underlined.
attr = 0;
for ( ; *p && *p != ','; ++p) // parse up to comma
{
***************
*** 3492,3508 ****
}
#ifdef USER_HIGHLIGHT
! /*
! * Setup the user highlights
! *
! * Temporarily utilize 28 more hl entries:
! * 9 for User1-User9 combined with StatusLineNC
! * 9 for User1-User9 combined with StatusLineTerm
! * 9 for User1-User9 combined with StatusLineTermNC
! * 1 for StatusLine default
! * Have to be in there simultaneously in case of table overflows in
! * get_attr_entry()
! */
# ifdef FEAT_STL_OPT
if (ga_grow(&highlight_ga, 28) == FAIL)
return FAIL;
--- 3637,3651 ----
}
#ifdef USER_HIGHLIGHT
! // Setup the user highlights
! //
! // Temporarily utilize 28 more hl entries:
! // 9 for User1-User9 combined with StatusLineNC
! // 9 for User1-User9 combined with StatusLineTerm
! // 9 for User1-User9 combined with StatusLineTermNC
! // 1 for StatusLine default
! // Have to be in there simultaneously in case of table overflows in
! // get_attr_entry()
# ifdef FEAT_STL_OPT
if (ga_grow(&highlight_ga, 28) == FAIL)
return FAIL;
*** ../vim-8.2.3535/src/version.c 2021-10-18 20:56:32.117548181 +0100
--- src/version.c 2021-10-18 22:08:49.651342156 +0100
***************
*** 759,760 ****
--- 759,762 ----
{ /* Add new patch number below this line */
+ /**/
+ 3536,
/**/
--
hundred-and-one symptoms of being an internet addict:
195. Your cat has its own home page.
/// Bram Moolenaar -- Br...@Moolenaar.net --
http://www.Moolenaar.net \\\
/// \\\
\\\ sponsor Vim, vote for features --
http://www.Vim.org/sponsor/ ///
\\\ help me help AIDS victims --
http://ICCF-Holland.org ///