aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/terminal.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/terminal.c')
-rw-r--r--src/nvim/terminal.c94
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)