fix(app): closing a pending split keeps the keys held for another terminal (P0 1193)

Closed
LA
5d ago
+19-1

Summary

P0 1193 family (lead 21:2xZ, re-ranked from the review of #29693, low finding 1): when the person closed a pending split (Cmd-W on its stand-in) and no other creation waited any more, CreationInputBuffer.cancel(tab:) dropped every held key, including a line held for another terminal. That is lost input.

Cause: if pending.isEmpty, awaited.isEmpty { events.removeAll() } (514770ead3c, 2026-10-18), written before keys had lanes: then a held key had no terminal of its own. With #29301's lanes, a key held for another terminal is that terminal's.

Fix: when nothing waits any more, drop only keys typed for no creation (lane nil: the same rule as before for them, never typed into whatever has the focus). A key with another terminal's lane stays, and goes to that terminal when the hold ends; the coordinator already ends the hold right after a cancel (drop(tab:in:) -> scheduleFlush).

Base: stacked on #29301's branch fix/p0-1193-key-lanes; after #29301 merges, the base moves to feat-cmux-next (no rebase).

Testing

Red-first, a unit test of the buffer: CreationInputHoldTests.closingAPendingSplitKeepsTheKeysHeldForAnotherTerminal (A's line held, A's reply came, B's split pending with its own key, B closed: A's key must stay).

RefWhat it isJobResult
65faf5dd0ea#29301's branch + the test only7178b4a892d4daa51ad1c8c0the new test fails on its outcome: take() == [] ("the line held for terminal A was dropped with the closed split of terminal B"); 5 others pass
7174f852a75 (this head)the fix30ac51b76972455d4c43236cCreationInputHoldTests 6 of 6, SecondCreationKeysTests 6 of 6 (no regression in #29301's tests)

Both ran as display steps (console session, CMUX_TEST_REQUIRE_GUI=1). Compiles: head f64555ec4856256a29d96199, red 1dcbb5e94e9160d935958e06.

Observed / Not run

Observed: the two runs above, logs read before counting.
Not run: an end-to-end test (Cmd-D twice, Cmd-W on the second split, then the first terminal's line arrives); the buffer test covers the rule, and the coordinator path after a cancel is unchanged.

Performance

No perf numbers: a correctness fix in a filter on held keys. perf claim: none.

Changelog

Fixed: Closing a new pane while it is still opening no longer drops what was typed for another pane

Proof

No capture: key routing inside the hold; the evidence is the fleet tests above.


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.


Summary by cubic

Fixes closing a pending split so keys typed for another terminal are no longer lost.

  • When no creation is pending, cancel(tab:) now only removes keys typed for no creation; keys held for a specific terminal stay and are delivered when that hold ends.
  • Adds a unit test covering the case where terminal A's line is held while terminal B's pending split is closed.