]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0372: pum: rendering issues with multibyte text and opacity v9.2.0372
authorYasuhiro Matsumoto <mattn.jp@gmail.com>
Mon, 20 Apr 2026 15:35:39 +0000 (15:35 +0000)
committerChristian Brabandt <cb@256bit.org>
Mon, 20 Apr 2026 15:35:39 +0000 (15:35 +0000)
Problem:  pum: rendering issues with multibyte text and opacity
Solution: Fix trailing-cell handling near popup text boundary,
          use popup attrs on opaque popup text,
          preserve right border when bg wide char spills,
          blend popup text bg with underlying bg,
          fix wide background char corruption
          (Yasuhiro Matsumoto)

closes: #20017

Signed-off-by: Yasuhiro Matsumoto <mattn.jp@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/highlight.c
src/screen.c
src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump [new file with mode: 0644]
src/testdir/dumps/Test_pumopt_opacity_wide_bg.dump [new file with mode: 0644]
src/testdir/dumps/Test_pumopt_opacity_wide_bg_shifted.dump [new file with mode: 0644]
src/testdir/test_popup.vim
src/version.c

index eb7707c81f0fe9eae3a4dcd9d2fd6add9e72849f..67b551c67e96a8409127eeecf873aaaef6257e46 100644 (file)
@@ -3250,9 +3250,13 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
                                base_fg, popup_aep->ae_u.gui.bg_color, blend);
                    }
                }
-               else if (popup_aep->ae_u.gui.fg_color != INVALCOLOR)
+               else
                {
-                   // blend_fg=FALSE: use popup foreground
+                   // blend_fg=FALSE: popup text is opaque.  Replace the
+                   // underlying cell's attribute flags and fg with the
+                   // popup's, so the underlying syntax highlighting does
+                   // not bleed through.
+                   new_en.ae_attr = popup_aep->ae_attr;
                    new_en.ae_u.gui.fg_color = popup_aep->ae_u.gui.fg_color;
                }
                // Blend background color: blend popup bg toward underlying bg
@@ -3294,8 +3298,17 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
            popup_aep = syn_cterm_attr2entry(popup_attr);
            if (popup_aep != NULL)
            {
-               // Blend foreground color
-               if (popup_aep->ae_u.cterm.fg_color > 0)
+               if (!blend_fg)
+               {
+                   // blend_fg=FALSE: popup text is opaque.  Replace the
+                   // underlying cell's attribute flags and fg with the
+                   // popup's, so the underlying syntax highlighting does
+                   // not bleed through.
+                   new_en.ae_attr = popup_aep->ae_attr;
+                   new_en.ae_u.cterm.fg_color = popup_aep->ae_u.cterm.fg_color;
+               }
+               else if (popup_aep->ae_u.cterm.fg_color > 0)
+                   // Blend foreground color
                    new_en.ae_u.cterm.fg_color = popup_aep->ae_u.cterm.fg_color;
                // Use popup background color (cterm colors don't support blending)
                if (popup_aep->ae_u.cterm.bg_color > 0)
@@ -3330,8 +3343,11 @@ hl_blend_attr(int char_attr, int popup_attr, int blend, int blend_fg UNUSED)
                                    base_fg, popup_bg, blend);
                        }
                    }
-                   else if (popup_fg != INVALCOLOR)
-                       // blend_fg=FALSE: use popup foreground
+                   else
+                       // blend_fg=FALSE: popup text is opaque.  Replace fg
+                       // with popup's (even INVALCOLOR) so the underlying
+                       // syntax highlighting fg does not bleed.  ae_attr
+                       // was already set above for this branch.
                        new_en.ae_u.cterm.fg_rgb = popup_fg;
                    if (popup_bg != INVALCOLOR)
                    {
index b9bde1d574f5dc9a8df8dd48c78e0ce81d9a91b0..dd9aa8d29adba4576804a5c3d1a503a3d44f3226 100644 (file)
@@ -1814,6 +1814,21 @@ screen_puts_len(
        force_redraw_this = force_redraw_next;
        force_redraw_next = FALSE;
 
+       // When drawing pum text with opacity, blend the popup bg with the
+       // saved underlying bg so text cells match the padding cells that
+       // use hl_pum_blend_attr.  Without this, popup text appears on a
+       // solid bg while padding shows a blended bg, creating a visible
+       // seam.
+       int cell_attr = attr;
+       if (screen_pum_blend > 0 && pum_bg_attrs != NULL
+               && row >= pum_bg_top && row < pum_bg_bot
+               && col < pum_bg_cols)
+       {
+           int soff = (row - pum_bg_top) * pum_bg_cols + col;
+           cell_attr = hl_blend_attr(pum_bg_attrs[soff], attr,
+                                           screen_pum_blend, FALSE);
+       }
+
        need_redraw = ScreenLines[off] != c
                || (mbyte_cells == 2
                    && ScreenLines[off + 1] != (enc_dbcs ? ptr[1] : 0))
@@ -1825,7 +1840,7 @@ screen_puts_len(
                                (u8char_T)(c < 0x80 && u8cc[0] == 0 ? 0 : u8c)
                        || (ScreenLinesUC[off] != 0
                                          && screen_comp_differs(off, u8cc))))
-               || ScreenAttrs[off] != attr
+               || ScreenAttrs[off] != cell_attr
                || exmode_active;
 
        if ((need_redraw || force_redraw_this) && !skip_for_popup(row, col))
@@ -1886,7 +1901,7 @@ screen_puts_len(
                            && (*mb_off2cells)(off + 1, max_off) > 1)))
                ScreenLines[off + mbyte_blen] = 0;
            ScreenLines[off] = c;
