opencode/run: refresh themes after terminal reloads (#30917)

This commit is contained in:
Simon Klee
2026-06-05 11:47:17 +02:00
committed by GitHub
parent b7d8c21f89
commit ce2e4ea4a9
12 changed files with 499 additions and 71 deletions
@@ -92,6 +92,7 @@ export class RunScrollbackStream {
private sessionID?: () => string | undefined
private treeSitterClient: TreeSitterClient | undefined
private wrote: boolean
private pendingThemes: RunTheme[] = []
constructor(
private renderer: CliRenderer,
@@ -101,12 +102,50 @@ export class RunScrollbackStream {
diffStyle?: RunDiffStyle
sessionID?: () => string | undefined
treeSitterClient?: TreeSitterClient
onThemeRelease?: (theme: RunTheme) => void
} = {},
) {
this.diffStyle = options.diffStyle
this.sessionID = options.sessionID
this.treeSitterClient = options.treeSitterClient ?? getTreeSitterClient()
this.wrote = options.wrote ?? false
this.onThemeRelease = options.onThemeRelease
}
private onThemeRelease: ((theme: RunTheme) => void) | undefined
private releasePendingThemes(): void {
if (this.pendingThemes.length === 0) {
return
}
for (const theme of this.pendingThemes.splice(0)) this.onThemeRelease?.(theme)
}
public setTheme(theme: RunTheme): void {
if (this.theme === theme) {
return
}
const previous = this.theme
this.theme = theme
const active = this.active
if (!active) {
this.onThemeRelease?.(previous)
return
}
this.pendingThemes.push(previous)
const style = entryLook(active.commit, theme.entry)
if (active.renderable instanceof TextRenderable) {
active.renderable.fg = style.fg
active.renderable.attributes = style.attrs ?? 0
return
}
active.renderable.fg = entryColor(active.commit, theme)
active.renderable.syntaxStyle = entrySyntax(active.commit, theme)
}
private createEntry(commit: StreamCommit, body: ActiveBody): ActiveEntry {
@@ -203,6 +242,7 @@ export class RunScrollbackStream {
const renderable = active.renderable
renderable.content = active.content
active.surface.render()
this.releasePendingThemes()
const targetRows = done ? active.surface.height : Math.max(active.committedRows, active.surface.height - 1)
if (targetRows <= active.committedRows) {
return false
@@ -226,6 +266,7 @@ export class RunScrollbackStream {
renderable.content = active.content
renderable.streaming = !done
await active.surface.settle()
this.releasePendingThemes()
const targetRows = done ? active.surface.height : Math.max(active.committedRows, active.surface.height - 1)
if (targetRows <= active.committedRows) {
return false
@@ -248,6 +289,7 @@ export class RunScrollbackStream {
renderable.content = active.content
renderable.streaming = !done
await active.surface.settle()
this.releasePendingThemes()
const targetBlockCount = done ? renderable._blockStates.length : renderable._stableBlockCount
if (targetBlockCount <= active.committedBlocks) {
return false
@@ -288,6 +330,7 @@ export class RunScrollbackStream {
if (!active.surface.isDestroyed) {
active.surface.destroy()
}
this.releasePendingThemes()
}
return active.rendered ? active.commit : undefined
@@ -368,6 +411,7 @@ export class RunScrollbackStream {
}
this.active = undefined
this.releasePendingThemes()
}
public async complete(trailingNewline = false): Promise<void> {
@@ -386,5 +430,6 @@ export class RunScrollbackStream {
public destroy(): void {
this.resetActive()
this.releasePendingThemes()
}
}