mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 09:44:31 +00:00 
			
		
		
		
	fix(extmarks): inline virt_text support multiple hl groups (#25303)
This commit is contained in:
		@@ -324,6 +324,24 @@ static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Get the next chunk of a virtual text item.
 | 
			
		||||
///
 | 
			
		||||
/// @param[in]     vt    The virtual text item
 | 
			
		||||
/// @param[in,out] pos   Position in the virtual text item
 | 
			
		||||
/// @param[in,out] attr  Highlight attribute
 | 
			
		||||
///
 | 
			
		||||
/// @return  The text of the chunk, or NULL if there are no more chunks
 | 
			
		||||
static char *next_virt_text_chunk(VirtText vt, size_t *pos, int *attr)
 | 
			
		||||
{
 | 
			
		||||
  char *text = NULL;
 | 
			
		||||
  for (; text == NULL && *pos < kv_size(vt); (*pos)++) {
 | 
			
		||||
    text = kv_A(vt, *pos).text;
 | 
			
		||||
    int hl_id = kv_A(vt, *pos).hl_id;
 | 
			
		||||
    *attr = hl_combine_attr(*attr, hl_id > 0 ? syn_id2attr(hl_id) : 0);
 | 
			
		||||
  }
 | 
			
		||||
  return text;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, int max_col,
 | 
			
		||||
                               int vcol, bool rl)
 | 
			
		||||
{
 | 
			
		||||
@@ -332,23 +350,17 @@ static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode,
 | 
			
		||||
  size_t virt_pos = 0;
 | 
			
		||||
 | 
			
		||||
  while (rl ? col > max_col : col < max_col) {
 | 
			
		||||
    if (!*s.p) {
 | 
			
		||||
    if (*s.p == NUL) {
 | 
			
		||||
      if (virt_pos >= kv_size(vt)) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
      virt_attr = 0;
 | 
			
		||||
      do {
 | 
			
		||||
        s.p = kv_A(vt, virt_pos).text;
 | 
			
		||||
        int hl_id = kv_A(vt, virt_pos).hl_id;
 | 
			
		||||
        virt_attr = hl_combine_attr(virt_attr,
 | 
			
		||||
                                    hl_id > 0 ? syn_id2attr(hl_id) : 0);
 | 
			
		||||
        virt_pos++;
 | 
			
		||||
      } while (!s.p && virt_pos < kv_size(vt));
 | 
			
		||||
      if (!s.p) {
 | 
			
		||||
      s.p = next_virt_text_chunk(vt, &virt_pos, &virt_attr);
 | 
			
		||||
      if (s.p == NULL) {
 | 
			
		||||
        break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (!*s.p) {
 | 
			
		||||
    if (*s.p == NUL) {
 | 
			
		||||
      continue;
 | 
			
		||||
    }
 | 
			
		||||
    int attr;
 | 
			
		||||
@@ -950,17 +962,20 @@ static void handle_inline_virtual_text(win_T *wp, winlinevars_T *wlv, ptrdiff_t
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      // already inside existing inline virtual text with multiple chunks
 | 
			
		||||
      VirtTextChunk vtc = kv_A(wlv->virt_inline, wlv->virt_inline_i);
 | 
			
		||||
      wlv->virt_inline_i++;
 | 
			
		||||
      wlv->p_extra = vtc.text;
 | 
			
		||||
      wlv->n_extra = (int)strlen(vtc.text);
 | 
			
		||||
      int attr = 0;
 | 
			
		||||
      char *text = next_virt_text_chunk(wlv->virt_inline, &wlv->virt_inline_i, &attr);
 | 
			
		||||
      if (text == NULL) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      wlv->p_extra = text;
 | 
			
		||||
      wlv->n_extra = (int)strlen(text);
 | 
			
		||||
      if (wlv->n_extra == 0) {
 | 
			
		||||
        continue;
 | 
			
		||||
      }
 | 
			
		||||
      wlv->c_extra = NUL;
 | 
			
		||||
      wlv->c_final = NUL;
 | 
			
		||||
      wlv->extra_attr = vtc.hl_id ? syn_id2attr(vtc.hl_id) : 0;
 | 
			
		||||
      wlv->n_attr = mb_charlen(vtc.text);
 | 
			
		||||
      wlv->extra_attr = attr;
 | 
			
		||||
      wlv->n_attr = mb_charlen(text);
 | 
			
		||||
      // If the text didn't reach until the first window
 | 
			
		||||
      // column we need to skip cells.
 | 
			
		||||
      if (wlv->skip_cells > 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1464,6 +1464,8 @@ describe('extmark decorations', function()
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
  it('can have virtual text which combines foreground and background groups', function()
 | 
			
		||||
    screen:try_resize(20, 3)
 | 
			
		||||
 | 
			
		||||
    screen:set_default_attr_ids {
 | 
			
		||||
      [1] = {bold=true, foreground=Screen.colors.Blue};
 | 
			
		||||
      [2] = {background = tonumber('0x123456'), foreground = tonumber('0xbbbbbb')};
 | 
			
		||||
@@ -1481,30 +1483,21 @@ describe('extmark decorations', function()
 | 
			
		||||
      hi VeryBold gui=bold
 | 
			
		||||
    ]]
 | 
			
		||||
 | 
			
		||||
    meths.buf_set_extmark(0, ns, 0, 0, { virt_text={
 | 
			
		||||
    insert('##')
 | 
			
		||||
    local vt = {
 | 
			
		||||
      {'a', {'BgOne', 'FgEin'}};
 | 
			
		||||
      {'b', {'BgOne', 'FgZwei'}};
 | 
			
		||||
      {'c', {'BgTwo', 'FgEin'}};
 | 
			
		||||
      {'d', {'BgTwo', 'FgZwei'}};
 | 
			
		||||
      {'X', {'BgTwo', 'FgZwei', 'VeryBold'}};
 | 
			
		||||
    }})
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
    meths.buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'eol' })
 | 
			
		||||
    meths.buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'right_align' })
 | 
			
		||||
    meths.buf_set_extmark(0, ns, 0, 0, { virt_text = vt, virt_text_pos = 'inline' })
 | 
			
		||||
    screen:expect{grid=[[
 | 
			
		||||
      ^ {2:a}{3:b}{4:c}{5:d}{6:X}                                            |
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
      {1:~                                                 }|
 | 
			
		||||
                                                        |
 | 
			
		||||
      {2:a}{3:b}{4:c}{5:d}{6:X}#^# {2:a}{3:b}{4:c}{5:d}{6:X}  {2:a}{3:b}{4:c}{5:d}{6:X}|
 | 
			
		||||
      {1:~                   }|
 | 
			
		||||
                          |
 | 
			
		||||
    ]]}
 | 
			
		||||
  end)
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user