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:
Girish Palya
2025-08-08 08:26:03 +02:00
committed by Christian Brabandt
parent 4fca92faa2
commit da9c966893
8 changed files with 101 additions and 12 deletions

View File

@ -455,9 +455,8 @@ cmdline_pum_active(void)
* items and refresh the screen.
*/
void
cmdline_pum_remove(cmdline_info_T *cclp UNUSED)
cmdline_pum_remove(cmdline_info_T *cclp UNUSED, int defer_redraw)
{
int save_p_lz = p_lz;
int save_KeyTyped = KeyTyped;
#ifdef FEAT_EVAL
int save_RedrawingDisabled = RedrawingDisabled;
@ -468,9 +467,15 @@ cmdline_pum_remove(cmdline_info_T *cclp UNUSED)
pum_undisplay();
VIM_CLEAR(compl_match_array);
compl_match_arraysize = 0;
p_lz = FALSE; // avoid the popup menu hanging around
update_screen(0);
p_lz = save_p_lz;
if (!defer_redraw)
{
int save_p_lz = p_lz;
p_lz = FALSE; // avoid the popup menu hanging around
update_screen(0);
p_lz = save_p_lz;
}
else
pum_call_update_screen();
redrawcmd();
// When a function is called (e.g. for 'foldtext') KeyTyped might be reset
@ -485,7 +490,7 @@ cmdline_pum_remove(cmdline_info_T *cclp UNUSED)
void
cmdline_pum_cleanup(cmdline_info_T *cclp)
{
cmdline_pum_remove(cclp);
cmdline_pum_remove(cclp, FALSE);
wildmenu_cleanup(cclp);
}
@ -1068,7 +1073,7 @@ ExpandOne(
// The entries from xp_files may be used in the PUM, remove it.
if (compl_match_array != NULL)
cmdline_pum_remove(get_cmdline_info());
cmdline_pum_remove(get_cmdline_info(), FALSE);
}
xp->xp_selected = 0;