aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorluukvbaal <luukvbaal@gmail.com>2025-01-29 12:07:27 +0100
committerGitHub <noreply@github.com>2025-01-29 12:07:27 +0100
commit216ec739721494fb31111f19b1dee356a0d88ba1 (patch)
tree8a9f1cb65b7e1d2f7fb1a950264c38a0fea5ba81
parente7ebc5c13d2d1658005a7fb477bc92718044746f (diff)
downloadrneovim-216ec739721494fb31111f19b1dee356a0d88ba1.tar.gz
rneovim-216ec739721494fb31111f19b1dee356a0d88ba1.tar.bz2
rneovim-216ec739721494fb31111f19b1dee356a0d88ba1.zip
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.
-rw-r--r--src/nvim/drawscreen.c7
-rw-r--r--src/nvim/ex_getln.c54
-rw-r--r--test/functional/lua/ui_event_spec.lua4
3 files changed, 35 insertions, 30 deletions
diff --git a/src/nvim/drawscreen.c b/src/nvim/drawscreen.c
index 66c9b2be29..4d7f80bf76 100644
--- a/src/nvim/drawscreen.c
+++ b/src/nvim/drawscreen.c
@@ -692,8 +692,11 @@ int update_screen(void)
decor_providers_invoke_end();
- // either cmdline is cleared, not drawn or mode is last drawn
- cmdline_was_last_drawn = false;
+ // Either cmdline is cleared, not drawn or mode is last drawn.
+ // This does not (necessarily) overwrite an external cmdline.
+ if (!ui_has(kUICmdline)) {
+ cmdline_was_last_drawn = false;
+ }
return OK;
}
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 1eecee2a38..b5fa05e5a4 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -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.
///
/// @param count only used for incremental search
@@ -954,8 +963,7 @@ theend:
char *p = ccline.cmdbuff;
if (ui_has(kUICmdline)) {
- ccline.redraw_state = kCmdRedrawNone;
- ui_call_cmdline_hide(ccline.level, s->gotesc);
+ ui_ext_cmdline_hide(s->gotesc);
msg_ext_clear_later();
}
if (!cmd_silent) {
@@ -2209,14 +2217,19 @@ end:
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) {
trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
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 "?":
// 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
@@ -2696,11 +2709,7 @@ static int command_line_changed(CommandLineState *s)
// Trigger CmdlineChanged autocommands.
do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-');
- // Trigger CursorMovedC autocommands.
- if (ccline.cmdpos != s->prev_cmdpos) {
- trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC);
- s->prev_cmdpos = ccline.cmdpos;
- }
+ may_trigger_cursormovedc(s);
const bool prev_cmdpreview = cmdpreview;
if (s->firstc == ':'
@@ -2741,7 +2750,6 @@ static int command_line_changed(CommandLineState *s)
static void abandon_cmdline(void)
{
dealloc_cmdbuff();
- ccline.redraw_state = kCmdRedrawNone;
if (msg_scrolled == 0) {
compute_cmdrow();
}
@@ -3385,7 +3393,7 @@ color_cmdline_error:
// when cmdline_star is true.
static void draw_cmdline(int start, int len)
{
- if (!color_cmdline(&ccline)) {
+ if (ccline.cmdbuff == NULL || !color_cmdline(&ccline)) {
return;
}
@@ -3491,8 +3499,7 @@ void ui_ext_cmdline_block_leave(void)
ui_call_cmdline_block_hide();
}
-/// Extra redrawing needed for redraw! and on ui_attach
-/// assumes "redrawcmdline()" will already be invoked
+/// Extra redrawing needed for redraw! and on ui_attach.
void cmdline_screen_cleared(void)
{
if (!ui_has(kUICmdline)) {
@@ -3515,6 +3522,7 @@ void cmdline_screen_cleared(void)
}
line = line->prev_ccline;
}
+ redrawcmd();
}
/// called by ui_flush, do what redraws necessary to keep cmdline updated.
@@ -3527,12 +3535,14 @@ void cmdline_ui_flush(void)
CmdlineInfo *line = &ccline;
while (level > 0 && line) {
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);
- } else if (line->redraw_state == kCmdRedrawPos) {
+ } else if (redraw_state == kCmdRedrawPos && cmdline_was_last_drawn) {
ui_call_cmdline_pos(line->cmdpos, line->level);
}
- line->redraw_state = kCmdRedrawNone;
level--;
}
line = line->prev_ccline;
@@ -3900,12 +3910,7 @@ void compute_cmdrow(void)
void cursorcmd(void)
{
- if (cmd_silent) {
- return;
- }
-
- if (ui_has(kUICmdline)) {
- ccline.redraw_state = MAX(ccline.redraw_state, kCmdRedrawPos);
+ if (cmd_silent || ui_has(kUICmdline)) {
return;
}
@@ -4507,10 +4512,7 @@ static int open_cmdwin(void)
curwin->w_cursor.col = ccline.cmdpos;
changed_line_abv_curs();
invalidate_botline(curwin);
- if (ui_has(kUICmdline)) {
- ccline.redraw_state = kCmdRedrawNone;
- ui_call_cmdline_hide(ccline.level, false);
- }
+ ui_ext_cmdline_hide(false);
redraw_later(curwin, UPD_SOME_VALID);
// No Ex mode here!
diff --git a/test/functional/lua/ui_event_spec.lua b/test/functional/lua/ui_event_spec.lua
index 80457555d4..ddb10127e4 100644
--- a/test/functional/lua/ui_event_spec.lua
+++ b/test/functional/lua/ui_event_spec.lua
@@ -202,7 +202,7 @@ describe('vim.ui_attach', function()
feed([[:call confirm("Save changes?", "&Yes\n&No\n&Cancel")<CR>]])
screen:expect({
grid = [[
- ^5 |
+ ^4 |
{1:~ }|*4
]],
cmdline = {
@@ -224,7 +224,7 @@ describe('vim.ui_attach', function()
feed('n')
screen:expect({
grid = [[
- ^5 |
+ ^4 |
{1:~ }|*4
]],
cmdline = { { abort = false } },