# HG changeset patch # User Christian Brabandt # Date 1506780904 -7200 # Node ID 31737ff54115a5372972dab307e5d91294c16706 # Parent b514b5992d419e0286c1d1bc25ae3bba1f8c9bba patch 8.0.1164: changing StatusLine highlight does not always work commit https://github.com/vim/vim/commit/65ed136844fbaffdd473903ed841c944600234dc Author: Bram Moolenaar Date: Sat Sep 30 16:00:14 2017 +0200 patch 8.0.1164: changing StatusLine highlight does not always work Problem: Changing StatusLine highlight while evaluating 'statusline' may not change the status line color. Solution: When changing highlighting while redrawing don't cause another redraw. (suggested by Ozaki Kiichi, closes #2171, closes #2120) diff --git a/src/buffer.c b/src/buffer.c --- a/src/buffer.c +++ b/src/buffer.c @@ -3910,7 +3910,6 @@ build_stl_str_hl( struct stl_hlrec *sp; int save_must_redraw = must_redraw; int save_redr_type = curwin->w_redr_type; - int save_highlight_shcnaged = need_highlight_changed; #ifdef FEAT_EVAL /* @@ -4683,12 +4682,13 @@ build_stl_str_hl( sp->userhl = 0; } - /* We do not want redrawing a stausline, ruler, title, etc. to trigger - * another redraw, it may cause an endless loop. This happens when a - * statusline changes a highlight group. */ - must_redraw = save_must_redraw; - curwin->w_redr_type = save_redr_type; - need_highlight_changed = save_highlight_shcnaged; + /* When inside update_screen we do not want redrawing a stausline, ruler, + * title, etc. to trigger another redraw, it may cause an endless loop. */ + if (updating_screen) + { + must_redraw = save_must_redraw; + curwin->w_redr_type = save_redr_type; + } return width; } diff --git a/src/syntax.c b/src/syntax.c --- a/src/syntax.c +++ b/src/syntax.c @@ -7378,6 +7378,7 @@ do_highlight( int id; int idx; struct hl_group item_before; + int did_change = FALSE; int dodefault = FALSE; int doclear = FALSE; int dolink = FALSE; @@ -7787,6 +7788,7 @@ do_highlight( /* 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 { @@ -7815,6 +7817,7 @@ do_highlight( 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; @@ -7826,6 +7829,7 @@ do_highlight( 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; @@ -7991,6 +7995,7 @@ do_highlight( *namep = vim_strsave(arg); else *namep = NULL; + did_change = TRUE; } # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) # ifdef FEAT_GUI_X11 @@ -8041,6 +8046,7 @@ do_highlight( *namep = vim_strsave(arg); else *namep = NULL; + did_change = TRUE; } # if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) # ifdef FEAT_GUI_X11 @@ -8090,6 +8096,7 @@ do_highlight( *namep = vim_strsave(arg); else *namep = NULL; + did_change = TRUE; } # ifdef FEAT_GUI } @@ -8259,13 +8266,18 @@ do_highlight( /* Only call highlight_changed() once, after a sequence of highlight * commands, and only if an attribute actually changed. */ - if (memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0 + if ((did_change + || memcmp(&HL_TABLE()[idx], &item_before, sizeof(item_before)) != 0) #if defined(FEAT_GUI) || defined(FEAT_TERMGUICOLORS) && !did_highlight_changed #endif ) { - redraw_all_later(NOT_VALID); + /* Do not trigger a redraw when highlighting is changed while + * redrawing. This may happen when evaluating 'statusline' changes the + * StatusLine group. */ + if (!updating_screen) + redraw_all_later(NOT_VALID); need_highlight_changed = TRUE; } } diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -762,6 +762,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1164, +/**/ 1163, /**/ 1162,