mirror of
https://github.com/neovim/neovim.git
synced 2025-09-22 19:18:34 +00:00
terminal: Ensure terminal buffers are flushed on exit
When a terminal closed, make sure it is refreshed before the Terminal structure is freed. Also extract `refresh_terminal` from `on_refresh`.
This commit is contained in:
@@ -428,7 +428,13 @@ void terminal_destroy(Terminal *term)
|
|||||||
term->buf->terminal = NULL;
|
term->buf->terminal = NULL;
|
||||||
}
|
}
|
||||||
term->buf = NULL;
|
term->buf = NULL;
|
||||||
|
if (pmap_has(ptr_t)(invalidated_terminals, term)) {
|
||||||
|
// flush any pending changes to the buffer
|
||||||
|
block_autocmds();
|
||||||
|
refresh_terminal(term);
|
||||||
|
unblock_autocmds();
|
||||||
pmap_del(ptr_t)(invalidated_terminals, term);
|
pmap_del(ptr_t)(invalidated_terminals, term);
|
||||||
|
}
|
||||||
for (size_t i = 0 ; i < term->sb_current; i++) {
|
for (size_t i = 0 ; i < term->sb_current; i++) {
|
||||||
xfree(term->sb_buffer[i]);
|
xfree(term->sb_buffer[i]);
|
||||||
}
|
}
|
||||||
@@ -884,6 +890,26 @@ static void invalidate_terminal(Terminal *term, int start_row, int end_row)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void refresh_terminal(Terminal *term)
|
||||||
|
{
|
||||||
|
// TODO(SplinterOfChaos): Find the condition that makes term->buf invalid.
|
||||||
|
bool valid = true;
|
||||||
|
if (!term->buf || !(valid = buf_valid(term->buf))) {
|
||||||
|
// destroyed by `close_buffer`. Dont do anything else
|
||||||
|
if (!valid) {
|
||||||
|
term->buf = NULL;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bool pending_resize = term->pending_resize;
|
||||||
|
WITH_BUFFER(term->buf, {
|
||||||
|
refresh_size(term);
|
||||||
|
refresh_scrollback(term);
|
||||||
|
refresh_screen(term);
|
||||||
|
redraw_buf_later(term->buf, NOT_VALID);
|
||||||
|
});
|
||||||
|
adjust_topline(term, pending_resize);
|
||||||
|
}
|
||||||
// libuv timer callback. This will enqueue on_refresh to be processed as an
|
// libuv timer callback. This will enqueue on_refresh to be processed as an
|
||||||
// event.
|
// event.
|
||||||
static void refresh_timer_cb(TimeWatcher *watcher, void *data)
|
static void refresh_timer_cb(TimeWatcher *watcher, void *data)
|
||||||
@@ -905,23 +931,7 @@ static void on_refresh(Event event)
|
|||||||
// don't process autocommands while updating terminal buffers
|
// don't process autocommands while updating terminal buffers
|
||||||
block_autocmds();
|
block_autocmds();
|
||||||
map_foreach(invalidated_terminals, term, stub, {
|
map_foreach(invalidated_terminals, term, stub, {
|
||||||
// TODO(SplinterOfChaos): Find the condition that makes term->buf invalid.
|
refresh_terminal(term);
|
||||||
bool valid = true;
|
|
||||||
if (!term->buf || !(valid = buf_valid(term->buf))) {
|
|
||||||
// destroyed by `close_buffer`. Dont do anything else
|
|
||||||
if (!valid) {
|
|
||||||
term->buf = NULL;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
bool pending_resize = term->pending_resize;
|
|
||||||
WITH_BUFFER(term->buf, {
|
|
||||||
refresh_size(term);
|
|
||||||
refresh_scrollback(term);
|
|
||||||
refresh_screen(term);
|
|
||||||
redraw_buf_later(term->buf, NOT_VALID);
|
|
||||||
});
|
|
||||||
adjust_topline(term, pending_resize);
|
|
||||||
});
|
});
|
||||||
pmap_clear(ptr_t)(invalidated_terminals);
|
pmap_clear(ptr_t)(invalidated_terminals);
|
||||||
unblock_autocmds();
|
unblock_autocmds();
|
||||||
|
Reference in New Issue
Block a user