fix(tui): attribute TermResponse to source channel #40330

Problem: Attach-time terminal probes cannot distinguish responses from
different attached UIs.

Solution: Identify the UI by RPC channel id in `TermResponse` and make
`vim.tty.request()` filter responses by channel.
This commit is contained in:
Barrett Ruth
2026-06-23 05:19:56 -05:00
committed by GitHub
parent e4fbe162c1
commit db30608058
8 changed files with 139 additions and 78 deletions

View File

@@ -66,6 +66,6 @@ void nvim_ui_term_event(uint64_t channel_id, String event, Object value, Error *
const String termresponse = value.data.string;
set_vim_var_string(VV_TERMRESPONSE, termresponse.data, (ptrdiff_t)termresponse.size);
do_termresponse_autocmd(termresponse);
do_termresponse_autocmd(termresponse, channel_id);
}
}

View File

@@ -106,6 +106,7 @@ static bool autocmd_nested = false;
static bool autocmd_include_groups = false;
static bool termresponse_changed = false;
static uint64_t termresponse_chan_id = 0;
// Map of autocmd group names and ids.
// name -> ID
@@ -2085,13 +2086,15 @@ BYPASS_AU:
return retval;
}
void do_termresponse_autocmd(const String sequence)
void do_termresponse_autocmd(const String sequence, uint64_t channel_id)
{
MAXSIZE_TEMP_DICT(data, 1);
MAXSIZE_TEMP_DICT(data, 2);
PUT_C(data, "sequence", STRING_OBJ(sequence));
PUT_C(data, "chan", INTEGER_OBJ((Integer)channel_id));
apply_autocmds_group(EVENT_TERMRESPONSE, NULL, NULL, true, AUGROUP_ALL, NULL, NULL,
&DICT_OBJ(data), false);
termresponse_changed = true;
termresponse_chan_id = channel_id;
}
// Block triggering autocommands until unblock_autocmd() is called.
@@ -2101,6 +2104,7 @@ void block_autocmds(void)
// Detect if v:termresponse is set while blocked.
if (!is_autocmd_blocked()) {
termresponse_changed = false;
termresponse_chan_id = 0;
}
autocmd_blocked++;
}
@@ -2115,7 +2119,7 @@ void unblock_autocmds(void)
if (!is_autocmd_blocked() && termresponse_changed && has_event(EVENT_TERMRESPONSE)) {
// Copied to a new allocation, as termresponse may be freed during the event.
const String sequence = cstr_to_string(get_vim_var_str(VV_TERMRESPONSE));
do_termresponse_autocmd(sequence);
do_termresponse_autocmd(sequence, termresponse_chan_id);
api_free_string(sequence);
}
}