diff options
Diffstat (limited to 'src/nvim/terminal.c')
-rw-r--r-- | src/nvim/terminal.c | 94 |
1 files changed, 48 insertions, 46 deletions
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index 42d0421f0c..b9bc4c6d78 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -67,7 +67,9 @@ #include "nvim/ex_cmds.h" #include "nvim/window.h" #include "nvim/fileio.h" -#include "nvim/os/event.h" +#include "nvim/event/loop.h" +#include "nvim/event/time.h" +#include "nvim/os/input.h" #include "nvim/api/private/helpers.h" #ifdef INCLUDE_GENERATED_DECLARATIONS @@ -80,7 +82,7 @@ // of data. #define REFRESH_DELAY 10 -static uv_timer_t refresh_timer; +static TimeWatcher refresh_timer; static bool refresh_pending = false; typedef struct { @@ -150,7 +152,7 @@ static VTermColor default_vt_bg_rgb; void terminal_init(void) { invalidated_terminals = pmap_new(ptr_t)(); - uv_timer_init(uv_default_loop(), &refresh_timer); + time_watcher_init(&loop, &refresh_timer, NULL); // initialize a rgb->color index map for cterm attributes(VTermScreenCell // only has RGB information and we need color indexes for terminal UIs) @@ -175,8 +177,8 @@ void terminal_init(void) void terminal_teardown(void) { - uv_timer_stop(&refresh_timer); - uv_close((uv_handle_t *)&refresh_timer, NULL); + time_watcher_stop(&refresh_timer); + time_watcher_close(&refresh_timer, NULL); pmap_free(ptr_t)(invalidated_terminals); map_free(int, int)(color_indexes); } @@ -323,7 +325,7 @@ void terminal_resize(Terminal *term, uint16_t width, uint16_t height) invalidate_terminal(term, -1, -1); } -void terminal_enter(bool process_deferred) +void terminal_enter(void) { Terminal *term = curbuf->terminal; assert(term && "should only be called when curbuf has a terminal"); @@ -352,15 +354,9 @@ void terminal_enter(bool process_deferred) bool got_bs = false; // True if the last input was <C-\> while (term->buf == curbuf) { - if (process_deferred) { - event_enable_deferred(); - } - + input_enable_events(); c = safe_vgetc(); - - if (process_deferred) { - event_disable_deferred(); - } + input_disable_events(); switch (c) { case K_LEFTMOUSE: @@ -380,7 +376,7 @@ void terminal_enter(bool process_deferred) break; case K_EVENT: - event_process(); + queue_process_events(loop.events); break; case Ctrl_N: @@ -426,7 +422,13 @@ void terminal_destroy(Terminal *term) term->buf->terminal = NULL; } term->buf = NULL; - pmap_del(ptr_t)(invalidated_terminals, term); + 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); + } for (size_t i = 0 ; i < term->sb_current; i++) { xfree(term->sb_buffer[i]); } @@ -572,9 +574,10 @@ static int term_settermprop(VTermProp prop, VTermValue *val, void *data) case VTERM_PROP_TITLE: { Error err; - dict_set_value(term->buf->b_vars, - cstr_as_string("term_title"), - STRING_OBJ(cstr_as_string(val->string)), &err); + api_free_object(dict_set_value(term->buf->b_vars, + cstr_as_string("term_title"), + STRING_OBJ(cstr_as_string(val->string)), + &err)); break; } @@ -876,53 +879,52 @@ static void invalidate_terminal(Terminal *term, int start_row, int end_row) pmap_put(ptr_t)(invalidated_terminals, term, NULL); if (!refresh_pending) { - uv_timer_start(&refresh_timer, refresh_timer_cb, REFRESH_DELAY, 0); + time_watcher_start(&refresh_timer, refresh_timer_cb, REFRESH_DELAY, 0); refresh_pending = true; } } -// libuv timer callback. This will enqueue on_refresh to be processed as an -// event. -static void refresh_timer_cb(uv_timer_t *handle) +static void refresh_terminal(Terminal *term) { - event_push((Event) {.handler = on_refresh}, false); - refresh_pending = false; + // 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); } - -// Refresh all invalidated terminals -static void on_refresh(Event event) +// libuv timer callback. This will enqueue on_refresh to be processed as an +// event. +static void refresh_timer_cb(TimeWatcher *watcher, void *data) { if (exiting) { // bad things can happen if we redraw when exiting, and there's no need to // update the buffer. - return; + goto end; } Terminal *term; void *stub; (void)(stub); // don't process autocommands while updating terminal buffers block_autocmds(); map_foreach(invalidated_terminals, term, stub, { - // 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; - } - 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); + refresh_terminal(term); }); pmap_clear(ptr_t)(invalidated_terminals); unblock_autocmds(); redraw(true); +end: + refresh_pending = false; } static void refresh_size(Terminal *term) |