mirror of
https://github.com/neovim/neovim.git
synced 2025-10-17 15:21:47 +00:00
fix(ui)!: decouple ext_messages from message grid #27963
Problem: ext_messages is implemented to mimic the message grid implementation w.r.t. scrolling messages, clearing scrolled messages, hit-enter-prompts and replacing a previous message. Meanwhile, an ext_messages UI may not be implemented in a way where these events are wanted. Moreover, correctness of these events even assuming a "scrolled message" implementation depends on fragile "currently visible messages" global state, which already isn't correct after a previous message was supposed to have been overwritten (because that should not only happen when `msg_scroll == false`). Solution: - No longer attempt to keep track of the currently visible messages: remove the `msg_ext(_history)_visible` variables. UIs may remove messages pre-emptively (timer based), or never show messages that don't fit a certain area in the first place. - No longer emit the `msg(_history)_clear` events to clear "scrolled" messages. This opens up the `msg_clear` event to be emitted when messages should actually be cleared (e.g. when the screen is cleared). May also be useful to emit before the first message in an event loop cycle as a hint to the UI that it is a new batch of messages (vim._extui currently schedules an event to determine that). - Set `replace_last` explicitly at the few callsites that want this to be set to true to replace an incomplete status message. - Don't store a "keep" message to be re-emitted.
This commit is contained in:
@@ -157,13 +157,6 @@ static sattr_T msg_ext_last_attr = -1;
|
||||
static int msg_ext_last_hl_id;
|
||||
|
||||
static bool msg_ext_history = false; ///< message was added to history
|
||||
static bool msg_ext_overwrite = false; ///< will overwrite last message
|
||||
static int msg_ext_visible = 0; ///< number of messages currently visible
|
||||
|
||||
static bool msg_ext_history_visible = false;
|
||||
|
||||
/// Shouldn't clear message after leaving cmdline
|
||||
static bool msg_ext_keep_after_cmdline = false;
|
||||
|
||||
static int msg_grid_pos_at_flush = 0;
|
||||
|
||||
@@ -1223,8 +1216,6 @@ void ex_messages(exarg_T *eap)
|
||||
if (kv_size(entries) > 0) {
|
||||
ui_call_msg_history_show(entries);
|
||||
api_free_array(entries);
|
||||
msg_ext_history_visible = true;
|
||||
wait_return(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1232,7 +1223,6 @@ void ex_messages(exarg_T *eap)
|
||||
/// and a delay.
|
||||
void msg_end_prompt(void)
|
||||
{
|
||||
msg_ext_clear_later();
|
||||
need_wait_return = false;
|
||||
emsg_on_display = false;
|
||||
cmdline_row = msg_row;
|
||||
@@ -1256,6 +1246,11 @@ void wait_return(int redraw)
|
||||
redraw_all_later(UPD_NOT_VALID);
|
||||
}
|
||||
|
||||
if (ui_has(kUIMessages)) {
|
||||
prompt_for_input("Press any key to continue", HLF_M, true, NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// If using ":silent cmd", don't wait for a return. Also don't set
|
||||
// need_wait_return to do it later.
|
||||
if (msg_silent != 0) {
|
||||
@@ -1404,7 +1399,6 @@ void wait_return(int redraw)
|
||||
}
|
||||
skip_redraw = true; // skip redraw once
|
||||
do_redraw = false;
|
||||
msg_ext_keep_after_cmdline = true;
|
||||
}
|
||||
|
||||
// If the screen size changed screen_resize() will redraw the screen.
|
||||
@@ -1430,9 +1424,6 @@ void wait_return(int redraw)
|
||||
if (redraw == true || (msg_scrolled != 0 && redraw != -1)) {
|
||||
redraw_later(curwin, UPD_VALID);
|
||||
}
|
||||
if (ui_has(kUIMessages)) {
|
||||
msg_ext_clear(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1450,8 +1441,6 @@ static void hit_return_msg(bool newline_sb)
|
||||
msg_putchar('\n');
|
||||
}
|
||||
p_more = false; // don't want to see this message when scrolling back
|
||||
msg_ext_skip_flush = false;
|
||||
msg_ext_set_kind("return_prompt");
|
||||
if (got_int) {
|
||||
msg_puts(_("Interrupt: "));
|
||||
}
|
||||
@@ -1466,6 +1455,11 @@ static void hit_return_msg(bool newline_sb)
|
||||
/// Set "keep_msg" to "s". Free the old value and check for NULL pointer.
|
||||
void set_keep_msg(const char *s, int hl_id)
|
||||
{
|
||||
// Kept message is not cleared and re-emitted with ext_messages: #20416.
|
||||
if (ui_has(kUIMessages)) {
|
||||
return;
|
||||
}
|
||||
|
||||
xfree(keep_msg);
|
||||
if (s != NULL && msg_silent == 0) {
|
||||
keep_msg = xstrdup(s);
|
||||
@@ -1577,10 +1571,6 @@ void msg_start(void)
|
||||
|
||||
if (ui_has(kUIMessages)) {
|
||||
msg_ext_ui_flush();
|
||||
if (!msg_scroll && msg_ext_visible) {
|
||||
// Will overwrite last message.
|
||||
msg_ext_overwrite = true;
|
||||
}
|
||||
}
|
||||
|
||||
// When redirecting, may need to start a new line.
|
||||
@@ -2177,16 +2167,7 @@ void msg_puts_len(const char *const str, const ptrdiff_t len, int hl_id, bool hi
|
||||
// need_wait_return after some prompt, and then outputting something
|
||||
// without scrolling
|
||||
// Not needed when only using CR to move the cursor.
|
||||
bool overflow = false;
|
||||
if (ui_has(kUIMessages)) {
|
||||
int count = msg_ext_visible + (msg_ext_overwrite ? 0 : 1);
|
||||
// TODO(bfredl): possible extension point, let external UI control this
|
||||
if (count > 1) {
|
||||
overflow = true;
|
||||
}
|
||||
} else {
|
||||
overflow = msg_scrolled > (p_ch == 0 ? 1 : 0);
|
||||
}
|
||||
bool overflow = !ui_has(kUIMessages) && msg_scrolled > (p_ch == 0 ? 1 : 0);
|
||||
|
||||
if (overflow && !msg_scrolled_ign && strcmp(str, "\r") != 0) {
|
||||
need_wait_return = true;
|
||||
@@ -2516,7 +2497,6 @@ void msg_scroll_flush(void)
|
||||
void msg_reset_scroll(void)
|
||||
{
|
||||
if (ui_has(kUIMessages)) {
|
||||
msg_ext_clear(true);
|
||||
return;
|
||||
}
|
||||
// TODO(bfredl): some duplicate logic with update_screen(). Later on
|
||||
@@ -2713,7 +2693,6 @@ void show_sb_text(void)
|
||||
{
|
||||
if (ui_has(kUIMessages)) {
|
||||
exarg_T ea = { .arg = "", .skip = true };
|
||||
msg_ext_clear(true);
|
||||
ex_messages(&ea);
|
||||
return;
|
||||
}
|
||||
@@ -3202,7 +3181,7 @@ void msg_ext_ui_flush(void)
|
||||
Array *tofree = msg_ext_init_chunks();
|
||||
ui_call_msg_show(cstr_as_string(msg_ext_kind), *tofree, msg_ext_overwrite, msg_ext_history,
|
||||
msg_ext_append);
|
||||
if (msg_ext_history || strequal(msg_ext_kind, "return_prompt")) {
|
||||
if (msg_ext_history) {
|
||||
api_free_array(*tofree);
|
||||
} else {
|
||||
// Add to history as temporary message for "g<".
|
||||
@@ -3216,9 +3195,6 @@ void msg_ext_ui_flush(void)
|
||||
msg_hist_add_multihl(msg, true);
|
||||
}
|
||||
xfree(tofree);
|
||||
if (!msg_ext_overwrite) {
|
||||
msg_ext_visible++;
|
||||
}
|
||||
msg_ext_overwrite = false;
|
||||
msg_ext_history = false;
|
||||
msg_ext_append = false;
|
||||
@@ -3243,44 +3219,6 @@ void msg_ext_flush_showmode(void)
|
||||
}
|
||||
}
|
||||
|
||||
void msg_ext_clear(bool force)
|
||||
{
|
||||
if (msg_ext_visible && (!msg_ext_keep_after_cmdline || force)) {
|
||||
ui_call_msg_clear();
|
||||
msg_ext_visible = 0;
|
||||
msg_ext_overwrite = false; // nothing to overwrite
|
||||
}
|
||||
if (msg_ext_history_visible) {
|
||||
ui_call_msg_history_clear();
|
||||
msg_ext_history_visible = false;
|
||||
}
|
||||
|
||||
// Only keep once.
|
||||
msg_ext_keep_after_cmdline = false;
|
||||
}
|
||||
|
||||
void msg_ext_clear_later(void)
|
||||
{
|
||||
if (msg_ext_is_visible()) {
|
||||
msg_ext_need_clear = true;
|
||||
set_must_redraw(UPD_VALID);
|
||||
}
|
||||
}
|
||||
|
||||
void msg_ext_check_clear(void)
|
||||
{
|
||||
// Redraw after cmdline or prompt is expected to clear messages.
|
||||
if (msg_ext_need_clear) {
|
||||
msg_ext_clear(true);
|
||||
msg_ext_need_clear = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool msg_ext_is_visible(void)
|
||||
{
|
||||
return ui_has(kUIMessages) && msg_ext_visible > 0;
|
||||
}
|
||||
|
||||
/// If the written message runs into the shown command or ruler, we have to
|
||||
/// wait for hit-return and redraw the window later.
|
||||
void msg_check(void)
|
||||
|
Reference in New Issue
Block a user