diff options
author | Jan Edmund Lazo <janedmundlazo@hotmail.com> | 2018-07-25 23:36:06 -0400 |
---|---|---|
committer | Jan Edmund Lazo <janedmundlazo@hotmail.com> | 2018-07-29 07:52:45 -0400 |
commit | 6b7b56dabe33a9f48c14a5d075b7796c0d2f3bb5 (patch) | |
tree | 9794bef4edc0284fa5ab1afa911ba273fdebee0d /src/nvim/syntax.c | |
parent | 0c0318f8a7ccbf1b286a4c52fefc168534ff7f5e (diff) | |
download | rneovim-6b7b56dabe33a9f48c14a5d075b7796c0d2f3bb5.tar.gz rneovim-6b7b56dabe33a9f48c14a5d075b7796c0d2f3bb5.tar.bz2 rneovim-6b7b56dabe33a9f48c14a5d075b7796c0d2f3bb5.zip |
vim-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.
https://github.com/vim/vim/commit/99433291b135094d9592c41f96d3ccd60073e2c1
Diffstat (limited to 'src/nvim/syntax.c')
-rw-r--r-- | src/nvim/syntax.c | 158 |
1 files changed, 87 insertions, 71 deletions
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index 86ce259a29..dcac907c5a 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -53,7 +53,7 @@ static bool did_syntax_onoff = false; struct hl_group { char_u *sg_name; ///< highlight group name char_u *sg_name_u; ///< uppercase of sg_name - int sg_cleared; ///< "hi clear" was used + bool sg_cleared; ///< "hi clear" was used int sg_attr; ///< Screen attr @see ATTR_ENTRY int sg_link; ///< link to this highlight group ID int sg_set; ///< combination of flags in \ref SG_SET @@ -6492,10 +6492,12 @@ void do_highlight(const char *line, const bool forceit, const bool init) int attr; int id; int idx; - int dodefault = FALSE; - int doclear = FALSE; - int dolink = FALSE; - int error = FALSE; + struct hl_group *item; + struct hl_group item_before; + bool dodefault = false; + bool doclear = false; + bool dolink = false; + bool error = false; int color; bool is_normal_group = false; // "Normal" group @@ -6565,6 +6567,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) from_id = syn_check_group((const char_u *)from_start, (int)(from_end - from_start)); + item = &HL_TABLE()[from_id - 1]; if (strncmp(to_start, "NONE", 4) == 0) { to_id = 0; } else { @@ -6572,7 +6575,7 @@ void do_highlight(const char *line, const bool forceit, const bool init) (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 // for the group, unless '!' is used if (to_id > 0 && !forceit && !init @@ -6580,19 +6583,22 @@ void do_highlight(const char *line, const bool forceit, const bool init) if (sourcing_name == NULL && !dodefault) { EMSG(_("E414: group has settings, highlight link ignored")); } - } else { - if (!init) - HL_TABLE()[from_id - 1].sg_set |= SG_LINK; - HL_TABLE()[from_id - 1].sg_link = to_id; - HL_TABLE()[from_id - 1].sg_scriptID = current_SID; - HL_TABLE()[from_id - 1].sg_cleared = false; + } else if (item->sg_link != to_id + || item->sg_scriptID != current_SID + || item->sg_cleared) { + if (!init) { + item->sg_set |= SG_LINK; + } + item->sg_link = to_id; + item->sg_scriptID = current_SID; + 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; } @@ -6622,19 +6628,23 @@ void do_highlight(const char *line, const bool forceit, const bool init) 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; } - is_normal_group = (STRCMP(HL_TABLE()[idx].sg_name_u, "NORMAL") == 0); + // Make a copy so we can check if any attribute actually changed + item_before = *item; + is_normal_group = (STRCMP(item->sg_name_u, "NORMAL") == 0); // Clear the highlighting for ":hi clear {group}" and ":hi clear". if (doclear || (forceit && init)) { highlight_clear(idx); - if (!doclear) - HL_TABLE()[idx].sg_set = 0; + if (!doclear) { + item->sg_set = 0; + } } char *key = NULL; @@ -6659,9 +6669,9 @@ void do_highlight(const char *line, const bool forceit, const bool init) linep = (const char *)skipwhite((const char_u *)linep); 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_CTERM+SG_GUI; + item->sg_set |= SG_CTERM+SG_GUI; } highlight_clear(idx); } @@ -6730,34 +6740,34 @@ void do_highlight(const char *line, const bool forceit, const bool init) break; } 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; + item->sg_set |= SG_CTERM; } - HL_TABLE()[idx].sg_cterm = attr; - HL_TABLE()[idx].sg_cterm_bold = false; + item->sg_cterm = attr; + item->sg_cterm_bold = false; } } else if (*key == 'G') { - 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; } - HL_TABLE()[idx].sg_gui = attr; + item->sg_gui = attr; } } } else if (STRCMP(key, "FONT") == 0) { // in non-GUI fonts are simply ignored } 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 (ascii_isdigit(*arg)) { @@ -6800,21 +6810,21 @@ void do_highlight(const char *line, const bool forceit, const bool init) // set/reset bold attribute to get light foreground // colors (on some terminals, e.g. "linux") if (bold == kTrue) { - 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 == kFalse) { - 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; } } 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; if (!ui_rgb_attached()) { @@ -6841,58 +6851,61 @@ void do_highlight(const char *line, const bool forceit, const bool init) } } } else if (strcmp(key, "GUIFG") == 0) { - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { - if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; + if (!init || !(item->sg_set & SG_GUI)) { + if (!init) { + item->sg_set |= SG_GUI; + } - xfree(HL_TABLE()[idx].sg_rgb_fg_name); + xfree(item->sg_rgb_fg_name); if (strcmp(arg, "NONE")) { - HL_TABLE()[idx].sg_rgb_fg_name = (char_u *)xstrdup((char *)arg); - HL_TABLE()[idx].sg_rgb_fg = name_to_color((const char_u *)arg); + item->sg_rgb_fg_name = (char_u *)xstrdup((char *)arg); + item->sg_rgb_fg = name_to_color((const char_u *)arg); } else { - HL_TABLE()[idx].sg_rgb_fg_name = NULL; - HL_TABLE()[idx].sg_rgb_fg = -1; + item->sg_rgb_fg_name = NULL; + item->sg_rgb_fg = -1; } } if (is_normal_group) { - normal_fg = HL_TABLE()[idx].sg_rgb_fg; + normal_fg = item->sg_rgb_fg; } } else if (STRCMP(key, "GUIBG") == 0) { - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { - if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; + if (!init || !(item->sg_set & SG_GUI)) { + if (!init) { + item->sg_set |= SG_GUI; + } - xfree(HL_TABLE()[idx].sg_rgb_bg_name); + xfree(item->sg_rgb_bg_name); if (STRCMP(arg, "NONE") != 0) { - HL_TABLE()[idx].sg_rgb_bg_name = (char_u *)xstrdup((char *)arg); - HL_TABLE()[idx].sg_rgb_bg = name_to_color((const char_u *)arg); + item->sg_rgb_bg_name = (char_u *)xstrdup((char *)arg); + item->sg_rgb_bg = name_to_color((const char_u *)arg); } else { - HL_TABLE()[idx].sg_rgb_bg_name = NULL; - HL_TABLE()[idx].sg_rgb_bg = -1; + item->sg_rgb_bg_name = NULL; + item->sg_rgb_bg = -1; } } if (is_normal_group) { - normal_bg = HL_TABLE()[idx].sg_rgb_bg; + normal_bg = item->sg_rgb_bg; } } else if (strcmp(key, "GUISP") == 0) { - if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) { - if (!init) - HL_TABLE()[idx].sg_set |= SG_GUI; + if (!init || !(item->sg_set & SG_GUI)) { + if (!init) { + item->sg_set |= SG_GUI; + } - xfree(HL_TABLE()[idx].sg_rgb_sp_name); + xfree(item->sg_rgb_sp_name); if (strcmp(arg, "NONE") != 0) { - HL_TABLE()[idx].sg_rgb_sp_name = (char_u *)xstrdup((char *)arg); - HL_TABLE()[idx].sg_rgb_sp = name_to_color((const char_u *)arg); + item->sg_rgb_sp_name = (char_u *)xstrdup((char *)arg); + item->sg_rgb_sp = name_to_color((const char_u *)arg); } else { - HL_TABLE()[idx].sg_rgb_sp_name = NULL; - HL_TABLE()[idx].sg_rgb_sp = -1; + item->sg_rgb_sp_name = NULL; + item->sg_rgb_sp = -1; } } if (is_normal_group) { - normal_sp = HL_TABLE()[idx].sg_rgb_sp; + normal_sp = item->sg_rgb_sp; } } else if (strcmp(key, "START") == 0 || strcmp(key, "STOP") == 0) { // Ignored for now @@ -6901,11 +6914,11 @@ void do_highlight(const char *line, const bool forceit, const bool init) 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. @@ -6934,14 +6947,17 @@ void do_highlight(const char *line, const bool forceit, const bool init) } else { set_hl_attr(idx); } - HL_TABLE()[idx].sg_scriptID = current_SID; - redraw_all_later(NOT_VALID); + item->sg_scriptID = current_SID; } xfree(key); xfree(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) |