fix: flush held text-run carry on a 16ms timer so shell prompts render immediately

The highlight stream holds a trailing text run for cross-chunk anchor
consistency; a bare shell prompt (plain text, no follow-up data) stayed
held until the next keypress. Now the carry auto-flushes within one frame.
This commit is contained in:
954801926@qq.com committed 2026-09-06 11:26:17 +08:00
1 parent 551723c2d4
commit db0eae5efd
2 files changed
+20

No files matched your search

@@ -319,9 +319,23 @@ export const TerminalView: ForwardRefExoticComponent<TerminalViewProps & { ref?:
// across a sessionId rebind (e.g. template apply).
const stream = new HighlightStream(compiledRules)
streamRef.current = stream
// The stream holds a trailing text run for cross-chunk anchor consistency.
// A shell prompt is exactly such a run with no follow-up data, so flush the
// carry on a short timer — prompts render within a frame, anchors survive.
let carryTimer: number | undefined
const scheduleCarryFlush = (): void => {
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<TerminalViewProps & { ref?:
}
return () => {
if (carryTimer !== undefined) window.clearTimeout(carryTimer)
for (const unsubscribe of unsubscribes) unsubscribe()
for (const disposable of disposables) disposable.dispose()
observer?.disconnect()
@@ -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