[PR #727] fix(stdin-buffer): handle split escape sequences #743

Open
opened 2026-03-02 23:47:55 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/727
Author: @yukukotani
Created: 2/22/2026
Status: 🔄 Open

Base: mainHead: delay-flash-esc


📝 Commits (2)

  • 48d195a fix(stdin-buffer): delay lone ESC flush to reassemble split focus sequences
  • 7519ea3 fix(stdin-buffer): extend flush delay to all incomplete escape sequences

📊 Changes

2 files changed (+176 additions, -6 deletions)

View changed files

📝 packages/core/src/lib/stdin-buffer.test.ts (+162 -5)
📝 packages/core/src/lib/stdin-buffer.ts (+14 -1)

📄 Description

Summary

  • Extend flush timeout for incomplete escape sequences so split focus sequences (e.g. ESC[I arriving as ESC then [I, or ESC[ then I) reassemble naturally
  • Uses existing isCompleteSequence() logic — no new fields or state management needed

Problem

Ghostty (and potentially other terminals) can deliver focus event sequences (ESC[I / ESC[O) split across multiple chunks. The StdinBuffer timeout (5ms) would flush the incomplete sequence before the rest arrived, causing fragments like [I to leak into the input as literal text.

Solution

When the timeout fires and the buffer contains an incomplete escape sequence (as determined by the existing isCompleteSequence()), extend the timeout once (50ms) to give the next chunk time to arrive and reassemble through the normal CSI completion logic.

Changes

  1. packages/core/src/lib/stdin-buffer.ts — 1-line condition change in the timeout handler: isCompleteSequence(this.buffer) === "incomplete" triggers a single timeout extension
  2. packages/core/src/lib/stdin-buffer.test.ts — Added 14 test cases for split focus sequences; updated 2 existing tests for new timeout behavior; added buffer cleanup in beforeEach

Testing

All existing tests pass:

  • stdin-buffer.test.ts (123 tests)
  • renderer.input.test.ts (60 tests)
  • renderer.focus-restore.test.ts (9 tests)
  • parse.keypress.test.ts (41 tests)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/anomalyco/opentui/pull/727 **Author:** [@yukukotani](https://github.com/yukukotani) **Created:** 2/22/2026 **Status:** 🔄 Open **Base:** `main` ← **Head:** `delay-flash-esc` --- ### 📝 Commits (2) - [`48d195a`](https://github.com/anomalyco/opentui/commit/48d195ab009f41f2da8ea439fad3125d57fe0f98) fix(stdin-buffer): delay lone ESC flush to reassemble split focus sequences - [`7519ea3`](https://github.com/anomalyco/opentui/commit/7519ea33e3ae83a81cb1a19670aed966b28636f8) fix(stdin-buffer): extend flush delay to all incomplete escape sequences ### 📊 Changes **2 files changed** (+176 additions, -6 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/src/lib/stdin-buffer.test.ts` (+162 -5) 📝 `packages/core/src/lib/stdin-buffer.ts` (+14 -1) </details> ### 📄 Description ## Summary - Extend flush timeout for incomplete escape sequences so split focus sequences (e.g. `ESC[I` arriving as `ESC` then `[I`, or `ESC[` then `I`) reassemble naturally - Uses existing `isCompleteSequence()` logic — no new fields or state management needed ## Problem Ghostty (and potentially other terminals) can deliver focus event sequences (`ESC[I` / `ESC[O`) split across multiple chunks. The `StdinBuffer` timeout (5ms) would flush the incomplete sequence before the rest arrived, causing fragments like `[I` to leak into the input as literal text. ## Solution When the timeout fires and the buffer contains an incomplete escape sequence (as determined by the existing `isCompleteSequence()`), extend the timeout once (50ms) to give the next chunk time to arrive and reassemble through the normal CSI completion logic. ## Changes 1. **`packages/core/src/lib/stdin-buffer.ts`** — 1-line condition change in the timeout handler: `isCompleteSequence(this.buffer) === "incomplete"` triggers a single timeout extension 2. **`packages/core/src/lib/stdin-buffer.test.ts`** — Added 14 test cases for split focus sequences; updated 2 existing tests for new timeout behavior; added buffer cleanup in `beforeEach` ## Testing All existing tests pass: - `stdin-buffer.test.ts` (123 tests) - `renderer.input.test.ts` (60 tests) - `renderer.focus-restore.test.ts` (9 tests) - `parse.keypress.test.ts` (41 tests) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#743
No description provided.