mirror of
https://github.com/stablyai/orca.git
synced 2026-10-20 16:03:20 +00:00
Escape was suppressed whenever the terminal's derived composition flag was set. That flag is not the per-event `isComposing` bit — it is tracked from composition events, and compositionend is not guaranteed, so it can stand until the tracker's 10 s stale expiry. For up to that long, Escape never reached the PTY and vim could not leave insert mode, with no way to recover. An Escape the IME really owns arrives marked, by `isComposing` or by keyCode 229 / key 'Process', and those clauses still suppress it. An unmarked one only ever means the flag has drifted. Letting a drifted Escape through bounds recovery by keystrokes rather than by the expiry timer. Escape does not take the finalize-then-encode path the other keys take: our vendored xterm build gives it its own branch in `CompositionHelper.keydown` (:278-282), ahead of the `_finalizeComposition` fall-through. While xterm still believes a composition is in flight that branch cancels — discarding the preedit and returning false — and `CoreBrowserTerminal._keyDown` (:875-879) then returns before `evaluateKeyDown`, so no `\x1b` is written. The cancel clears xterm's `_isComposing` but not this tracker, so the next Escape passes through. Worst case is one extra keypress; when only the tracker drifted and xterm has already settled, the first Escape reaches the shell. The rest of the IME-owned set — arrows, Backspace, Delete, Enter, Home/End, PageUp/PageDown — is unchanged: those are candidate-window keys and forwarding them mid-composition is what the set exists to prevent. Co-authored-by: Orca <help@stably.ai>