]> granicus.if.org Git - vim/commitdiff
patch 8.0.1072: :highlight command causes a redraw even when nothing changed v8.0.1072
authorBram Moolenaar <Bram@vim.org>
Fri, 8 Sep 2017 10:37:47 +0000 (12:37 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 8 Sep 2017 10:37:47 +0000 (12:37 +0200)
Problem:    The :highlight command causes a redraw even when nothing changed.
Solution:   Only set "need_highlight_changed" when an attribute changed.

src/syntax.c
src/version.c

index 00e292932df3c1c56db223521e877142163b4cf9..ded6cd33d9aa177be67bc6b9ca349cf2a8143dda 100644 (file)
@@ -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,22 +7479,26 @@ 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;
+               item->sg_scriptID = current_SID;
 #endif
-               HL_TABLE()[from_id - 1].sg_cleared = FALSE;
+               item->sg_cleared = FALSE;
                redraw_all_later(SOME_VALID);
+
+               /* Only call highlight_changed() once after multiple changes. */
+               need_highlight_changed = TRUE;
            }
        }
 
-       /* Only call highlight_changed() once, after sourcing a syntax file */
-       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)
+           if (key[5] == 'F' && item->sg_cterm_bold)
            {
-               HL_TABLE()[idx].sg_cterm &= ~HL_BOLD;
-               HL_TABLE()[idx].sg_cterm_bold = FALSE;
+               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;
+       item->sg_scriptID = current_SID;
 #endif
-       redraw_all_later(NOT_VALID);
     }
+
     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)
index 4d040fb0dbc993756b72063ad92336b191238369..2ffd91a509dccd15fa9d36a2e0d9e3fcdfc46ea6 100644 (file)
@@ -769,6 +769,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1072,
 /**/
     1071,
 /**/