patch 9.1.1621: flicker in popup menu during cmdline autocompletion
Problem: When the popup menu (PUM) occupies more than half the screen
height, it flickers whenever a character is typed or erased.
This happens because the PUM is cleared and the screen is
redrawn before a new PUM is rendered. The extra redraw between
menu updates causes visible flicker.
Solution: A complete, non-hacky fix would require removing the
CmdlineChanged event from the loop and letting autocompletion
manage the process end-to-end. This is because screen redraws
after any cmdline change are necessary for other features to
work.
This change modifies wildtrigger() so that the next typed
character defers the screen update instead of redrawing
immediately. This removes the intermediate redraw, eliminating
flicker and making cmdline autocompletion feel smooth
(Girish Palya).
Trade-offs:
This behavior change in wildtrigger() is tailored specifically for
:h cmdline-autocompletion. wildtrigger() now has no general-purpose use
outside this scenario.
closes: #17932
Signed-off-by: Girish Palya <girishji@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
committed by
Christian Brabandt
parent
4fca92faa2
commit
da9c966893
@ -939,6 +939,7 @@ cmdline_wildchar_complete(
|
||||
int *wim_index_p,
|
||||
expand_T *xp,
|
||||
int *gotesc,
|
||||
int redraw_if_menu_empty,
|
||||
pos_T *pre_incsearch_pos)
|
||||
{
|
||||
int wim_index = *wim_index_p;
|
||||
@ -991,6 +992,10 @@ cmdline_wildchar_complete(
|
||||
else
|
||||
res = nextwild(xp, WILD_EXPAND_KEEP, options, escape);
|
||||
|
||||
// Remove popup window if no completion items are available
|
||||
if (redraw_if_menu_empty && xp->xp_numfiles <= 0)
|
||||
update_screen(0);
|
||||
|
||||
// if interrupted while completing, behave like it failed
|
||||
if (got_int)
|
||||
{
|
||||
@ -1633,7 +1638,7 @@ getcmdline_int(
|
||||
int clear_ccline) // clear ccline first
|
||||
{
|
||||
static int depth = 0; // call depth
|
||||
int c;
|
||||
int c = 0;
|
||||
int i;
|
||||
int j;
|
||||
int gotesc = FALSE; // TRUE when <ESC> just typed
|
||||
@ -1838,6 +1843,7 @@ getcmdline_int(
|
||||
int trigger_cmdlinechanged = TRUE;
|
||||
int end_wildmenu;
|
||||
int prev_cmdpos = ccline.cmdpos;
|
||||
int skip_pum_redraw = FALSE;
|
||||
|
||||
VIM_CLEAR(prev_cmdbuff);
|
||||
|
||||
@ -1863,6 +1869,10 @@ getcmdline_int(
|
||||
goto returncmd;
|
||||
}
|
||||
|
||||
// Defer screen update to avoid pum flicker during wildtrigger()
|
||||
if (c == K_WILD && firstc != '@')
|
||||
skip_pum_redraw = TRUE;
|
||||
|
||||
// Get a character. Ignore K_IGNORE and K_NOP, they should not do
|
||||
// anything, such as stop completion.
|
||||
do
|
||||
@ -2002,7 +2012,12 @@ getcmdline_int(
|
||||
if (end_wildmenu)
|
||||
{
|
||||
if (cmdline_pum_active())
|
||||
cmdline_pum_remove(&ccline);
|
||||
{
|
||||
skip_pum_redraw = skip_pum_redraw && (vim_isprintc(c)
|
||||
|| c == K_BS || c == Ctrl_H || c == K_DEL
|
||||
|| c == K_KDEL || c == Ctrl_W || c == Ctrl_U);
|
||||
cmdline_pum_remove(&ccline, skip_pum_redraw);
|
||||
}
|
||||
if (xpc.xp_numfiles != -1)
|
||||
(void)ExpandOne(&xpc, NULL, NULL, 0, WILD_FREE);
|
||||
did_wild_list = FALSE;
|
||||
@ -2081,7 +2096,7 @@ getcmdline_int(
|
||||
if (c == K_WILD)
|
||||
++emsg_silent; // Silence the bell
|
||||
res = cmdline_wildchar_complete(c, firstc != '@', &did_wild_list,
|
||||
&wim_index, &xpc, &gotesc,
|
||||
&wim_index, &xpc, &gotesc, c == K_WILD,
|
||||
#ifdef FEAT_SEARCH_EXTRA
|
||||
&is_state.search_start
|
||||
#else
|
||||
@ -2647,7 +2662,7 @@ returncmd:
|
||||
// if certain special keys like <Esc> or <C-\> were used as wildchar. Make
|
||||
// sure to still clean up to avoid memory corruption.
|
||||
if (cmdline_pum_active())
|
||||
cmdline_pum_remove(&ccline);
|
||||
cmdline_pum_remove(&ccline, FALSE);
|
||||
wildmenu_cleanup(&ccline);
|
||||
did_wild_list = FALSE;
|
||||
wim_index = 0;
|
||||
|
||||
Reference in New Issue
Block a user