fix(tui): reassemble Windows key-burst pastes so repaste-to-expand works

On Windows, crossterm's console backend never emits Event::Paste: a
terminal paste arrives as a per-character key burst that the event loop
reassembles with timing heuristics. Three of its bounds split real
pastes into fragments:

- the 10 ms continue window is below one Windows scheduler quantum
  (~15.6 ms), so a routine mid-burst gap ended collection early;
- the 5000-event safety cap truncated any paste past ~5 KB;
- the 2 ms detection window missed bursts whose second chunk lagged,
  so collection never started.

Each fragment became its own synthetic paste. The paste chip then held
only the first fragment, and pasting again could never byte-equal the
chip content, so repaste-to-expand inserted a duplicate instead of
expanding — while macOS worked, because the unix parser buffers a
bracketed paste to the end marker and always delivers one whole event.

Widen the continue window past one quantum (25 ms), raise the cap above
any real paste (200k events), and skip the detection window entirely
when the batch already holds a >=8-key burst, which typing and
auto-repeat never produce. Unix paths are untouched: batches containing
a real Event::Paste never enter this reassembly.

Covered by a paused-clock test that trickles a burst tail with
one-quantum gaps and asserts it reassembles into a single paste.
This commit is contained in:
2026-07-24 12:41:26 -04:00
parent f5b9000c5d
commit 7ade135e76
2 changed files with 97 additions and 6 deletions
+2
View File
@@ -154,6 +154,8 @@ windows-sys = { version = "0.59", features = ["Win32_System_Console"] }
[dev-dependencies]
# Enable the render crate's test-only helpers for the pager's test build.
kigi-pager-render = { path = "../kigi-pager-render", features = ["test-support"] }
# `start_paused = true` for deterministic paste-reassembly timeout tests.
tokio = { workspace = true, features = ["test-util"] }
pretty_assertions = { workspace = true }
insta = { workspace = true }
criterion = { workspace = true }