-           ScreenAttrs[off] = attr;
+           ScreenAttrs[off] = cell_attr;
            ScreenCols[off] = -1;
            if (enc_utf8)
            {
@@ -1907,7 +1922,10 @@ screen_puts_len(
                if (mbyte_cells == 2)
                {
                    ScreenLines[off + 1] = 0;
-                   ScreenAttrs[off + 1] = attr;
+                   ScreenLinesUC[off + 1] = 0;
+                   for (int ci = 0; ci < Screen_mco; ++ci)
+                       ScreenLinesC[ci][off + 1] = 0;
+                   ScreenAttrs[off + 1] = cell_attr;
                    ScreenCols[off + 1] = -1;
                }
                screen_char(off, row, col);
@@ -1915,7 +1933,7 @@ screen_puts_len(
            else if (mbyte_cells == 2)
            {
                ScreenLines[off + 1] = ptr[1];
-               ScreenAttrs[off + 1] = attr;
+               ScreenAttrs[off + 1] = cell_attr;
                ScreenCols[off + 1] = -1;
                screen_char_2(off, row, col);
            }
@@ -2793,8 +2811,58 @@ skip_opacity_fill:
                        && col < pum_bg_cols)
                {
                    int soff = (row - pum_bg_top) * pum_bg_cols + col;
+
+                   // Skip the trailing cell of a wide background char: its
+                   // leading cell already emitted the full wide glyph via
+                   // screen_char(); drawing here would clobber the right half.
+                   // Only applies when the previous cell was actually processed
+                   // in this fill range -- if the fill starts here (col ==
+                   // start_col), the "wide lead" is outside our range (e.g.,
+                   // popup text wrote a narrow cell there), so we fall through
+                   // to the regular blend path which renders a blended space.
+                   if (enc_utf8 && pum_bg_linesUC != NULL
+                           && col > start_col
+                           && pum_bg_linesUC[soff] == 0
+                           && pum_bg_linesUC[soff - 1] != 0
+                           && utf_char2cells(pum_bg_linesUC[soff - 1]) == 2)
+                   {
+                       ScreenLines[off] = 0;
+                       if (ScreenLinesUC != NULL)
+                           ScreenLinesUC[off] = 0;
+                       ScreenAttrs[off] = ScreenAttrs[off - 1];
+                       goto next_col;
+                   }
+
                    int underlying_attr = pum_bg_attrs[soff];
 
+                   // If restoring the leading cell of a wide background char
+                   // would extend past the end of the fill range (e.g. into a
+                   // popup border cell on the right edge), render a blended
+                   // space instead so the border at col+1 is preserved.
+                   // Likewise, if this cell is the trailing half of a wide
+                   // background char whose leading cell is outside the fill
+                   // range (e.g., popup text wrote a narrow cell there),
+                   // restoring the trailing alone would emit a stray NUL.
+                   if (enc_utf8 && pum_bg_linesUC != NULL
+                           && ((pum_bg_linesUC[soff] != 0
+                                   && utf_char2cells(pum_bg_linesUC[soff]) == 2
+                                   && col + 1 >= end_col)
+                               || (col == start_col
+                                   && pum_bg_linesUC[soff] == 0
+                                   && col > 0
+                                   && pum_bg_linesUC[soff - 1] != 0
+                                   && utf_char2cells(pum_bg_linesUC[soff - 1])
+                                                                      == 2)))
+                   {
+                       ScreenLines[off] = ' ';
+                       if (ScreenLinesUC != NULL)
+                           ScreenLinesUC[off] = 0;
+                       ScreenAttrs[off] = hl_pum_blend_attr(underlying_attr,
+                                               attr, screen_pum_blend);
+                       screen_char(off, row, col);
+                       goto next_col;
+                   }
+
                    // Restore underlying character so text shows through.
                    ScreenLines[off] = pum_bg_lines[soff];
                    if (enc_utf8 && pum_bg_linesUC != NULL
diff --git a/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump b/src/testdir/dumps/Test_pumopt_opacity_text_attrs.dump
new file mode 100644 (file)
index 0000000..93ea3a5
--- /dev/null
@@ -0,0 +1,20 @@
+|ほ*0&#ffffff0|げ> +&@70
+|ほ*0#0000001#ffff4012|げ|ほ|げ|ほ|げ|漢*4&&| +&| +4#e000e06#ffffff0|テ*&|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ふ*0#ffffff16#0000e05|が|漢|字|ほ|げ|漢*4&&| +&| +4#e000e06#ffffff0|テ*&|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|カ*0#ffffff16#0000e05|タ|カ|ナ|候|補|漢*4&&| +&| +4#e000e06#ffffff0|テ*&|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢*4#e000e06&|字|テ|ス|ト|あ*0#0000000&|い|う|え|お|カ|タ|カ|ナ| +&@34
+|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_pumopt_opacity_wide_bg.dump b/src/testdir/dumps/Test_pumopt_opacity_wide_bg.dump
new file mode 100644 (file)
index 0000000..ed52522
--- /dev/null
@@ -0,0 +1,20 @@
+|ほ*0&#ffffff0|げ> +&@70
+|╭+0#0000001#ffd7ff255|─@15|╮|ス*0#0000000#ffffff0|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|│+0#0000001#ffd7ff255| +0&#e0e0e08|ほ*&|げ@1|ほ|げ|漢|字| +&|│+0&#ffd7ff255|ス*0#0000000#ffffff0|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|│+0#0000001#ffd7ff255| |ふ*&|が|漢|字|げ|漢|字| +&|│|ス*0#0000000#ffffff0|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|│+0#0000001#ffd7ff255| |カ*&|タ|カ|ナ|候|補|字| +&|│|ス*0#0000000#ffffff0|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|╰+0#0000001#ffd7ff255|─@15|╯|ス*0#0000000#ffffff0|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1| @10|T|o|p| 
diff --git a/src/testdir/dumps/Test_pumopt_opacity_wide_bg_shifted.dump b/src/testdir/dumps/Test_pumopt_opacity_wide_bg_shifted.dump
new file mode 100644 (file)
index 0000000..c145bf0
--- /dev/null
@@ -0,0 +1,20 @@
+|ほ*0&#ffffff0|げ> +&@70
+|╭+0#0000001#ffd7ff255|─@15|╮|ス*0#0000000#ffffff0|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|│+0#0000001#ffd7ff255| +0&#e0e0e08|ほ*&|げ| +&|げ*&|ほ|げ|漢|字|│+0&#ffd7ff255| +0#0000000#ffffff0|ス*&|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|│+0#0000001#ffd7ff255| |ふ*&|が|漢|字|げ|漢|字| +&|│|ス*0#0000000#ffffff0|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|│+0#0000001#ffd7ff255| |カ*&|タ|カ|ナ|候|補| +&|字*&|│+&| +0#0000000#ffffff0|ス*&|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|╰+0#0000001#ffd7ff255|─@15|╯|ス*0#0000000#ffffff0|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|a|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|a|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|a|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|a|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|a|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|a|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@34
+|a|ほ*&|げ|ほ|げ|ほ|げ|漢|字|テ|ス|ト|あ|い|う|え|お|カ|タ|カ|ナ| +&@33
+|-+2&&@1| |I|N|S|E|R|T| |-@1| +0&&@44|1|,|1| @10|T|o|p| 
index 0ea6ae48e33eed2ac6d4ab2ce6e46796d02c5257..3362cd14f0b5a86fdd0c827ab099a2ad89e1ce41 100644 (file)
@@ -2443,6 +2443,106 @@ func Test_pumopt_opacity_screendump()
   call StopVimInTerminal(buf)
 endfunc
 
+" Test pumopt opacity with multibyte background text and multibyte popup
+" items.  Exercises the wide-character alignment in the blend path:
+" - a wide background character whose trailing cell falls inside the pum
+"   fill range must not be re-emitted after screen_char() has already drawn
+"   the full glyph (would clobber the right half);
+" - a wide background character at the right edge of the fill range must
+"   not spill into the adjacent border cell.
+func Test_pumopt_opacity_wide_bg()
+  CheckScreendump
+  let lines =<< trim END
+    set pumopt=opacity:50,border:round
+    set completeopt=menu
+    call setline(1, '')
+    for i in range(20)
+      call append(line('$'), 'ほげほげほげ漢字テストあいうえおカタカナ')
+    endfor
+    normal gg
+    inoremap <F5> <Cmd>call complete(col('.'),
+          \ ['ほげ', 'ふが漢字', 'カタカナ候補'])<CR>
+  END
+  call writefile(lines, 'Xpumoptopacitywide', 'D')
+  let buf = RunVimInTerminal('-S Xpumoptopacitywide', {})
+  call TermWait(buf)
+  call term_sendkeys(buf, "i\<F5>")
+  call TermWait(buf, 100)
+  call VerifyScreenDump(buf, 'Test_pumopt_opacity_wide_bg', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>u")
+  call TermWait(buf)
+  call StopVimInTerminal(buf)
+endfunc
+
+" Test pumopt opacity when every other background line is shifted by one
+" narrow cell, so the background's wide-character boundaries do not align
+" with the popup's wide-character grid.  Exercises the blend path when:
+" - pum_bg has the trailing half of a wide character at col == start_col
+"   (its leading half was overwritten by the popup text's clear_next_cell
+"   narrow space), where restoring the trailing alone would emit a stray
+"   NUL; a blended space must be rendered instead.
+" - clearing of ScreenLinesUC[off + 1] when screen_puts_len writes a wide
+"   character on a cell whose trailing previously held a different wide
+"   char's leading codepoint.
+func Test_pumopt_opacity_wide_bg_shifted()
+  CheckScreendump
+  let lines =<< trim END
+    set pumopt=opacity:50,border:round
+    set completeopt=menu
+    call setline(1, '')
+    let base = 'ほげほげほげ漢字テストあいうえおカタカナ'
+    for i in range(20)
+      call append(line('$'), (i % 2 == 0 ? '' : 'a') .. base)
+    endfor
+    normal gg
+    inoremap <F5> <Cmd>call complete(col('.'),
+          \ ['ほげ', 'ふが漢字', 'カタカナ候補'])<CR>
+  END
+  call writefile(lines, 'Xpumoptopacityshifted', 'D')
+  let buf = RunVimInTerminal('-S Xpumoptopacityshifted', {})
+  call TermWait(buf)
+  call term_sendkeys(buf, "i\<F5>")
+  call TermWait(buf, 100)
+  call VerifyScreenDump(buf, 'Test_pumopt_opacity_wide_bg_shifted', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>u")
+  call TermWait(buf)
+  call StopVimInTerminal(buf)
+endfunc
+
+" Test that opaque popup text uses the popup's own attributes (fg and flags
+" like italic) rather than inheriting them from the syntax-highlighted
+" multibyte background cell underneath.  Without this guard, popup text
+" picks up the fg/italic of whatever buffer text happened to sit under
+" each cell.
+func Test_pumopt_opacity_text_attrs()
+  CheckScreendump
+  let lines =<< trim END
+    set pumopt=opacity:50
+    set completeopt=menu
+    hi clear
+    hi Pmenu    guifg=#ffffff guibg=#004488 ctermfg=white ctermbg=darkblue
+    hi PmenuSel guifg=#000000 guibg=#ffcc00 ctermfg=black ctermbg=yellow
+    hi Special  guifg=#ff66cc cterm=italic gui=italic
+    call setline(1, '')
+    for i in range(20)
+      call append(line('$'), 'ほげほげほげ漢字テストあいうえおカタカナ')
+    endfor
+    call matchadd('Special', '漢字\|テスト')
+    normal gg
+    inoremap <F5> <Cmd>call complete(col('.'),
+          \ ['ほげ', 'ふが漢字', 'カタカナ候補'])<CR>
+  END
+  call writefile(lines, 'Xpumoptopacityattrs', 'D')
+  let buf = RunVimInTerminal('-S Xpumoptopacityattrs', {})
+  call TermWait(buf)
+  call term_sendkeys(buf, "i\<F5>")
+  call TermWait(buf, 100)
+  call VerifyScreenDump(buf, 'Test_pumopt_opacity_text_attrs', {})
+  call term_sendkeys(buf, "\<C-E>\<Esc>u")
+  call TermWait(buf)
+  call StopVimInTerminal(buf)
+endfunc
+
 " Test pumopt opacity:100 (fully opaque, same as default)
 func Test_pumopt_opacity_100()
   CheckScreendump
index 4cdbfdc0579075adc22833d7b82936b621fc480e..54ea03e260b668fab55455b7ed545f2569ec70fb 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    372,
 /**/
     371,
 /**/