Bug Description
When using a custom light theme on a terminal with a white/light background, text inside code blocks (especially those without a language annotation) is rendered as white text on a white background, making it completely invisible. This cannot be fixed through the theme JSON — the white color is hardcoded in the rendering layer.
Steps to Reproduce
- Use a terminal with a white/light background
- Create a custom theme with all dark foreground colors:
{
"theme": {
"text": "#383A42",
"markdownCodeBlock": "#383A42",
"syntaxComment": "#5F6169",
"syntaxKeyword": "#A626A4",
...
}
}
- Have the assistant generate a response containing a code block without a language annotation (bare
``` or indented text)
- The text inside the code block is rendered in white — invisible on the light background
Root Cause Analysis
After investigating the source code, we identified three contributing factors:
1. Hardcoded white default foreground in TextBufferRenderable
The default foreground color is hardcoded to white:
// TextBufferRenderable.ts
protected _defaultOptions = {
fg: RGBA.fromValues(1, 1, 1, 1), // WHITE
bg: RGBA.fromValues(0, 0, 0, 0), // transparent
...
}
2. createCodeRenderable() does not pass fg from the theme
When MarkdownRenderable creates a CodeRenderable for fenced code blocks, it passes syntaxStyle but not fg:
// Markdown.ts
private createCodeRenderable(token: Tokens.Code, id: string, marginBottom: number = 0): Renderable {
return new CodeRenderable(this.ctx, {
id,
content: token.text,
filetype: token.lang || undefined,
syntaxStyle: this._syntaxStyle, // syntax style IS passed
conceal: this._concealCode,
// ... NO fg prop!
})
}
This means the code block falls back to the hardcoded white default for any text not covered by syntax highlighting.
3. markdownCodeBlock theme property is unused
The markdownCodeBlock property is accepted in the theme JSON schema but is never mapped to any tree-sitter scope in getSyntaxRules() in theme.tsx. Setting it has no effect on rendering.
Combined effect
- For code blocks with a recognized language: the
"default" syntax scope (mapped to theme.text) colors unrecognized tokens correctly, but there may be a flash of white before highlighting completes
- For code blocks without a language annotation: the entire block renders in the hardcoded white default, with no way to override it via the theme
Suggested Fix
- Pass
fg to CodeRenderable: In createCodeRenderable(), pass fg from the theme's text color (or from the resolved "default" syntax rule)
- Map
markdownCodeBlock: Either use markdownCodeBlock as the fg for code block containers, or map it to the markup.raw.block scope in getSyntaxRules()
- Make the default foreground theme-aware: Consider changing
TextBufferRenderable's default fg from hardcoded white to theme.text
Environment
- OpenCode version: latest
- Terminal: white/light background
- OS: macOS
- Theme: custom light theme (One Light based)
Bug Description
When using a custom light theme on a terminal with a white/light background, text inside code blocks (especially those without a language annotation) is rendered as white text on a white background, making it completely invisible. This cannot be fixed through the theme JSON — the white color is hardcoded in the rendering layer.
Steps to Reproduce
{ "theme": { "text": "#383A42", "markdownCodeBlock": "#383A42", "syntaxComment": "#5F6169", "syntaxKeyword": "#A626A4", ... } }```or indented text)Root Cause Analysis
After investigating the source code, we identified three contributing factors:
1. Hardcoded white default foreground in
TextBufferRenderableThe default foreground color is hardcoded to white:
2.
createCodeRenderable()does not passfgfrom the themeWhen
MarkdownRenderablecreates aCodeRenderablefor fenced code blocks, it passessyntaxStylebut notfg:This means the code block falls back to the hardcoded white default for any text not covered by syntax highlighting.
3.
markdownCodeBlocktheme property is unusedThe
markdownCodeBlockproperty is accepted in the theme JSON schema but is never mapped to any tree-sitter scope ingetSyntaxRules()intheme.tsx. Setting it has no effect on rendering.Combined effect
"default"syntax scope (mapped totheme.text) colors unrecognized tokens correctly, but there may be a flash of white before highlighting completesSuggested Fix
fgtoCodeRenderable: IncreateCodeRenderable(), passfgfrom the theme'stextcolor (or from the resolved"default"syntax rule)markdownCodeBlock: Either usemarkdownCodeBlockas thefgfor code block containers, or map it to themarkup.raw.blockscope ingetSyntaxRules()TextBufferRenderable's defaultfgfrom hardcoded white totheme.textEnvironment