diff --git a/src/renderer/src/terminal/TerminalView.tsx b/src/renderer/src/terminal/TerminalView.tsx index 4fefe2c..00b6ae1 100644 --- a/src/renderer/src/terminal/TerminalView.tsx +++ b/src/renderer/src/terminal/TerminalView.tsx @@ -319,9 +319,23 @@ export const TerminalView: ForwardRefExoticComponent { + if (carryTimer !== undefined || !stream.hasPending()) return + carryTimer = window.setTimeout(() => { + carryTimer = undefined + if (deadRef.current) return + const rest = stream.flush() + if (rest) term.write(rest) + }, 16) + } const writeHighlighted = (data: string) => { const out = stream.push(data) if (out) term.write(out) + scheduleCarryFlush() } const disposables: { dispose(): void }[] = [ term.onData((data) => { @@ -375,6 +389,7 @@ export const TerminalView: ForwardRefExoticComponent { + if (carryTimer !== undefined) window.clearTimeout(carryTimer) for (const unsubscribe of unsubscribes) unsubscribe() for (const disposable of disposables) disposable.dispose() observer?.disconnect() diff --git a/src/renderer/src/terminal/highlightEngine.ts b/src/renderer/src/terminal/highlightEngine.ts index 768a84f..9907aa5 100644 --- a/src/renderer/src/terminal/highlightEngine.ts +++ b/src/renderer/src/terminal/highlightEngine.ts @@ -240,6 +240,11 @@ export class HighlightStream { this.rules = rules } + /** True while content is held back (a pending flush will release it). */ + hasPending(): boolean { + return this.buffer.length > 0 + } + /** Join held bytes with `chunk`, return content safe to hand to xterm. */ push(chunk: string): string { this.buffer += chunk