fix(terminal): free the "[Process exited]" msg extmark #38246

Problem: Since the "[Process exited]" msg is no longer part of buffer
contents, `jobstart`'s reuse of unmodified finished terminal buffers
does not clear the msg.

Solution: Delete the extmark if `term` is already closed.
This commit is contained in:
Ayaan
2026-03-11 14:43:38 +05:30
committed by GitHub
parent b897e81b30
commit a2f01953b8
2 changed files with 8 additions and 10 deletions

View File

@@ -209,6 +209,7 @@ struct terminal {
VTermTerminator termrequest_terminator; ///< Terminator (BEL or ST) used in the termrequest
size_t refcount; // reference count
uint32_t exitmsg_id;
};
static VTermScreenCallbacks vterm_screen_callbacks = {
@@ -672,10 +673,14 @@ void terminal_close(Terminal **termpp, int status)
bool only_destroy = false;
buf_T *buf = handle_get_buffer(term->buf_handle);
if (term->closed) {
// If called from buf_close_terminal() after the process has already exited, we
// only need to call the close callback to clean up the terminal object.
only_destroy = true;
// Buffer may be reused so delete the "[Process exited]" msg
extmark_del_id(buf, (uint32_t)-1, term->exitmsg_id);
} else {
// flush any pending changes to the buffer
if (!exiting) {
@@ -686,8 +691,6 @@ void terminal_close(Terminal **termpp, int status)
term->closed = true;
}
buf_T *buf = handle_get_buffer(term->buf_handle);
if (status == -1 || exiting) {
// If this was called by buf_close_terminal() (status is -1), or if exiting, we
// must inform the buffer the terminal no longer exists so that buf_freeall()
@@ -729,7 +732,7 @@ void terminal_close(Terminal **termpp, int status)
int pos = MIN(row_to_linenr(term, term->cursor.row),
buf->b_ml.ml_line_count - 1);
extmark_set(buf, (uint32_t)-1, NULL, pos, 0, -1, 0,
extmark_set(buf, (uint32_t)-1, &term->exitmsg_id, pos, 0, -1, 0,
decor, 0, true, false, true, false, NULL);
// Redraw statusline to show the exit code.

View File

@@ -1313,11 +1313,6 @@ describe(':terminal buffer', function()
[Process exited 0] |
|*5
]])
api.nvim_buf_clear_namespace(0, -1, 0, -1)
env.screen:expect([[
^ready $ |
|*6
]])
env.buf = api.nvim_get_current_buf()
api.nvim_set_option_value('modified', false, { buf = env.buf })
end)
@@ -1334,10 +1329,10 @@ describe(':terminal buffer', function()
local chan = api.nvim_open_term(0, {})
api.nvim_chan_send(chan, 'TEST')
fn.chanclose(chan)
api.nvim_buf_clear_namespace(0, -1, 0, -1)
env.screen:expect([[
^TEST |
|*6
[Terminal closed] |
|*5
]])
env.buf = api.nvim_get_current_buf()
api.nvim_set_option_value('modified', false, { buf = env.buf })