diff options
| -rw-r--r-- | src/nvim/syntax.c | 2 | ||||
| -rw-r--r-- | src/nvim/tui/terminfo.c | 23 | ||||
| -rw-r--r-- | src/nvim/tui/tui.c | 36 | ||||
| -rw-r--r-- | test/functional/ex_cmds/highlight_spec.lua | 43 | 
4 files changed, 77 insertions, 27 deletions
diff --git a/src/nvim/syntax.c b/src/nvim/syntax.c index d28e996581..bc7362af72 100644 --- a/src/nvim/syntax.c +++ b/src/nvim/syntax.c @@ -6648,7 +6648,7 @@ do_highlight(char_u *line, int forceit, int init) {    if (error && idx == highlight_ga.ga_len) {      syn_unadd_group();    } else { -    if (is_normal_group) { +    if (!error && is_normal_group) {        // Need to update all groups, because they might be using "bg" and/or        // "fg", which have been changed now.        highlight_attr_set_all(); diff --git a/src/nvim/tui/terminfo.c b/src/nvim/tui/terminfo.c index 6b0be50917..75e9a2d8da 100644 --- a/src/nvim/tui/terminfo.c +++ b/src/nvim/tui/terminfo.c @@ -8,6 +8,7 @@  #include <unibilium.h> +#include "nvim/log.h"  #include "nvim/tui/terminfo.h"  #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -77,8 +78,6 @@ static const signed char ansi_terminfo[] = {    26,   1,  40,   0,  23,   0,  16,   0, 125,   1,  68,   2,  97, 110, 115, 105, 124,  97, 110, 115, 105,  47, 112,  99,  45, 116, 101, 114, 109,  32,  99, 111, 109, 112,  97, 116, 105,  98, 108, 101,  32, 119, 105, 116, 104,  32,  99, 111, 108, 111, 114,   0,   0,   1,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   0,   1,   1,   0,   0,   0,   0,   0,   0,   0,   1,   0,  80,   0,   8,   0,  24,   0,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   8,   0,  64,   0,   3,   0,   0,   0,   4,   0,   6,   0,  -1,  -1,   8,   0,  13,   0,  20,   0,  24,   0,  28,   0,  -1,  -1,  39,   0,  56,   0,  60,   0,  -1,  -1,  64,   0,  -1,  -1,  -1,  -1,  68,   0,  -1,  -1,  72,   0,  -1,  -1,  76,   0,  80,   0,  -1,  -1,  -1,  -1,  84,   0,  90,   0,  95,   0,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, 100,   0,  -1,  -1, 105,   0, 110,   0, 115,   0, 120,   0,-127,   0,-121,   0,  -1,  -1,  -1,  -1,  -1,  -1,-113,   0,-109,   0,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,-105,   0,  -1,  -1,-101,   0,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, -99,   0,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, -95,   0, -91,   0,  -1,  -1, -87,   0,  -1,  -1,  -1,  -1,  -1,  -1, -83,   0,  -1,  -1,  -1,  -1,  -1,  -1, -79,   0,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, -75,   0,  -1,  -1, -70,   0, -61,   0, -52,   0, -43,   0, -34,   0, -25,   0, -16,   0,  -7,   0,   2,   1,  11,   1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  20,   1,  25,   1,  30,   1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  50,   1,  -1,  -1,  61,   1,  -1,  -1,  63,   1,-107,   1,  -1,  -1,-104,   1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,-100,   1,  -1,  -1, -37,   1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, -33,   1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, -28,   1, -17,   1, -12,   1,   7,   2,  11,   2,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  20,   2,  30,   2,  -1,  -1,  -1,  -1,  -1,  -1,  40,   2,  44,   2,  48,   2,  52,   2,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  56,   2,  62,   2,  27,  91,  90,   0,   7,   0,  13,   0,  27,  91,  51, 103,   0,  27,  91,  72,  27,  91,  74,   0,  27,  91,  75,   0,  27,  91,  74,   0,  27,  91,  37, 105,  37, 112,  49,  37, 100,  71,   0,  27,  91,  37, 105,  37, 112,  49,  37, 100,  59,  37, 112,  50,  37, 100,  72,   0,  27,  91,  66,   0,  27,  91,  72,   0,  27,  91,  68,   0,  27,  91,  67,   0,  27,  91,  65,   0,  27,  91,  80,   0,  27,  91,  77,   0,  27,  91,  49,  49, 109,   0,  27,  91,  53, 109,   0,  27,  91,  49, 109,   0,  27,  91,  56, 109,   0,  27,  91,  55, 109,   0,  27,  91,  55, 109,   0,  27,  91,  52, 109,   0,  27,  91,  37, 112,  49,  37, 100,  88,   0,  27,  91,  49,  48, 109,   0,  27,  91,  48,  59,  49,  48, 109,   0,  27,  91, 109,   0,  27,  91, 109,   0,  27,  91,  76,   0,   8,   0,  27,  91,  66,   0,  27,  91,  72,   0,  27,  91,  76,   0,  27,  91,  68,   0,  27,  91,  67,   0,  27,  91,  65,   0,  13,  27,  91,  83,   0,  27,  91,  37, 112,  49,  37, 100,  80,   0,  27,  91,  37, 112,  49,  37, 100,  77,   0,  27,  91,  37, 112,  49,  37, 100,  66,   0,  27,  91,  37, 112,  49,  37, 100,  64,   0,  27,  91,  37, 112,  49,  37, 100,  83,   0,  27,  91,  37, 112,  49,  37, 100,  76,   0,  27,  91,  37, 112,  49,  37, 100,  68,   0,  27,  91,  37, 112,  49,  37, 100,  67,   0,  27,  91,  37, 112,  49,  37, 100,  84,   0,  27,  91,  37, 112,  49,  37, 100,  65,   0,  27,  91,  52, 105,   0,  27,  91,  53, 105,   0,  37, 112,  49,  37,  99,  27,  91,  37, 112,  50,  37, 123,  49, 125,  37,  45,  37, 100,  98,   0,  27,  91,  37, 105,  37, 112,  49,  37, 100, 100,   0,  10,   0,  27,  91,  48,  59,  49,  48,  37,  63,  37, 112,  49,  37, 116,  59,  55,  37,  59,  37,  63,  37, 112,  50,  37, 116,  59,  52,  37,  59,  37,  63,  37, 112,  51,  37, 116,  59,  55,  37,  59,  37,  63,  37, 112,  52,  37, 116,  59,  53,  37,  59,  37,  63,  37, 112,  54,  37, 116,  59,  49,  37,  59,  37,  63,  37, 112,  55,  37, 116,  59,  56,  37,  59,  37,  63,  37, 112,  57,  37, 116,  59,  49,  49,  37,  59, 109,   0,  27,  72,   0,  27,  91,  73,   0,  43,  16,  44,  17,  45,  24,  46,  25,  48, -37,  96,   4,  97, -79, 102,  -8, 103, -15, 104, -80, 106, -39, 107, -65, 108, -38, 109, -64, 110, -59, 111, 126, 112, -60, 113, -60, 114, -60, 115,  95, 116, -61, 117, -76, 118, -63, 119, -62, 120, -77, 121, -13, 122, -14, 123, -29, 124, -40, 125,-100, 126,  -2,   0,  27,  91,  90,   0,  27,  91,  49,  75,   0,  27,  91,  37, 105,  37, 100,  59,  37, 100,  82,   0,  27,  91,  54, 110,   0,  27,  91,  63,  37,  91,  59,  48,  49,  50,  51,  52,  53,  54,  55,  56,  57,  93,  99,   0,  27,  91,  99,   0,  27,  91,  51,  57,  59,  52,  57, 109,   0,  27,  91,  51,  37, 112,  49,  37, 100, 109,   0,  27,  91,  52,  37, 112,  49,  37, 100, 109,   0,  27,  40,  66,   0,  27,  41,  66,   0,  27,  42,  66,   0,  27,  43,  66,   0,  27,  91,  49,  49, 109,   0,  27,  91,  49,  48, 109,   0  }; -// Per the commentary in terminfo, only a minus sign is a true suffix -// separator.  bool terminfo_is_term_family(const char *term, const char *family)  {    if (!term) { @@ -88,15 +87,14 @@ bool terminfo_is_term_family(const char *term, const char *family)    size_t flen = strlen(family);    return tlen >= flen      && 0 == memcmp(term, family, flen) \ +    // Per the commentary in terminfo, minus sign is the suffix separator.      && ('\0' == term[flen] || '-' == term[flen]);  } -/// Load one of the built-in terminfo entries when unibilium has failed to -/// load a terminfo record from an external database, as it does on termcap- -/// -only systems.  We do not do any fancy recognition of xterm pretenders -/// here.  An external terminfo database would not do that, and we want to -/// behave as much like an external terminfo database as possible. -unibi_term *load_builtin_terminfo(const char * term) +/// Loads a built-in terminfo db when we (unibilium) failed to load a terminfo +/// record from the environment (termcap systems, unrecognized $TERM, …). +/// We do not attempt to detect xterm pretenders here. +static unibi_term *terminfo_builtin(const char *term)  {    if (terminfo_is_term_family(term, "xterm")) {      return unibi_from_mem((const char *)xterm_256colour_terminfo, @@ -137,3 +135,12 @@ unibi_term *load_builtin_terminfo(const char * term)                            sizeof ansi_terminfo);    }  } + +unibi_term *terminfo_from_builtin(const char *term) +{ +  unibi_term *ut = terminfo_builtin(term); +  // Disable BCE by default (for built-in terminfos). #7624 +  // https://github.com/kovidgoyal/kitty/issues/160#issuecomment-346470545 +  unibi_set_bool(ut, unibi_back_color_erase, false); +  return ut; +} diff --git a/src/nvim/tui/tui.c b/src/nvim/tui/tui.c index 7ff426239a..c2e597c36c 100644 --- a/src/nvim/tui/tui.c +++ b/src/nvim/tui/tui.c @@ -194,7 +194,7 @@ static void terminfo_start(UI *ui)    const char *term = os_getenv("TERM");    data->ut = unibi_from_env();    if (!data->ut) { -    data->ut = load_builtin_terminfo(term); +    data->ut = terminfo_from_builtin(term);    }    // None of the following work over SSH; see :help TERM .    const char *colorterm = os_getenv("COLORTERM"); @@ -940,9 +940,10 @@ static void tui_scroll(UI *ui, Integer count)      }      cursor_goto(ui, saved_row, saved_col); -    if (!scroll_clears_to_current_colour) { -      // This is required because scrolling will leave wrong background in the -      // cleared area on non-bge terminals. +    if (!scroll_clears_to_current_colour && grid->bg != -1) { +      // Scrolling may leave wrong background in the cleared area on non-bge +      // terminals. Update the cleared area of the terminal if its builtin +      // scrolling facility was used and bg color is not the default.        clear_region(ui, clear_top, clear_bot, grid->left, grid->right);      }    } else { @@ -1234,11 +1235,9 @@ static int unibi_find_ext_str(unibi_term *ut, const char *name)    return -1;  } -/// Several entries in terminfo are known to be deficient or outright wrong, -/// unfortunately; and several terminal emulators falsely announce incorrect -/// terminal types.  So patch the terminfo records after loading from an -/// external or a built-in database.  In an ideal world, the real terminfo data -/// would be correct and complete, and this function would be almost empty. +/// Patches the terminfo records after loading from system or built-in db. +/// Several entries in terminfo are known to be deficient or outright wrong; +/// and several terminal emulators falsely announce incorrect terminal types.  static void patch_terminfo_bugs(TUIData *data, const char *term,                                  const char *colorterm, long vte_version,                                  bool konsole, bool iterm_env) @@ -1304,6 +1303,11 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,      }    } +  if (!true_xterm) { +    // Cannot trust terminfo; safer to disable BCE. #7624 +    unibi_set_bool(ut, unibi_back_color_erase, false); +  } +    if (xterm) {      // Termit, LXTerminal, GTKTerm2, GNOME Terminal, MATE Terminal, roxterm,      // and EvilVTE falsely claim to be xterm and do not support important xterm @@ -1397,11 +1401,9 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,  #define XTERM_SETAB_16 \    "\x1b[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e39%;m" -  // Terminals where there is actually 256-colour SGR support despite what -  // the terminfo record may say. +  // Terminals with 256-colour SGR support despite what terminfo says.    if (unibi_get_num(ut, unibi_max_colors) < 256) { -    // See http://fedoraproject.org/wiki/Features/256_Color_Terminals for -    // more on this. +    // See http://fedoraproject.org/wiki/Features/256_Color_Terminals      if (true_xterm || iterm || iterm_pretending_xterm) {        unibi_set_num(ut, unibi_max_colors, 256);        unibi_set_str(ut, unibi_set_a_foreground, XTERM_SETAF_256_COLON); @@ -1417,8 +1419,7 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,        unibi_set_str(ut, unibi_set_a_background, XTERM_SETAB_256);      }    } -  // Terminals where there is actually 16-colour SGR support despite what -  // the terminfo record may say. +  // Terminals with 16-colour SGR support despite what terminfo says.    if (unibi_get_num(ut, unibi_max_colors) < 16) {      if (colorterm) {        unibi_set_num(ut, unibi_max_colors, 16); @@ -1427,9 +1428,8 @@ static void patch_terminfo_bugs(TUIData *data, const char *term,      }    } -  // Some terminals can not currently be trusted to report if they support -  // DECSCUSR or not. So we need to have a blacklist for when we should not -  // trust the reported features. +  // Some terminals cannot be trusted to report DECSCUSR support. So we keep +  // blacklist for when we should not trust the reported features.    if (!((vte_version != 0 && vte_version < 3900) || konsole)) {      // Dickey ncurses terminfo has included the Ss and Se capabilities,      // pioneered by tmux, since 2011-07-14. So adding them to terminal types, diff --git a/test/functional/ex_cmds/highlight_spec.lua b/test/functional/ex_cmds/highlight_spec.lua new file mode 100644 index 0000000000..25968b8204 --- /dev/null +++ b/test/functional/ex_cmds/highlight_spec.lua @@ -0,0 +1,43 @@ +local Screen = require('test.functional.ui.screen') +local helpers = require("test.functional.helpers")(after_each) +local eq, command = helpers.eq, helpers.command +local clear = helpers.clear +local eval, exc_exec = helpers.eval, helpers.exc_exec + +describe(':highlight', function() +  local screen + +  before_each(function() +    clear() +    screen = Screen.new() +    screen:attach() +  end) + +  after_each(function() +    screen:detach() +  end) + +  it('invalid color name', function() +    eq('Vim(highlight):E421: Color name or number not recognized: ctermfg=#181818', +       exc_exec("highlight normal ctermfg=#181818")) +    eq('Vim(highlight):E421: Color name or number not recognized: ctermbg=#181818', +       exc_exec("highlight normal ctermbg=#181818")) +  end) + +  it('invalid group name', function() +    eq('Vim(highlight):E411: highlight group not found: foo', +       exc_exec("highlight foo")) +  end) + +  it('"Normal" foreground with red', function() +    eq('', eval('synIDattr(hlID("Normal"), "fg", "cterm")')) +    command('highlight normal ctermfg=red') +    eq('9', eval('synIDattr(hlID("Normal"), "fg", "cterm")')) +  end) + +  it('"Normal" background with red', function() +    eq('', eval('synIDattr(hlID("Normal"), "bg", "cterm")')) +    command('highlight normal ctermbg=red') +    eq('9', eval('synIDattr(hlID("Normal"), "bg", "cterm")')) +  end) +end)  | 
