Merge pull request #532 from fluxlabs/fix/arrow-keys-escape-sequence-splitting-493
fix: prevent arrow keys from inserting escape sequences as text
This commit is contained in:
commit
946fce4ee6
3 changed files with 23 additions and 2 deletions
|
|
@ -730,8 +730,17 @@ export class Editor implements Component, Focusable {
|
|||
return;
|
||||
}
|
||||
|
||||
// Regular characters
|
||||
// Regular characters — reject partial escape sequence remnants that can
|
||||
// occur when event loop latency causes the StdinBuffer to split an escape
|
||||
// sequence (e.g. \x1b flushed as ESC, then "[D" arrives as text).
|
||||
if (data.charCodeAt(0) >= 32) {
|
||||
if (data[0] === "[" && data.length >= 2 && data.length <= 8) {
|
||||
const last = data[data.length - 1]!;
|
||||
// CSI navigation remnants: [A-F (arrows/home/end), [H, [Z (shift-tab), [<n>~ (func keys)
|
||||
if (/^[A-FHZ]$/.test(last) || last === "~") {
|
||||
return; // Drop CSI remnant (e.g. "[D", "[C", "[5~")
|
||||
}
|
||||
}
|
||||
this.insertCharacter(data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -112,7 +112,10 @@ export class ProcessTerminal implements Terminal {
|
|||
* to handle the case where the response arrives split across multiple events.
|
||||
*/
|
||||
private setupStdinBuffer(): void {
|
||||
this.stdinBuffer = new StdinBuffer({ timeout: 10 });
|
||||
// 50ms matches xterm's default escapeCodeTimeout and gives enough headroom
|
||||
// for escape sequences that arrive split across multiple stdin data events
|
||||
// (e.g. \x1b arriving separately from [D due to event loop latency).
|
||||
this.stdinBuffer = new StdinBuffer({ timeout: 50 });
|
||||
|
||||
// Kitty protocol response pattern: \x1b[?<flags>u
|
||||
const kittyResponsePattern = /^\x1b\[\?(\d+)u$/;
|
||||
|
|
|
|||
|
|
@ -137,6 +137,15 @@ migratePiCredentials(authStorage)
|
|||
// Run onboarding wizard on first launch (no LLM provider configured)
|
||||
if (!isPrintMode && shouldRunOnboarding(authStorage)) {
|
||||
await runOnboarding(authStorage)
|
||||
|
||||
// Clean up stdin state left by @clack/prompts.
|
||||
// readline.emitKeypressEvents() adds a permanent data listener and
|
||||
// readline.createInterface() may leave stdin paused. Remove stale
|
||||
// listeners and pause stdin so the TUI can start with a clean slate.
|
||||
process.stdin.removeAllListeners('data')
|
||||
process.stdin.removeAllListeners('keypress')
|
||||
if (process.stdin.setRawMode) process.stdin.setRawMode(false)
|
||||
process.stdin.pause()
|
||||
}
|
||||
|
||||
// Non-blocking update check — runs at most once per 24h, fire-and-forget
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue