mirror of
https://github.com/neovim/neovim
synced 2025-07-15 16:51:49 +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);
|
||||
}
|
||||
|
||||
// Don't make non-flushed message part of the showmode and reset global
|
||||
// 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;
|
||||
// Don't make non-flushed message part of the showmode.
|
||||
msg_ext_ui_flush();
|
||||
|
||||
msg_grid_validate();
|
||||
@ -960,8 +954,8 @@ int showmode(void)
|
||||
msg_check_for_delay(false);
|
||||
|
||||
// if the cmdline is more than one line high, erase top lines
|
||||
bool need_clear = clear_cmd;
|
||||
if (clear_cmd && cmdline_row < Rows - 1) {
|
||||
bool need_clear = clear_cmdline;
|
||||
if (clear_cmdline && cmdline_row < Rows - 1) {
|
||||
msg_clr_cmdline(); // will reset clear_cmdline
|
||||
}
|
||||
|
||||
@ -1083,7 +1077,7 @@ int showmode(void)
|
||||
}
|
||||
|
||||
mode_displayed = true;
|
||||
if (need_clear || clear_cmd || draw_mode) {
|
||||
if (need_clear || clear_cmdline || redraw_mode) {
|
||||
msg_clr_eos();
|
||||
}
|
||||
msg_didout = false; // overwrite this message
|
||||
@ -1092,10 +1086,10 @@ int showmode(void)
|
||||
msg_no_more = false;
|
||||
lines_left = save_lines_left;
|
||||
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".
|
||||
msg_clr_cmdline();
|
||||
} else if (draw_mode) {
|
||||
} else if (redraw_mode) {
|
||||
msg_pos_mode();
|
||||
msg_clr_eos();
|
||||
}
|
||||
@ -1118,6 +1112,10 @@ int showmode(void)
|
||||
grid_line_flush();
|
||||
}
|
||||
|
||||
redraw_cmdline = false;
|
||||
redraw_mode = false;
|
||||
clear_cmdline = false;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
|
@ -3455,11 +3455,9 @@ void cmdline_screen_cleared(void)
|
||||
/// called by ui_flush, do what redraws necessary to keep cmdline updated.
|
||||
void cmdline_ui_flush(void)
|
||||
{
|
||||
static bool flushing = false;
|
||||
if (!ui_has(kUICmdline) || flushing) {
|
||||
if (!ui_has(kUICmdline)) {
|
||||
return;
|
||||
}
|
||||
flushing = true;
|
||||
int level = ccline.level;
|
||||
CmdlineInfo *line = &ccline;
|
||||
while (level > 0 && line) {
|
||||
@ -3474,7 +3472,6 @@ void cmdline_ui_flush(void)
|
||||
}
|
||||
line = line->prev_ccline;
|
||||
}
|
||||
flushing = false;
|
||||
}
|
||||
|
||||
// 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, '')
|
||||
call_output:write('\n{\n')
|
||||
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)
|
||||
call_output:write(' ui_call_event("' .. ev.name .. '", ' .. args .. ');\n')
|
||||
call_output:write(' entered = false;\n')
|
||||
elseif ev.compositor_impl then
|
||||
call_output:write(' ui_comp_' .. ev.name)
|
||||
write_signature(call_output, ev, '', true)
|
||||
|
@ -1081,6 +1081,22 @@ stack traceback:
|
||||
},
|
||||
})
|
||||
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)
|
||||
|
||||
describe('ui/builtin messages', function()
|
||||
|
Reference in New Issue
Block a user