fix(ui): avoid redundant ext_cmdline events (#32237)

Problem:  `cmdline_show` is emitted unnecessarily each event
          loop iteration, because `cmdline_was_last_drawn` is never set.
Solution: Keep track of whether the cmdline was last drawn to avoid
          unnecessarily emitting cmdline_show. Set `redraw_state` to
          emit `cmdline_pos` when emitting `CursorMovedC`. Only emit
          `cmdline_pos` when cmdline was last drawn.
This commit is contained in:
luukvbaal
2025-01-29 12:07:27 +01:00
committed by GitHub
parent e7ebc5c13d
commit 216ec73972
3 changed files with 35 additions and 30 deletions

View File

@@ -692,8 +692,11 @@ int update_screen(void)
decor_providers_invoke_end(); decor_providers_invoke_end();
// either cmdline is cleared, not drawn or mode is last drawn // Either cmdline is cleared, not drawn or mode is last drawn.
cmdline_was_last_drawn = false; // This does not (necessarily) overwrite an external cmdline.
if (!ui_has(kUICmdline)) {
cmdline_was_last_drawn = false;
}
return OK; return OK;
} }

View File

@@ -679,6 +679,15 @@ static void init_ccline(int firstc, int indent)
} }
} }
static void ui_ext_cmdline_hide(bool abort)
{
if (ui_has(kUICmdline)) {
cmdline_was_last_drawn = false;
ccline.redraw_state = kCmdRedrawNone;
ui_call_cmdline_hide(ccline.level, abort);
}
}
/// Internal entry point for cmdline mode. /// Internal entry point for cmdline mode.
/// ///
/// @param count only used for incremental search /// @param count only used for incremental search
@@ -954,8 +963,7 @@ theend:
char *p = ccline.cmdbuff; char *p = ccline.cmdbuff;
if (ui_has(kUICmdline)) { if (ui_has(kUICmdline)) {
ccline.redraw_state = kCmdRedrawNone; ui_ext_cmdline_hide(s->gotesc);
ui_call_cmdline_hide(ccline.level, s->gotesc);
msg_ext_clear_later(); msg_ext_clear_later();
} }
if (!cmd_silent) { if (!cmd_silent) {
@@ -2209,14 +2217,19 @@ end:
return ccline.one_key ? 0 : command_line_changed(s); return ccline.one_key ? 0 : command_line_changed(s);
} }
static int command_line_not_changed(CommandLineState *s) /// Trigger CursorMovedC autocommands.
static void may_trigger_cursormovedc(CommandLineState *s)
{ {
// Trigger CursorMovedC autocommands.
if (ccline.cmdpos != s->prev_cmdpos) { if (ccline.cmdpos != s->prev_cmdpos) {
trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC); trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
s->prev_cmdpos = ccline.cmdpos; s->prev_cmdpos = ccline.cmdpos;
ccline.redraw_state = MAX(ccline.redraw_state, kCmdRedrawPos);
} }
}
static int command_line_not_changed(CommandLineState *s)
{
may_trigger_cursormovedc(s);
// Incremental searches for "/" and "?": // Incremental searches for "/" and "?":
// Enter command_line_not_changed() when a character has been read but the // Enter command_line_not_changed() when a character has been read but the
// command line did not change. Then we only search and redraw if something // command line did not change. Then we only search and redraw if something
@@ -2696,11 +2709,7 @@ static int command_line_changed(CommandLineState *s)
// Trigger CmdlineChanged autocommands. // Trigger CmdlineChanged autocommands.
do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-'); do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-');
// Trigger CursorMovedC autocommands. may_trigger_cursormovedc(s);
if (ccline.cmdpos != s->prev_cmdpos) {
trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
s->prev_cmdpos = ccline.cmdpos;
}
const bool prev_cmdpreview = cmdpreview; const bool prev_cmdpreview = cmdpreview;
if (s->firstc == ':' if (s->firstc == ':'
@@ -2741,7 +2750,6 @@ static int command_line_changed(CommandLineState *s)
static void abandon_cmdline(void) static void abandon_cmdline(void)
{ {
dealloc_cmdbuff(); dealloc_cmdbuff();
ccline.redraw_state = kCmdRedrawNone;
if (msg_scrolled == 0) { if (msg_scrolled == 0) {
compute_cmdrow(); compute_cmdrow();
} }
@@ -3385,7 +3393,7 @@ color_cmdline_error:
// when cmdline_star is true. // when cmdline_star is true.
static void draw_cmdline(int start, int len) static void draw_cmdline(int start, int len)
{ {
if (!color_cmdline(&ccline)) { if (ccline.cmdbuff == NULL || !color_cmdline(&ccline)) {
return; return;
} }
@@ -3491,8 +3499,7 @@ void ui_ext_cmdline_block_leave(void)
ui_call_cmdline_block_hide(); ui_call_cmdline_block_hide();
} }
/// Extra redrawing needed for redraw! and on ui_attach /// Extra redrawing needed for redraw! and on ui_attach.
/// assumes "redrawcmdline()" will already be invoked
void cmdline_screen_cleared(void) void cmdline_screen_cleared(void)
{ {
if (!ui_has(kUICmdline)) { if (!ui_has(kUICmdline)) {
@@ -3515,6 +3522,7 @@ void cmdline_screen_cleared(void)
} }
line = line->prev_ccline; line = line->prev_ccline;
} }
redrawcmd();
} }
/// called by ui_flush, do what redraws necessary to keep cmdline updated. /// called by ui_flush, do what redraws necessary to keep cmdline updated.
@@ -3527,12 +3535,14 @@ void cmdline_ui_flush(void)
CmdlineInfo *line = &ccline; CmdlineInfo *line = &ccline;
while (level > 0 && line) { while (level > 0 && line) {
if (line->level == level) { if (line->level == level) {
if (line->redraw_state == kCmdRedrawAll) { CmdRedraw redraw_state = line->redraw_state;
line->redraw_state = kCmdRedrawNone;
if (redraw_state == kCmdRedrawAll) {
cmdline_was_last_drawn = true;
ui_ext_cmdline_show(line); ui_ext_cmdline_show(line);
} else if (line->redraw_state == kCmdRedrawPos) { } else if (redraw_state == kCmdRedrawPos && cmdline_was_last_drawn) {
ui_call_cmdline_pos(line->cmdpos, line->level); ui_call_cmdline_pos(line->cmdpos, line->level);
} }
line->redraw_state = kCmdRedrawNone;
level--; level--;
} }
line = line->prev_ccline; line = line->prev_ccline;
@@ -3900,12 +3910,7 @@ void compute_cmdrow(void)
void cursorcmd(void) void cursorcmd(void)
{ {
if (cmd_silent) { if (cmd_silent || ui_has(kUICmdline)) {
return;
}
if (ui_has(kUICmdline)) {
ccline.redraw_state = MAX(ccline.redraw_state, kCmdRedrawPos);
return; return;
} }
@@ -4507,10 +4512,7 @@ static int open_cmdwin(void)
curwin->w_cursor.col = ccline.cmdpos; curwin->w_cursor.col = ccline.cmdpos;
changed_line_abv_curs(); changed_line_abv_curs();
invalidate_botline(curwin); invalidate_botline(curwin);
if (ui_has(kUICmdline)) { ui_ext_cmdline_hide(false);
ccline.redraw_state = kCmdRedrawNone;
ui_call_cmdline_hide(ccline.level, false);
}
redraw_later(curwin, UPD_SOME_VALID); redraw_later(curwin, UPD_SOME_VALID);
// No Ex mode here! // No Ex mode here!

View File

@@ -202,7 +202,7 @@ describe('vim.ui_attach', function()
feed([[:call confirm("Save changes?", "&Yes\n&No\n&Cancel")<CR>]]) feed([[:call confirm("Save changes?", "&Yes\n&No\n&Cancel")<CR>]])
screen:expect({ screen:expect({
grid = [[ grid = [[
^5 | ^4 |
{1:~ }|*4 {1:~ }|*4
]], ]],
cmdline = { cmdline = {
@@ -224,7 +224,7 @@ describe('vim.ui_attach', function()
feed('n') feed('n')
screen:expect({ screen:expect({
grid = [[ grid = [[
^5 | ^4 |
{1:~ }|*4 {1:~ }|*4
]], ]],
cmdline = { { abort = false } }, cmdline = { { abort = false } },