+ (pum_shadow ? 2 : 0);
int extra_above = pum_border;
int extra_below = pum_border + (pum_shadow ? 1 : 0);
+ int top = pum_row - extra_above;
+ int bot = pum_row + pum_height + extra_below;
+ int left = pum_col - 1 - extra_left;
+ int right = pum_col + pum_width + pum_scrollbar + extra_right;
- return (!only_redrawing || pum_will_redraw)
- && row >= pum_row - extra_above
- && row < pum_row + pum_height + extra_below
- && col >= pum_col - 1 - extra_left
- && col < pum_col + pum_width + pum_scrollbar + extra_right;
+ if (!((!only_redrawing || pum_will_redraw)
+ && row >= top && row < bot && col >= left && col < right))
+ return FALSE;
+
+ if (pum_shadow)
+ {
+ // The shadow recolors the cells underneath. When the menu will be
+ // redrawn, leave the shadow cells unprotected so the window refreshes
+ // them first, clearing stale content left by a larger menu.
+ if (only_redrawing)
+ {
+ if (col >= right - 2 || row == bot - 1)
+ return FALSE;
+ }
+ else
+ {
+ // Menu stays as-is: exclude only the corner cells the shadow never
+ // draws.
+ int right_margin, left_margin, left_padding;
+
+ compute_margins(&right_margin, &left_margin, &left_padding);
+ if (row == top && col >= right - 2)
+ return FALSE;
+ if (row == bot - 1 && col < pum_col + 2 - left_padding - pum_border
+ - left_margin)
+ return FALSE;
+ }
+ }
+ return TRUE;
}
/*
call StopVimInTerminal(buf)
endfunc
+" When the wildmenu popup menu shrinks, its shadow must be cleared, also on the
+" empty (~) lines above the menu. See issue #20740.
+func Test_wildmenu_pum_shadow()
+ CheckScreendump
+
+ let lines =<< trim [SCRIPT]
+ func MyCompl(a, l, p)
+ return filter(['axxxxxxxxx', 'ab', 'ac'], 'stridx(v:val, a:a) == 0')
+ endfunc
+ command! -nargs=1 -complete=customlist,MyCompl MyCmd echo <q-args>
+ set wildmode=noselect:lastused,full
+ set wildoptions=pum,fuzzy
+ set pumopt=shadow
+ set shortmess+=I
+ " Give the shadow a distinct color so it is easy to tell apart from the
+ " background in the screen dump.
+ hi Normal ctermbg=grey ctermfg=black guibg=grey guifg=black
+ hi PmenuShadow ctermbg=darkred ctermfg=white guibg=darkred guifg=white
+ autocmd CmdlineChanged : call wildtrigger()
+ [SCRIPT]
+ call writefile(lines, 'XTest_wildshadow', 'D')
+
+ let buf = RunVimInTerminal('-S XTest_wildshadow', {'rows': 12, 'cols': 40})
+
+ " Wide popup with a shadow drawn over the ~ lines.
+ call term_sendkeys(buf, ":MyCmd a")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_shadow_1', {})
+
+ " Narrow the matches: the popup shrinks and the wider shadow must be cleared.
+ call term_sendkeys(buf, "b")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_shadow_2', {})
+
+ call term_sendkeys(buf, "\<Esc>")
+ call StopVimInTerminal(buf)
+endfunc
+
+" Same as above but with a border, and the menu also gets narrower. When the
+" menu shrinks the stale content of the wider menu must be cleared before the
+" shadow is drawn over it, otherwise the old border and text show through the
+" shadow. See issue #20740.
+func Test_wildmenu_pum_shadow_border()
+ CheckScreendump
+
+ let lines =<< trim [SCRIPT]
+ func MyCompl(a, l, p)
+ return filter(['aVeryLongItemName', 'ab', 'ac'], 'stridx(v:val, a:a) == 0')
+ endfunc
+ command! -nargs=1 -complete=customlist,MyCompl MyCmd echo <q-args>
+ set wildmode=noselect:lastused,full
+ set wildoptions=pum,fuzzy
+ set pumopt=shadow,border:single
+ set shortmess+=I
+ " Give the shadow a distinct color so it is easy to tell apart from the
+ " background in the screen dump.
+ hi Normal ctermbg=grey ctermfg=black guibg=grey guifg=black
+ hi PmenuShadow ctermbg=darkred ctermfg=white guibg=darkred guifg=white
+ autocmd CmdlineChanged : call wildtrigger()
+ [SCRIPT]
+ call writefile(lines, 'XTest_wildshadowborder', 'D')
+
+ let buf = RunVimInTerminal('-S XTest_wildshadowborder', {'rows': 12, 'cols': 40})
+
+ " Wide popup with a border and a shadow drawn over the ~ lines.
+ call term_sendkeys(buf, ":MyCmd a")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_shadow_border_1', {})
+
+ " Narrow the matches: the popup shrinks in both width and height, the wider
+ " menu's border and text must be cleared next to and under the shadow.
+ call term_sendkeys(buf, "b")
+ call TermWait(buf, 50)
+ call VerifyScreenDump(buf, 'Test_wildmenu_pum_shadow_border_2', {})
+
+ call term_sendkeys(buf, "\<Esc>")
+ call StopVimInTerminal(buf)
+endfunc
+
func Test_wildmenu_with_input_func()
CheckScreendump