diff options
-rw-r--r-- | src/nvim/terminal.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/src/nvim/terminal.c b/src/nvim/terminal.c index b9bc4c6d78..eb010bc190 100644 --- a/src/nvim/terminal.c +++ b/src/nvim/terminal.c @@ -132,6 +132,8 @@ struct terminal { // the default values are used to obtain the color numbers passed to cterm // colors RgbValue colors[256]; + // With a reference count of 0 the terminal can be freed. + size_t refcount; }; static VTermScreenCallbacks vterm_screen_callbacks = { @@ -277,8 +279,10 @@ void terminal_close(Terminal *term, char *msg) // close_buffer() doesn't call this again. term->buf->terminal = NULL; term->buf = NULL; - // We should not wait for the user to press a key. - term->opts.close_cb(term->opts.data); + if (!term->refcount) { + // We should not wait for the user to press a key. + term->opts.close_cb(term->opts.data); + } } else { terminal_receive(term, msg, strlen(msg)); } @@ -376,7 +380,14 @@ void terminal_enter(void) break; case K_EVENT: + // We cannot let an event free the terminal yet. It is still needed. + term->refcount++; queue_process_events(loop.events); + term->refcount--; + if (term->buf == NULL) { + close = true; + goto end; + } break; case Ctrl_N: @@ -422,19 +433,22 @@ void terminal_destroy(Terminal *term) term->buf->terminal = 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); - } - for (size_t i = 0 ; i < term->sb_current; i++) { - xfree(term->sb_buffer[i]); + + if (!term->refcount) { + 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]); + } + xfree(term->sb_buffer); + vterm_free(term->vt); + xfree(term); } - xfree(term->sb_buffer); - vterm_free(term->vt); - xfree(term); } void terminal_send(Terminal *term, char *data, size_t size) |