# HG changeset patch # User Christian Brabandt # Date 1504867504 -7200 # Node ID 972732a27d7c01b0af134344ddb4e5de2402f062 # Parent a9cf1e51c795cf62bac2e45cc002872e9d41a780 patch 8.0.1072: :highlight command causes a redraw even when nothing changed commit https://github.com/vim/vim/commit/99433291b135094d9592c41f96d3ccd60073e2c1 Author: Bram Moolenaar Date: Fri Sep 8 12:37:47 2017 +0200 patch 8.0.1072: :highlight command causes a redraw even when nothing changed Problem: The :highlight command causes a redraw even when nothing changed. Solution: Only set "need_highlight_changed" when an attribute changed. diff --git a/src/syntax.c b/src/syntax.c --- a/src/syntax.c +++ b/src/syntax.c @@ -7364,6 +7364,8 @@ do_highlight( int attr; int id; int idx; + struct hl_group *item; + struct hl_group item_before; int dodefault = FALSE; int doclear = FALSE; int dolink = FALSE; @@ -7459,12 +7461,13 @@ do_highlight( } from_id = syn_check_group(from_start, (int)(from_end - from_start)); + item = &HL_TABLE()[from_id - 1]; 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 && (!init || HL_TABLE()[from_id - 1].sg_set == 0)) + if (from_id > 0 && (!init || item->sg_set == 0)) { /* * Don't allow a link when there already is some highlighting @@ -7476,21 +7479,25 @@ do_highlight( if (sourcing_name == NULL && !dodefault) EMSG(_("E414: group has settings, highlight link ignored")); } - else + else if (item->sg_link != to_id +#ifdef FEAT_EVAL + || item->sg_scriptID != current_SID +#endif + || item->sg_cleared) { if (!init) - HL_TABLE()[from_id - 1].sg_set |= SG_LINK; - HL_TABLE()[from_id - 1].sg_link = to_id; + item->sg_set |= SG_LINK; + item->sg_link = to_id; #ifdef FEAT_EVAL - HL_TABLE()[from_id - 1].sg_scriptID = current_SID; -#endif - HL_TABLE()[from_id - 1].sg_cleared = FALSE; + item->sg_scriptID = current_SID; +#endif + item->sg_cleared = FALSE; redraw_all_later(SOME_VALID); - } - } - - /* Only call highlight_changed() once, after sourcing a syntax file */ - need_highlight_changed = TRUE; + + /* Only call highlight_changed() once after multiple changes. */ + need_highlight_changed = TRUE; + } + } return; } @@ -7577,19 +7584,23 @@ do_highlight( if (id == 0) /* failed (out of memory) */ return; idx = id - 1; /* index is ID minus one */ + item = &HL_TABLE()[idx]; /* Return if "default" was used and the group already has settings. */ if (dodefault && hl_has_settings(idx, TRUE)) return; - if (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0) + /* Make a copy so we can check if any attribute actually changed. */ + item_before = *item; + + if (STRCMP(item->sg_name_u, "NORMAL") == 0) is_normal_group = TRUE; #ifdef FEAT_GUI_X11 - else if (STRCMP(HL_TABLE()[idx].sg_name_u, "MENU") == 0) + else if (STRCMP(item->sg_name_u, "MENU") == 0) is_menu_group = TRUE; - else if (STRCMP(HL_TABLE()[idx].sg_name_u, "SCROLLBAR") == 0) + else if (STRCMP(item->sg_name_u, "SCROLLBAR") == 0) is_scrollbar_group = TRUE; - else if (STRCMP(HL_TABLE()[idx].sg_name_u, "TOOLTIP") == 0) + else if (STRCMP(item->sg_name_u, "TOOLTIP") == 0) is_tooltip_group = TRUE; #endif @@ -7598,7 +7609,7 @@ do_highlight( { highlight_clear(idx); if (!doclear) - HL_TABLE()[idx].sg_set = 0; + item->sg_set = 0; } if (!doclear) @@ -7629,10 +7640,10 @@ do_highlight( if (STRCMP(key, "NONE") == 0) { - if (!init || HL_TABLE()[idx].sg_set == 0) + if (!init || item->sg_set == 0) { if (!init) - HL_TABLE()[idx].sg_set |= SG_TERM+SG_CTERM+SG_GUI; + item->sg_set |= SG_TERM+SG_CTERM+SG_GUI; highlight_clear(idx); } continue; @@ -7719,31 +7730,31 @@ do_highlight( break; if (*key == 'T') { - if (!init || !(HL_TABLE()[idx].sg_set & SG_TERM)) + if (!init || !(item->sg_set & SG_TERM)) { if (!init) - HL_TABLE()[idx].sg_set |= SG_TERM; - HL_TABLE()[idx].sg_term = attr; + item->sg_set |= SG_TERM; + item->sg_term = attr; } } else if (*key == 'C') { - if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) + if (!init || !(item->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; + item->sg_set |= SG_CTERM; + item->sg_cterm = attr; + item->sg_cterm_bold = FALSE; } } #if defined(FEAT_GUI) || defined(FEAT_EVAL) else { - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) + if (!init || !(item->sg_set & SG_GUI)) { if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; - HL_TABLE()[idx].sg_gui = attr; + item->sg_set |= SG_GUI; + item->sg_gui = attr; } } #endif @@ -7752,69 +7763,74 @@ do_highlight( { /* in non-GUI fonts are simply ignored */ #ifdef FEAT_GUI - if (!gui.shell_created) + if (item->sg_font_name != NULL + && STRCMP(item->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); + vim_free(item->sg_font_name); + item->sg_font_name = vim_strsave(arg); } else { - GuiFont temp_sg_font = HL_TABLE()[idx].sg_font; + GuiFont temp_sg_font = item->sg_font; # ifdef FEAT_XFONTSET - GuiFontset temp_sg_fontset = HL_TABLE()[idx].sg_fontset; + GuiFontset temp_sg_fontset = item->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 + * If the allocation fails, item->sg_font OR * sg_fontset will be set to NOFONT or NOFONTSET respectively. */ - HL_TABLE()[idx].sg_font = NOFONT; + item->sg_font = NOFONT; # ifdef FEAT_XFONTSET - HL_TABLE()[idx].sg_fontset = NOFONTSET; + item->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) + if (item->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); + vim_free(item->sg_font_name); + item->sg_font_name = vim_strsave(arg); } else - HL_TABLE()[idx].sg_fontset = temp_sg_fontset; + item->sg_fontset = temp_sg_fontset; # endif - if (HL_TABLE()[idx].sg_font != NOFONT) + if (item->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); + vim_free(item->sg_font_name); + item->sg_font_name = vim_strsave(arg); } else - HL_TABLE()[idx].sg_font = temp_sg_font; + item->sg_font = temp_sg_font; } #endif } else if (STRCMP(key, "CTERMFG") == 0 || STRCMP(key, "CTERMBG") == 0) { - if (!init || !(HL_TABLE()[idx].sg_set & SG_CTERM)) + if (!init || !(item->sg_set & SG_CTERM)) { if (!init) - HL_TABLE()[idx].sg_set |= SG_CTERM; + item->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 (key[5] == 'F' && item->sg_cterm_bold) + { + item->sg_cterm &= ~HL_BOLD; + item->sg_cterm_bold = FALSE; } if (VIM_ISDIGIT(*arg)) @@ -7871,22 +7887,22 @@ do_highlight( * colors (on some terminals, e.g. "linux") */ if (bold == TRUE) { - HL_TABLE()[idx].sg_cterm |= HL_BOLD; - HL_TABLE()[idx].sg_cterm_bold = TRUE; + item->sg_cterm |= HL_BOLD; + item->sg_cterm_bold = TRUE; } else if (bold == FALSE) - HL_TABLE()[idx].sg_cterm &= ~HL_BOLD; + item->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; + item->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); + cterm_normal_fg_bold = (item->sg_cterm & HL_BOLD); #ifdef FEAT_GUI /* Don't do this if the GUI is used. */ if (!gui.in_use && !gui.starting) @@ -7900,7 +7916,7 @@ do_highlight( } else { - HL_TABLE()[idx].sg_cterm_bg = color + 1; + item->sg_cterm_bg = color + 1; if (is_normal_group) { cterm_normal_bg_color = color + 1; @@ -7940,23 +7956,23 @@ do_highlight( else if (STRCMP(key, "GUIFG") == 0) { #if defined(FEAT_GUI) || defined(FEAT_EVAL) - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) + if (!init || !(item->sg_set & SG_GUI)) { if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; + item->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; + item->sg_gui_fg = i; # endif - vim_free(HL_TABLE()[idx].sg_gui_fg_name); + vim_free(item->sg_gui_fg_name); if (STRCMP(arg, "NONE") != 0) - HL_TABLE()[idx].sg_gui_fg_name = vim_strsave(arg); + item->sg_gui_fg_name = vim_strsave(arg); else - HL_TABLE()[idx].sg_gui_fg_name = NULL; + item->sg_gui_fg_name = NULL; # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) # ifdef FEAT_GUI_X11 if (is_menu_group) @@ -7977,23 +7993,23 @@ do_highlight( else if (STRCMP(key, "GUIBG") == 0) { #if defined(FEAT_GUI) || defined(FEAT_EVAL) - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) + if (!init || !(item->sg_set & SG_GUI)) { if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; + item->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; + item->sg_gui_bg = i; # endif - vim_free(HL_TABLE()[idx].sg_gui_bg_name); + vim_free(item->sg_gui_bg_name); if (STRCMP(arg, "NONE") != 0) - HL_TABLE()[idx].sg_gui_bg_name = vim_strsave(arg); + item->sg_gui_bg_name = vim_strsave(arg); else - HL_TABLE()[idx].sg_gui_bg_name = NULL; + item->sg_gui_bg_name = NULL; # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) # ifdef FEAT_GUI_X11 if (is_menu_group) @@ -8014,22 +8030,22 @@ do_highlight( else if (STRCMP(key, "GUISP") == 0) { #if defined(FEAT_GUI) || defined(FEAT_EVAL) - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) + if (!init || !(item->sg_set & SG_GUI)) { if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; + item->sg_set |= SG_GUI; # ifdef FEAT_GUI i = color_name2handle(arg); if (i != INVALCOLOR || STRCMP(arg, "NONE") == 0 || !gui.in_use) { - HL_TABLE()[idx].sg_gui_sp = i; + item->sg_gui_sp = i; # endif - vim_free(HL_TABLE()[idx].sg_gui_sp_name); + vim_free(item->sg_gui_sp_name); if (STRCMP(arg, "NONE") != 0) - HL_TABLE()[idx].sg_gui_sp_name = vim_strsave(arg); + item->sg_gui_sp_name = vim_strsave(arg); else - HL_TABLE()[idx].sg_gui_sp_name = NULL; + item->sg_gui_sp_name = NULL; # ifdef FEAT_GUI } # endif @@ -8042,7 +8058,7 @@ do_highlight( char_u *tname; if (!init) - HL_TABLE()[idx].sg_set |= SG_TERM; + item->sg_set |= SG_TERM; /* * The "start" and "stop" arguments can be a literal escape @@ -8109,13 +8125,13 @@ do_highlight( p = vim_strsave(buf); if (key[2] == 'A') { - vim_free(HL_TABLE()[idx].sg_start); - HL_TABLE()[idx].sg_start = p; + vim_free(item->sg_start); + item->sg_start = p; } else { - vim_free(HL_TABLE()[idx].sg_stop); - HL_TABLE()[idx].sg_stop = p; + vim_free(item->sg_stop); + item->sg_stop = p; } } else @@ -8124,13 +8140,13 @@ do_highlight( error = TRUE; break; } - HL_TABLE()[idx].sg_cleared = FALSE; + item->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; + if (!init || !(item->sg_set & SG_LINK)) + item->sg_link = 0; /* * Continue with next argument. @@ -8147,10 +8163,10 @@ do_highlight( { if (is_normal_group) { - HL_TABLE()[idx].sg_term_attr = 0; - HL_TABLE()[idx].sg_cterm_attr = 0; + item->sg_term_attr = 0; + item->sg_cterm_attr = 0; #ifdef FEAT_GUI - HL_TABLE()[idx].sg_gui_attr = 0; + item->sg_gui_attr = 0; /* * Need to update all groups, because they might be using "bg" * and/or "fg", which have been changed now. @@ -8185,15 +8201,20 @@ do_highlight( else set_hl_attr(idx); #ifdef FEAT_EVAL - HL_TABLE()[idx].sg_scriptID = current_SID; -#endif - redraw_all_later(NOT_VALID); - } + item->sg_scriptID = current_SID; +#endif + } + vim_free(key); vim_free(arg); - /* Only call highlight_changed() once, after sourcing a syntax file */ - need_highlight_changed = TRUE; + /* Only call highlight_changed() once, after a sequence of highlight + * commands, and only if an attribute actually changed. */ + if (memcmp(item, &item_before, sizeof(item_before)) != 0) + { + redraw_all_later(NOT_VALID); + need_highlight_changed = TRUE; + } } #if defined(EXITFREE) || defined(PROTO) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -770,6 +770,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1072, +/**/ 1071, /**/ 1070,