mirror of
https://github.com/neovim/neovim
synced 2025-07-16 09:11:51 +00:00
fix(ui): superfluous showmode / excessive grid_cursor_goto #29089
Problem: Unsetting global variables earlier in #28578 to avoid recursiveness, caused superfluous or even unlimited showmode(). Solution: Partly revert #28578 so that the globals are unset at the end of showmode(), and avoid recursiveness for ext UI by adding a recursive function guard to each generated UI call that may call a Lua callback.
This commit is contained in:
@ -931,13 +931,7 @@ int showmode(void)
|
|||||||
msg_ext_clear(true);
|
msg_ext_clear(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't make non-flushed message part of the showmode and reset global
|
// Don't make non-flushed message part of the showmode.
|
||||||
// variables before flushing to to avoid recursiveness.
|
|
||||||
bool draw_mode = redraw_mode;
|
|
||||||
bool clear_cmd = clear_cmdline;
|
|
||||||
redraw_cmdline = false;
|
|
||||||
redraw_mode = false;
|
|
||||||
clear_cmdline = false;
|
|
||||||
msg_ext_ui_flush();
|
msg_ext_ui_flush();
|
||||||
|
|
||||||
msg_grid_validate();
|
msg_grid_validate();
|
||||||
@ -960,8 +954,8 @@ int showmode(void)
|
|||||||
msg_check_for_delay(false);
|
msg_check_for_delay(false);
|
||||||
|
|
||||||
// if the cmdline is more than one line high, erase top lines
|
// if the cmdline is more than one line high, erase top lines
|
||||||
bool need_clear = clear_cmd;
|
bool need_clear = clear_cmdline;
|
||||||
if (clear_cmd && cmdline_row < Rows - 1) {
|
if (clear_cmdline && cmdline_row < Rows - 1) {
|
||||||
msg_clr_cmdline(); // will reset clear_cmdline
|
msg_clr_cmdline(); // will reset clear_cmdline
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1083,7 +1077,7 @@ int showmode(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
mode_displayed = true;
|
mode_displayed = true;
|
||||||
if (need_clear || clear_cmd || draw_mode) {
|
if (need_clear || clear_cmdline || redraw_mode) {
|
||||||
msg_clr_eos();
|
msg_clr_eos();
|
||||||
}
|
}
|
||||||
msg_didout = false; // overwrite this message
|
msg_didout = false; // overwrite this message
|
||||||
@ -1092,10 +1086,10 @@ int showmode(void)
|
|||||||
msg_no_more = false;
|
msg_no_more = false;
|
||||||
lines_left = save_lines_left;
|
lines_left = save_lines_left;
|
||||||
need_wait_return = nwr_save; // never ask for hit-return for this
|
need_wait_return = nwr_save; // never ask for hit-return for this
|
||||||
} else if (clear_cmd && msg_silent == 0) {
|
} else if (clear_cmdline && msg_silent == 0) {
|
||||||
// Clear the whole command line. Will reset "clear_cmdline".
|
// Clear the whole command line. Will reset "clear_cmdline".
|
||||||
msg_clr_cmdline();
|
msg_clr_cmdline();
|
||||||
} else if (draw_mode) {
|
} else if (redraw_mode) {
|
||||||
msg_pos_mode();
|
msg_pos_mode();
|
||||||
msg_clr_eos();
|
msg_clr_eos();
|
||||||
}
|
}
|
||||||
@ -1118,6 +1112,10 @@ int showmode(void)
|
|||||||
grid_line_flush();
|
grid_line_flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
redraw_cmdline = false;
|
||||||
|
redraw_mode = false;
|
||||||
|
clear_cmdline = false;
|
||||||
|
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3455,11 +3455,9 @@ void cmdline_screen_cleared(void)
|
|||||||
/// called by ui_flush, do what redraws necessary to keep cmdline updated.
|
/// called by ui_flush, do what redraws necessary to keep cmdline updated.
|
||||||
void cmdline_ui_flush(void)
|
void cmdline_ui_flush(void)
|
||||||
{
|
{
|
||||||
static bool flushing = false;
|
if (!ui_has(kUICmdline)) {
|
||||||
if (!ui_has(kUICmdline) || flushing) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
flushing = true;
|
|
||||||
int level = ccline.level;
|
int level = ccline.level;
|
||||||
CmdlineInfo *line = &ccline;
|
CmdlineInfo *line = &ccline;
|
||||||
while (level > 0 && line) {
|
while (level > 0 && line) {
|
||||||
@ -3474,7 +3472,6 @@ void cmdline_ui_flush(void)
|
|||||||
}
|
}
|
||||||
line = line->prev_ccline;
|
line = line->prev_ccline;
|
||||||
}
|
}
|
||||||
flushing = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put a character on the command line. Shifts the following text to the
|
// Put a character on the command line. Shifts the following text to the
|
||||||
|
@ -128,8 +128,16 @@ for i = 1, #events do
|
|||||||
write_signature(call_output, ev, '')
|
write_signature(call_output, ev, '')
|
||||||
call_output:write('\n{\n')
|
call_output:write('\n{\n')
|
||||||
if ev.remote_only then
|
if ev.remote_only then
|
||||||
|
-- Lua callbacks may emit other events or the same event again. Avoid the latter
|
||||||
|
-- by adding a recursion guard to each generated function that may call a Lua callback.
|
||||||
|
call_output:write(' static bool entered = false;\n')
|
||||||
|
call_output:write(' if (entered) {\n')
|
||||||
|
call_output:write(' return;\n')
|
||||||
|
call_output:write(' }\n')
|
||||||
|
call_output:write(' entered = true;\n')
|
||||||
write_arglist(call_output, ev)
|
write_arglist(call_output, ev)
|
||||||
call_output:write(' ui_call_event("' .. ev.name .. '", ' .. args .. ');\n')
|
call_output:write(' ui_call_event("' .. ev.name .. '", ' .. args .. ');\n')
|
||||||
|
call_output:write(' entered = false;\n')
|
||||||
elseif ev.compositor_impl then
|
elseif ev.compositor_impl then
|
||||||
call_output:write(' ui_comp_' .. ev.name)
|
call_output:write(' ui_comp_' .. ev.name)
|
||||||
write_signature(call_output, ev, '', true)
|
write_signature(call_output, ev, '', true)
|
||||||
|
@ -1081,6 +1081,22 @@ stack traceback:
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('does not do showmode unnecessarily #29086', function()
|
||||||
|
local screen_showmode = screen._handle_msg_showmode
|
||||||
|
local showmode = 0
|
||||||
|
screen._handle_msg_showmode = function(...)
|
||||||
|
screen_showmode(...)
|
||||||
|
showmode = showmode + 1
|
||||||
|
end
|
||||||
|
screen:expect({
|
||||||
|
grid = [[
|
||||||
|
^ |
|
||||||
|
{1:~ }|*4
|
||||||
|
]],
|
||||||
|
})
|
||||||
|
eq(showmode, 1)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe('ui/builtin messages', function()
|
describe('ui/builtin messages', function()
|
||||||
|
Reference in New Issue
Block a user