mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	Merge #4633: support "special" highlight (undercurl)
Closes #2040 Closes #3370
This commit is contained in:
		@@ -504,6 +504,7 @@ EXTERN int cterm_normal_fg_bold INIT(= 0);
 | 
				
			|||||||
EXTERN int cterm_normal_bg_color INIT(= 0);
 | 
					EXTERN int cterm_normal_bg_color INIT(= 0);
 | 
				
			||||||
EXTERN RgbValue normal_fg INIT(= -1);
 | 
					EXTERN RgbValue normal_fg INIT(= -1);
 | 
				
			||||||
EXTERN RgbValue normal_bg INIT(= -1);
 | 
					EXTERN RgbValue normal_bg INIT(= -1);
 | 
				
			||||||
 | 
					EXTERN RgbValue normal_sp INIT(= -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
EXTERN int autocmd_busy INIT(= FALSE);          /* Is apply_autocmds() busy? */
 | 
					EXTERN int autocmd_busy INIT(= FALSE);          /* Is apply_autocmds() busy? */
 | 
				
			||||||
EXTERN int autocmd_no_enter INIT(= FALSE);      /* *Enter autocmds disabled */
 | 
					EXTERN int autocmd_no_enter INIT(= FALSE);      /* *Enter autocmds disabled */
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -96,6 +96,7 @@ static Object remote_ui_attach(uint64_t channel_id, uint64_t request_id,
 | 
				
			|||||||
  ui->visual_bell = remote_ui_visual_bell;
 | 
					  ui->visual_bell = remote_ui_visual_bell;
 | 
				
			||||||
  ui->update_fg = remote_ui_update_fg;
 | 
					  ui->update_fg = remote_ui_update_fg;
 | 
				
			||||||
  ui->update_bg = remote_ui_update_bg;
 | 
					  ui->update_bg = remote_ui_update_bg;
 | 
				
			||||||
 | 
					  ui->update_sp = remote_ui_update_sp;
 | 
				
			||||||
  ui->flush = remote_ui_flush;
 | 
					  ui->flush = remote_ui_flush;
 | 
				
			||||||
  ui->suspend = remote_ui_suspend;
 | 
					  ui->suspend = remote_ui_suspend;
 | 
				
			||||||
  ui->set_title = remote_ui_set_title;
 | 
					  ui->set_title = remote_ui_set_title;
 | 
				
			||||||
@@ -285,6 +286,10 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs)
 | 
				
			|||||||
    PUT(hl, "background", INTEGER_OBJ(attrs.background));
 | 
					    PUT(hl, "background", INTEGER_OBJ(attrs.background));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (attrs.special != -1) {
 | 
				
			||||||
 | 
					    PUT(hl, "special", INTEGER_OBJ(attrs.special));
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  ADD(args, DICTIONARY_OBJ(hl));
 | 
					  ADD(args, DICTIONARY_OBJ(hl));
 | 
				
			||||||
  push_call(ui, "highlight_set", args);
 | 
					  push_call(ui, "highlight_set", args);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -323,6 +328,13 @@ static void remote_ui_update_bg(UI *ui, int bg)
 | 
				
			|||||||
  push_call(ui, "update_bg", args);
 | 
					  push_call(ui, "update_bg", args);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void remote_ui_update_sp(UI *ui, int sp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  Array args = ARRAY_DICT_INIT;
 | 
				
			||||||
 | 
					  ADD(args, INTEGER_OBJ(sp));
 | 
				
			||||||
 | 
					  push_call(ui, "update_sp", args);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void remote_ui_flush(UI *ui)
 | 
					static void remote_ui_flush(UI *ui)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  UIData *data = ui->data;
 | 
					  UIData *data = ui->data;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -62,8 +62,10 @@ struct hl_group {
 | 
				
			|||||||
  int sg_gui;                   // "gui=" highlighting attributes
 | 
					  int sg_gui;                   // "gui=" highlighting attributes
 | 
				
			||||||
  RgbValue sg_rgb_fg;           // RGB foreground color
 | 
					  RgbValue sg_rgb_fg;           // RGB foreground color
 | 
				
			||||||
  RgbValue sg_rgb_bg;           // RGB background color
 | 
					  RgbValue sg_rgb_bg;           // RGB background color
 | 
				
			||||||
 | 
					  RgbValue sg_rgb_sp;           // RGB special color
 | 
				
			||||||
  uint8_t *sg_rgb_fg_name;      // RGB foreground color name
 | 
					  uint8_t *sg_rgb_fg_name;      // RGB foreground color name
 | 
				
			||||||
  uint8_t *sg_rgb_bg_name;      // RGB background color name
 | 
					  uint8_t *sg_rgb_bg_name;      // RGB background color name
 | 
				
			||||||
 | 
					  uint8_t *sg_rgb_sp_name;      // RGB special color name
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define SG_CTERM        2       // cterm has been set
 | 
					#define SG_CTERM        2       // cterm has been set
 | 
				
			||||||
@@ -6169,12 +6171,11 @@ do_highlight (
 | 
				
			|||||||
        break;
 | 
					        break;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      /*
 | 
					      // Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg",
 | 
				
			||||||
       * Isolate the key ("term", "ctermfg", "ctermbg", "font", "guifg" or
 | 
					      // "guibg" or "guisp").
 | 
				
			||||||
       * "guibg").
 | 
					      while (*linep && !ascii_iswhite(*linep) && *linep != '=') {
 | 
				
			||||||
       */
 | 
					        linep++;
 | 
				
			||||||
      while (*linep && !ascii_iswhite(*linep) && *linep != '=')
 | 
					      }
 | 
				
			||||||
        ++linep;
 | 
					 | 
				
			||||||
      xfree(key);
 | 
					      xfree(key);
 | 
				
			||||||
      key = vim_strnsave_up(key_start, (int)(linep - key_start));
 | 
					      key = vim_strnsave_up(key_start, (int)(linep - key_start));
 | 
				
			||||||
      linep = skipwhite(linep);
 | 
					      linep = skipwhite(linep);
 | 
				
			||||||
@@ -6452,7 +6453,23 @@ do_highlight (
 | 
				
			|||||||
          normal_bg = HL_TABLE()[idx].sg_rgb_bg;
 | 
					          normal_bg = HL_TABLE()[idx].sg_rgb_bg;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else if (STRCMP(key, "GUISP") == 0)   {
 | 
					      } else if (STRCMP(key, "GUISP") == 0)   {
 | 
				
			||||||
        // Ignored for now
 | 
					        if (!init || !(HL_TABLE()[idx].sg_set & SG_GUI)) {
 | 
				
			||||||
 | 
					          if (!init)
 | 
				
			||||||
 | 
					            HL_TABLE()[idx].sg_set |= SG_GUI;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          xfree(HL_TABLE()[idx].sg_rgb_sp_name);
 | 
				
			||||||
 | 
					          if (STRCMP(arg, "NONE") != 0) {
 | 
				
			||||||
 | 
					            HL_TABLE()[idx].sg_rgb_sp_name = (uint8_t *)xstrdup((char *)arg);
 | 
				
			||||||
 | 
					            HL_TABLE()[idx].sg_rgb_sp = name_to_color(arg);
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            HL_TABLE()[idx].sg_rgb_sp_name = NULL;
 | 
				
			||||||
 | 
					            HL_TABLE()[idx].sg_rgb_sp = -1;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (is_normal_group) {
 | 
				
			||||||
 | 
					          normal_sp = HL_TABLE()[idx].sg_rgb_sp;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
      } else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0)   {
 | 
					      } else if (STRCMP(key, "START") == 0 || STRCMP(key, "STOP") == 0)   {
 | 
				
			||||||
        // Ignored for now
 | 
					        // Ignored for now
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
@@ -6516,6 +6533,7 @@ void restore_cterm_colors(void)
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  normal_fg = -1;
 | 
					  normal_fg = -1;
 | 
				
			||||||
  normal_bg = -1;
 | 
					  normal_bg = -1;
 | 
				
			||||||
 | 
					  normal_sp = -1;
 | 
				
			||||||
  cterm_normal_fg_color = 0;
 | 
					  cterm_normal_fg_color = 0;
 | 
				
			||||||
  cterm_normal_fg_bold = 0;
 | 
					  cterm_normal_fg_bold = 0;
 | 
				
			||||||
  cterm_normal_bg_color = 0;
 | 
					  cterm_normal_bg_color = 0;
 | 
				
			||||||
@@ -6532,6 +6550,7 @@ static int hl_has_settings(int idx, int check_link)
 | 
				
			|||||||
         || HL_TABLE()[idx].sg_cterm_bg != 0
 | 
					         || HL_TABLE()[idx].sg_cterm_bg != 0
 | 
				
			||||||
         || HL_TABLE()[idx].sg_rgb_fg_name != NULL
 | 
					         || HL_TABLE()[idx].sg_rgb_fg_name != NULL
 | 
				
			||||||
         || HL_TABLE()[idx].sg_rgb_bg_name != NULL
 | 
					         || HL_TABLE()[idx].sg_rgb_bg_name != NULL
 | 
				
			||||||
 | 
					         || HL_TABLE()[idx].sg_rgb_sp_name != NULL
 | 
				
			||||||
         || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK));
 | 
					         || (check_link && (HL_TABLE()[idx].sg_set & SG_LINK));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -6548,14 +6567,18 @@ static void highlight_clear(int idx)
 | 
				
			|||||||
  HL_TABLE()[idx].sg_gui = 0;
 | 
					  HL_TABLE()[idx].sg_gui = 0;
 | 
				
			||||||
  HL_TABLE()[idx].sg_rgb_fg = -1;
 | 
					  HL_TABLE()[idx].sg_rgb_fg = -1;
 | 
				
			||||||
  HL_TABLE()[idx].sg_rgb_bg = -1;
 | 
					  HL_TABLE()[idx].sg_rgb_bg = -1;
 | 
				
			||||||
 | 
					  HL_TABLE()[idx].sg_rgb_sp = -1;
 | 
				
			||||||
  xfree(HL_TABLE()[idx].sg_rgb_fg_name);
 | 
					  xfree(HL_TABLE()[idx].sg_rgb_fg_name);
 | 
				
			||||||
  HL_TABLE()[idx].sg_rgb_fg_name = NULL;
 | 
					  HL_TABLE()[idx].sg_rgb_fg_name = NULL;
 | 
				
			||||||
  xfree(HL_TABLE()[idx].sg_rgb_bg_name);
 | 
					  xfree(HL_TABLE()[idx].sg_rgb_bg_name);
 | 
				
			||||||
  HL_TABLE()[idx].sg_rgb_bg_name = NULL;
 | 
					  HL_TABLE()[idx].sg_rgb_bg_name = NULL;
 | 
				
			||||||
  /* Clear the script ID only when there is no link, since that is not
 | 
					  xfree(HL_TABLE()[idx].sg_rgb_sp_name);
 | 
				
			||||||
   * cleared. */
 | 
					  HL_TABLE()[idx].sg_rgb_sp_name = NULL;
 | 
				
			||||||
  if (HL_TABLE()[idx].sg_link == 0)
 | 
					  // Clear the script ID only when there is no link, since that is not
 | 
				
			||||||
 | 
					  // cleared.
 | 
				
			||||||
 | 
					  if (HL_TABLE()[idx].sg_link == 0) {
 | 
				
			||||||
    HL_TABLE()[idx].sg_scriptID = 0;
 | 
					    HL_TABLE()[idx].sg_scriptID = 0;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -6597,7 +6620,8 @@ int get_attr_entry(attrentry_T *aep)
 | 
				
			|||||||
        && aep->cterm_bg_color == taep->cterm_bg_color
 | 
					        && aep->cterm_bg_color == taep->cterm_bg_color
 | 
				
			||||||
        && aep->rgb_ae_attr == taep->rgb_ae_attr
 | 
					        && aep->rgb_ae_attr == taep->rgb_ae_attr
 | 
				
			||||||
        && aep->rgb_fg_color == taep->rgb_fg_color
 | 
					        && aep->rgb_fg_color == taep->rgb_fg_color
 | 
				
			||||||
        && aep->rgb_bg_color == taep->rgb_bg_color) {
 | 
					        && aep->rgb_bg_color == taep->rgb_bg_color
 | 
				
			||||||
 | 
					        && aep->rgb_sp_color == taep->rgb_sp_color) {
 | 
				
			||||||
      return i + ATTR_OFF;
 | 
					      return i + ATTR_OFF;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
@@ -6635,6 +6659,7 @@ int get_attr_entry(attrentry_T *aep)
 | 
				
			|||||||
  taep->rgb_ae_attr = aep->rgb_ae_attr;
 | 
					  taep->rgb_ae_attr = aep->rgb_ae_attr;
 | 
				
			||||||
  taep->rgb_fg_color = aep->rgb_fg_color;
 | 
					  taep->rgb_fg_color = aep->rgb_fg_color;
 | 
				
			||||||
  taep->rgb_bg_color = aep->rgb_bg_color;
 | 
					  taep->rgb_bg_color = aep->rgb_bg_color;
 | 
				
			||||||
 | 
					  taep->rgb_sp_color = aep->rgb_sp_color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return table->ga_len - 1 + ATTR_OFF;
 | 
					  return table->ga_len - 1 + ATTR_OFF;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -6696,6 +6721,10 @@ int hl_combine_attr(int char_attr, int prim_attr)
 | 
				
			|||||||
    if (spell_aep->rgb_bg_color >= 0) {
 | 
					    if (spell_aep->rgb_bg_color >= 0) {
 | 
				
			||||||
      new_en.rgb_bg_color = spell_aep->rgb_bg_color;
 | 
					      new_en.rgb_bg_color = spell_aep->rgb_bg_color;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (spell_aep->rgb_sp_color >= 0) {
 | 
				
			||||||
 | 
					      new_en.rgb_sp_color = spell_aep->rgb_sp_color;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return get_attr_entry(&new_en);
 | 
					  return get_attr_entry(&new_en);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -6733,7 +6762,7 @@ static void highlight_list_one(int id)
 | 
				
			|||||||
  didh = highlight_list_arg(id, didh, LIST_STRING,
 | 
					  didh = highlight_list_arg(id, didh, LIST_STRING,
 | 
				
			||||||
      0, sgp->sg_rgb_bg_name, "guibg");
 | 
					      0, sgp->sg_rgb_bg_name, "guibg");
 | 
				
			||||||
  didh = highlight_list_arg(id, didh, LIST_STRING,
 | 
					  didh = highlight_list_arg(id, didh, LIST_STRING,
 | 
				
			||||||
      0, NULL, "guisp");
 | 
					                            0, sgp->sg_rgb_sp_name, "guisp");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (sgp->sg_link && !got_int) {
 | 
					  if (sgp->sg_link && !got_int) {
 | 
				
			||||||
    (void)syn_list_header(didh, 9999, id);
 | 
					    (void)syn_list_header(didh, 9999, id);
 | 
				
			||||||
@@ -6847,8 +6876,9 @@ highlight_color (
 | 
				
			|||||||
  if (modec == 'g') {
 | 
					  if (modec == 'g') {
 | 
				
			||||||
    if (fg)
 | 
					    if (fg)
 | 
				
			||||||
      return HL_TABLE()[id - 1].sg_rgb_fg_name;
 | 
					      return HL_TABLE()[id - 1].sg_rgb_fg_name;
 | 
				
			||||||
    if (sp)
 | 
					    if (sp) {
 | 
				
			||||||
      return NULL;
 | 
					      return HL_TABLE()[id - 1].sg_rgb_sp_name;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return HL_TABLE()[id - 1].sg_rgb_bg_name;
 | 
					    return HL_TABLE()[id - 1].sg_rgb_bg_name;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  if (font || sp)
 | 
					  if (font || sp)
 | 
				
			||||||
@@ -6935,10 +6965,12 @@ set_hl_attr (
 | 
				
			|||||||
  // before setting attr_entry->{f,g}g_color to a other than -1
 | 
					  // before setting attr_entry->{f,g}g_color to a other than -1
 | 
				
			||||||
  at_en.rgb_fg_color = sgp->sg_rgb_fg_name ? sgp->sg_rgb_fg : -1;
 | 
					  at_en.rgb_fg_color = sgp->sg_rgb_fg_name ? sgp->sg_rgb_fg : -1;
 | 
				
			||||||
  at_en.rgb_bg_color = sgp->sg_rgb_bg_name ? sgp->sg_rgb_bg : -1;
 | 
					  at_en.rgb_bg_color = sgp->sg_rgb_bg_name ? sgp->sg_rgb_bg : -1;
 | 
				
			||||||
 | 
					  at_en.rgb_sp_color = sgp->sg_rgb_sp_name ? sgp->sg_rgb_sp : -1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (at_en.cterm_fg_color != 0 || at_en.cterm_bg_color != 0
 | 
					  if (at_en.cterm_fg_color != 0 || at_en.cterm_bg_color != 0
 | 
				
			||||||
      || at_en.rgb_fg_color != -1 || at_en.rgb_bg_color != -1
 | 
					      || at_en.rgb_fg_color != -1 || at_en.rgb_bg_color != -1
 | 
				
			||||||
      || at_en.cterm_ae_attr != 0 || at_en.rgb_ae_attr != 0) {
 | 
					      || at_en.rgb_sp_color != -1 || at_en.cterm_ae_attr != 0
 | 
				
			||||||
 | 
					      || at_en.rgb_ae_attr != 0) {
 | 
				
			||||||
    sgp->sg_attr = get_attr_entry(&at_en);
 | 
					    sgp->sg_attr = get_attr_entry(&at_en);
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -7271,6 +7303,10 @@ int highlight_changed(void)
 | 
				
			|||||||
        hlt[hlcnt + i].sg_rgb_bg = hlt[id - 1].sg_rgb_bg;
 | 
					        hlt[hlcnt + i].sg_rgb_bg = hlt[id - 1].sg_rgb_bg;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (hlt[id - 1].sg_rgb_sp != hlt[id_S - 1].sg_rgb_sp) {
 | 
				
			||||||
 | 
					        hlt[hlcnt + i].sg_rgb_sp = hlt[id - 1].sg_rgb_sp;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      highlight_ga.ga_len = hlcnt + i + 1;
 | 
					      highlight_ga.ga_len = hlcnt + i + 1;
 | 
				
			||||||
      set_hl_attr(hlcnt + i);           /* At long last we can apply */
 | 
					      set_hl_attr(hlcnt + i);           /* At long last we can apply */
 | 
				
			||||||
      highlight_stlnc[i] = syn_id2attr(hlcnt + i + 1);
 | 
					      highlight_stlnc[i] = syn_id2attr(hlcnt + i + 1);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -69,8 +69,8 @@ struct syn_state {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Structure shared between syntax.c, screen.c
 | 
					// Structure shared between syntax.c, screen.c
 | 
				
			||||||
typedef struct attr_entry {
 | 
					typedef struct attr_entry {
 | 
				
			||||||
  short rgb_ae_attr, cterm_ae_attr;  // HL_BOLD, etc.
 | 
					  int16_t rgb_ae_attr, cterm_ae_attr;  // HL_BOLD, etc.
 | 
				
			||||||
  RgbValue rgb_fg_color, rgb_bg_color;
 | 
					  RgbValue rgb_fg_color, rgb_bg_color, rgb_sp_color;
 | 
				
			||||||
  int cterm_fg_color, cterm_bg_color;
 | 
					  int cterm_fg_color, cterm_bg_color;
 | 
				
			||||||
} attrentry_T;
 | 
					} attrentry_T;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -100,6 +100,7 @@ UI *tui_start(void)
 | 
				
			|||||||
  ui->visual_bell = tui_visual_bell;
 | 
					  ui->visual_bell = tui_visual_bell;
 | 
				
			||||||
  ui->update_fg = tui_update_fg;
 | 
					  ui->update_fg = tui_update_fg;
 | 
				
			||||||
  ui->update_bg = tui_update_bg;
 | 
					  ui->update_bg = tui_update_bg;
 | 
				
			||||||
 | 
					  ui->update_sp = tui_update_sp;
 | 
				
			||||||
  ui->flush = tui_flush;
 | 
					  ui->flush = tui_flush;
 | 
				
			||||||
  ui->suspend = tui_suspend;
 | 
					  ui->suspend = tui_suspend;
 | 
				
			||||||
  ui->set_title = tui_set_title;
 | 
					  ui->set_title = tui_set_title;
 | 
				
			||||||
@@ -573,6 +574,11 @@ static void tui_update_bg(UI *ui, int bg)
 | 
				
			|||||||
  ((TUIData *)ui->data)->grid.bg = bg;
 | 
					  ((TUIData *)ui->data)->grid.bg = bg;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void tui_update_sp(UI *ui, int sp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  // Do nothing; 'special' color is for GUI only
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void tui_flush(UI *ui)
 | 
					static void tui_flush(UI *ui)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  TUIData *data = ui->data;
 | 
					  TUIData *data = ui->data;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -21,7 +21,7 @@ struct ugrid {
 | 
				
			|||||||
  UCell **cells;
 | 
					  UCell **cells;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define EMPTY_ATTRS ((HlAttrs){false, false, false, false, false, -1, -1})
 | 
					#define EMPTY_ATTRS ((HlAttrs){ false, false, false, false, false, -1, -1, -1 })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define UGRID_FOREACH_CELL(grid, top, bot, left, right, code)           \
 | 
					#define UGRID_FOREACH_CELL(grid, top, bot, left, right, code)           \
 | 
				
			||||||
  do {                                                                  \
 | 
					  do {                                                                  \
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -155,6 +155,7 @@ void ui_resize(int new_width, int new_height)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  UI_CALL(update_fg, (ui->rgb ? normal_fg : cterm_normal_fg_color - 1));
 | 
					  UI_CALL(update_fg, (ui->rgb ? normal_fg : cterm_normal_fg_color - 1));
 | 
				
			||||||
  UI_CALL(update_bg, (ui->rgb ? normal_bg : cterm_normal_bg_color - 1));
 | 
					  UI_CALL(update_bg, (ui->rgb ? normal_bg : cterm_normal_bg_color - 1));
 | 
				
			||||||
 | 
					  UI_CALL(update_sp, (ui->rgb ? normal_sp : -1));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  sr.top = 0;
 | 
					  sr.top = 0;
 | 
				
			||||||
  sr.bot = height - 1;
 | 
					  sr.bot = height - 1;
 | 
				
			||||||
@@ -388,7 +389,7 @@ static void parse_control_character(uint8_t c)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void set_highlight_args(int attr_code)
 | 
					static void set_highlight_args(int attr_code)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1 };
 | 
					  HlAttrs rgb_attrs = { false, false, false, false, false, -1, -1, -1 };
 | 
				
			||||||
  HlAttrs cterm_attrs = rgb_attrs;
 | 
					  HlAttrs cterm_attrs = rgb_attrs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (attr_code == HL_NORMAL) {
 | 
					  if (attr_code == HL_NORMAL) {
 | 
				
			||||||
@@ -425,6 +426,10 @@ static void set_highlight_args(int attr_code)
 | 
				
			|||||||
    rgb_attrs.background = aep->rgb_bg_color;
 | 
					    rgb_attrs.background = aep->rgb_bg_color;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (aep->rgb_sp_color != normal_sp) {
 | 
				
			||||||
 | 
					    rgb_attrs.special = aep->rgb_sp_color;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (cterm_normal_fg_color != aep->cterm_fg_color) {
 | 
					  if (cterm_normal_fg_color != aep->cterm_fg_color) {
 | 
				
			||||||
    cterm_attrs.foreground = aep->cterm_fg_color - 1;
 | 
					    cterm_attrs.foreground = aep->cterm_fg_color - 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
  bool bold, underline, undercurl, italic, reverse;
 | 
					  bool bold, underline, undercurl, italic, reverse;
 | 
				
			||||||
  int foreground, background;
 | 
					  int foreground, background, special;
 | 
				
			||||||
} HlAttrs;
 | 
					} HlAttrs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct ui_t UI;
 | 
					typedef struct ui_t UI;
 | 
				
			||||||
@@ -35,6 +35,7 @@ struct ui_t {
 | 
				
			|||||||
  void (*flush)(UI *ui);
 | 
					  void (*flush)(UI *ui);
 | 
				
			||||||
  void (*update_fg)(UI *ui, int fg);
 | 
					  void (*update_fg)(UI *ui, int fg);
 | 
				
			||||||
  void (*update_bg)(UI *ui, int bg);
 | 
					  void (*update_bg)(UI *ui, int bg);
 | 
				
			||||||
 | 
					  void (*update_sp)(UI *ui, int sp);
 | 
				
			||||||
  void (*suspend)(UI *ui);
 | 
					  void (*suspend)(UI *ui);
 | 
				
			||||||
  void (*set_title)(UI *ui, char *title);
 | 
					  void (*set_title)(UI *ui, char *title);
 | 
				
			||||||
  void (*set_icon)(UI *ui, char *icon);
 | 
					  void (*set_icon)(UI *ui, char *icon);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -49,6 +49,7 @@ UI *ui_bridge_attach(UI *ui, ui_main_fn ui_main, event_scheduler scheduler)
 | 
				
			|||||||
  rv->bridge.visual_bell = ui_bridge_visual_bell;
 | 
					  rv->bridge.visual_bell = ui_bridge_visual_bell;
 | 
				
			||||||
  rv->bridge.update_fg = ui_bridge_update_fg;
 | 
					  rv->bridge.update_fg = ui_bridge_update_fg;
 | 
				
			||||||
  rv->bridge.update_bg = ui_bridge_update_bg;
 | 
					  rv->bridge.update_bg = ui_bridge_update_bg;
 | 
				
			||||||
 | 
					  rv->bridge.update_sp = ui_bridge_update_sp;
 | 
				
			||||||
  rv->bridge.flush = ui_bridge_flush;
 | 
					  rv->bridge.flush = ui_bridge_flush;
 | 
				
			||||||
  rv->bridge.suspend = ui_bridge_suspend;
 | 
					  rv->bridge.suspend = ui_bridge_suspend;
 | 
				
			||||||
  rv->bridge.set_title = ui_bridge_set_title;
 | 
					  rv->bridge.set_title = ui_bridge_set_title;
 | 
				
			||||||
@@ -305,6 +306,16 @@ static void ui_bridge_update_bg_event(void **argv)
 | 
				
			|||||||
  ui->update_bg(ui, PTR2INT(argv[1]));
 | 
					  ui->update_bg(ui, PTR2INT(argv[1]));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void ui_bridge_update_sp(UI *b, int sp)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  UI_CALL(b, update_sp, 2, b, INT2PTR(sp));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					static void ui_bridge_update_sp_event(void **argv)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  UI *ui = UI(argv[0]);
 | 
				
			||||||
 | 
					  ui->update_sp(ui, PTR2INT(argv[1]));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ui_bridge_flush(UI *b)
 | 
					static void ui_bridge_flush(UI *b)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  UI_CALL(b, flush, 1, b);
 | 
					  UI_CALL(b, flush, 1, b);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,7 +25,7 @@ describe('terminal window highlighting', function()
 | 
				
			|||||||
      [5] = {background = 11},
 | 
					      [5] = {background = 11},
 | 
				
			||||||
      [6] = {foreground = 130},
 | 
					      [6] = {foreground = 130},
 | 
				
			||||||
      [7] = {reverse = true},
 | 
					      [7] = {reverse = true},
 | 
				
			||||||
      [8] = {background = 11}
 | 
					      [8] = {background = 11},
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    screen:attach(false)
 | 
					    screen:attach(false)
 | 
				
			||||||
    execute('enew | call termopen(["'..nvim_dir..'/tty-test"]) | startinsert')
 | 
					    execute('enew | call termopen(["'..nvim_dir..'/tty-test"]) | startinsert')
 | 
				
			||||||
@@ -121,7 +121,7 @@ describe('terminal window highlighting with custom palette', function()
 | 
				
			|||||||
    clear()
 | 
					    clear()
 | 
				
			||||||
    screen = Screen.new(50, 7)
 | 
					    screen = Screen.new(50, 7)
 | 
				
			||||||
    screen:set_default_attr_ids({
 | 
					    screen:set_default_attr_ids({
 | 
				
			||||||
      [1] = {foreground = 1193046}
 | 
					      [1] = {foreground = 1193046, special = Screen.colors.Black}
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    screen:set_default_attr_ignore({
 | 
					    screen:set_default_attr_ignore({
 | 
				
			||||||
      [1] = {bold = true},
 | 
					      [1] = {bold = true},
 | 
				
			||||||
@@ -130,7 +130,7 @@ describe('terminal window highlighting with custom palette', function()
 | 
				
			|||||||
      [5] = {background = 11},
 | 
					      [5] = {background = 11},
 | 
				
			||||||
      [6] = {foreground = 130},
 | 
					      [6] = {foreground = 130},
 | 
				
			||||||
      [7] = {reverse = true},
 | 
					      [7] = {reverse = true},
 | 
				
			||||||
      [8] = {background = 11}
 | 
					      [8] = {background = 11},
 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    screen:attach(true)
 | 
					    screen:attach(true)
 | 
				
			||||||
    nvim('set_var', 'terminal_color_3', '#123456')
 | 
					    nvim('set_var', 'terminal_color_3', '#123456')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,7 @@
 | 
				
			|||||||
local helpers = require('test.functional.helpers')
 | 
					local helpers = require('test.functional.helpers')
 | 
				
			||||||
local Screen = require('test.functional.ui.screen')
 | 
					local Screen = require('test.functional.ui.screen')
 | 
				
			||||||
local os = require('os')
 | 
					local os = require('os')
 | 
				
			||||||
local clear, feed = helpers.clear, helpers.feed
 | 
					local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
 | 
				
			||||||
local execute, request, eq = helpers.execute, helpers.request, helpers.eq
 | 
					local execute, request, eq = helpers.execute, helpers.request, helpers.eq
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -303,3 +303,61 @@ describe('Default highlight groups', function()
 | 
				
			|||||||
    ]], {[1] = {foreground = Screen.colors.Red, background = Screen.colors.Green}})
 | 
					    ]], {[1] = {foreground = Screen.colors.Red, background = Screen.colors.Green}})
 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
end)
 | 
					end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('guisp (special/undercurl)', function()
 | 
				
			||||||
 | 
					  local screen
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  before_each(function()
 | 
				
			||||||
 | 
					    clear()
 | 
				
			||||||
 | 
					    screen = Screen.new(25,10)
 | 
				
			||||||
 | 
					    screen:attach()
 | 
				
			||||||
 | 
					    screen:set_default_attr_ignore({
 | 
				
			||||||
 | 
					      [1] = {bold = true, foreground = Screen.colors.Blue},
 | 
				
			||||||
 | 
					      [2] = {bold = true}
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  it('can be set and is applied like foreground or background', function()
 | 
				
			||||||
 | 
					    execute('syntax on')
 | 
				
			||||||
 | 
					    execute('syn keyword TmpKeyword neovim')
 | 
				
			||||||
 | 
					    execute('syn keyword TmpKeyword1 special')
 | 
				
			||||||
 | 
					    execute('syn keyword TmpKeyword2 specialwithbg')
 | 
				
			||||||
 | 
					    execute('syn keyword TmpKeyword3 specialwithfg')
 | 
				
			||||||
 | 
					    execute('hi! Awesome guifg=red guibg=yellow guisp=red')
 | 
				
			||||||
 | 
					    execute('hi! Awesome1 guisp=red')
 | 
				
			||||||
 | 
					    execute('hi! Awesome2 guibg=yellow guisp=red')
 | 
				
			||||||
 | 
					    execute('hi! Awesome3 guifg=red guisp=red')
 | 
				
			||||||
 | 
					    execute('hi link TmpKeyword Awesome')
 | 
				
			||||||
 | 
					    execute('hi link TmpKeyword1 Awesome1')
 | 
				
			||||||
 | 
					    execute('hi link TmpKeyword2 Awesome2')
 | 
				
			||||||
 | 
					    execute('hi link TmpKeyword3 Awesome3')
 | 
				
			||||||
 | 
					    insert([[
 | 
				
			||||||
 | 
					      neovim
 | 
				
			||||||
 | 
					      awesome neovim
 | 
				
			||||||
 | 
					      wordcontainingneovim
 | 
				
			||||||
 | 
					      special
 | 
				
			||||||
 | 
					      specialwithbg
 | 
				
			||||||
 | 
					      specialwithfg
 | 
				
			||||||
 | 
					      ]])
 | 
				
			||||||
 | 
					    feed('Go<tab>neovim tabbed')
 | 
				
			||||||
 | 
					    screen:expect([[
 | 
				
			||||||
 | 
					      {1:neovim}                   |
 | 
				
			||||||
 | 
					      awesome {1:neovim}           |
 | 
				
			||||||
 | 
					      wordcontainingneovim     |
 | 
				
			||||||
 | 
					      {2:special}                  |
 | 
				
			||||||
 | 
					      {3:specialwithbg}            |
 | 
				
			||||||
 | 
					      {4:specialwithfg}            |
 | 
				
			||||||
 | 
					                               |
 | 
				
			||||||
 | 
					              {1:neovim} tabbed^    |
 | 
				
			||||||
 | 
					      ~                        |
 | 
				
			||||||
 | 
					      -- INSERT --             |
 | 
				
			||||||
 | 
					    ]],{
 | 
				
			||||||
 | 
					      [1] = {background = Screen.colors.Yellow, foreground = Screen.colors.Red,
 | 
				
			||||||
 | 
					             special = Screen.colors.Red},
 | 
				
			||||||
 | 
					      [2] = {special = Screen.colors.Red},
 | 
				
			||||||
 | 
					      [3] = {special = Screen.colors.Red, background = Screen.colors.Yellow},
 | 
				
			||||||
 | 
					      [4] = {foreground = Screen.colors.Red, special = Screen.colors.Red},
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  end)
 | 
				
			||||||
 | 
					end)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -425,6 +425,10 @@ function Screen:_handle_update_bg(bg)
 | 
				
			|||||||
  self._bg = bg
 | 
					  self._bg = bg
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function Screen:_handle_update_sp(sp)
 | 
				
			||||||
 | 
					  self._sp = sp
 | 
				
			||||||
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Screen:_handle_suspend()
 | 
					function Screen:_handle_suspend()
 | 
				
			||||||
  self.suspended = true
 | 
					  self.suspended = true
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
@@ -573,7 +577,7 @@ function Screen:_pprint_attrs(attrs)
 | 
				
			|||||||
    local items = {}
 | 
					    local items = {}
 | 
				
			||||||
    for f, v in pairs(attrs) do
 | 
					    for f, v in pairs(attrs) do
 | 
				
			||||||
      local desc = tostring(v)
 | 
					      local desc = tostring(v)
 | 
				
			||||||
      if f == "foreground" or f == "background" then
 | 
					      if f == "foreground" or f == "background" or f == "special" then
 | 
				
			||||||
        if Screen.colornames[v] ~= nil then
 | 
					        if Screen.colornames[v] ~= nil then
 | 
				
			||||||
          desc = "Screen.colors."..Screen.colornames[v]
 | 
					          desc = "Screen.colors."..Screen.colornames[v]
 | 
				
			||||||
        end
 | 
					        end
 | 
				
			||||||
@@ -614,7 +618,8 @@ function Screen:_equal_attrs(a, b)
 | 
				
			|||||||
       a.underline == b.underline and a.undercurl == b.undercurl and
 | 
					       a.underline == b.underline and a.undercurl == b.undercurl and
 | 
				
			||||||
       a.italic == b.italic and a.reverse == b.reverse and
 | 
					       a.italic == b.italic and a.reverse == b.reverse and
 | 
				
			||||||
       a.foreground == b.foreground and
 | 
					       a.foreground == b.foreground and
 | 
				
			||||||
       a.background == b.background
 | 
					       a.background == b.background and
 | 
				
			||||||
 | 
					       a.special == b.special
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
function Screen:_attr_index(attrs, attr)
 | 
					function Screen:_attr_index(attrs, attr)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user