[PR #8077] feat(opencode): enhanced markdown renderer with tables, themes, and syntax highlighting #12612

Closed
opened 2026-02-16 18:17:30 -05:00 by yindo · 0 comments
Owner

Original Pull Request: https://github.com/anomalyco/opencode/pull/8077

State: closed
Merged: No


Related Issues

Tables & Formatting:

  • Closes #3845 - Markdown tables display as plain text instead of formatted tables
  • Closes #7671 - Markdown table formatting
  • Closes #4988 - [FEATURE]: Support Table Rendering in Markdown Format
  • Closes #5675 - markdown user messages aren't formatted

Summary

Comprehensive markdown rendering overhaul for both CLI and TUI with proper table support, theme integration, syntax highlighting, and unified rendering architecture.

Key Features

📊 Table Rendering

  • Box-drawing borders - Unicode characters (┌─┬─┐) instead of ASCII pipes
  • Automatic column sizing - Proportional width distribution based on content
  • Word wrapping - Long content wraps within cells without breaking inline code
  • Backtick preservation - Never breaks `code` across lines
  • Inline markdown in cells - Bold, italic, code, links all work in table cells
  • Escaped pipes - Support for \| to show literal pipes (TypeScript union types: `number | undefined`)
  • Double-width character support - Proper alignment with Unicode/emoji

🎨 Theme Support

  • Unified theme system - CLI and TUI use identical colors from user's theme
  • 12+ built-in themes - opencode, dracula, nord, catppuccin, tokyo-night, etc.
  • Theme loader - Loads theme JSON files and converts to rendering format
  • Automatic detection - Reads from user config, no manual setup needed

💻 Syntax Highlighting

  • Tree-sitter integration - Uses OpenTUI's tree-sitter for code blocks
  • 10+ languages - JavaScript, TypeScript, Python, Go, Rust, Shell, etc.
  • Diff highlighting - Red/green colors for added/removed lines
  • Stable rendering - No flashing during streaming

🎯 Advanced Formatting

  • Inline markdown - **bold**, *italic*, `code`, links, strikethrough
  • Lists - Numbered and bulleted with colored markers
  • Blockquotes - Bar with proper formatting
  • Headers - Background color for h1/h2, bold for h3+
  • Horizontal rules - Clean separator lines

🏗️ Architecture

  • Unified rendering - Single source of truth (`renderMarkdownThemedStyled()`)
  • Code deduplication - CLI and TUI share rendering logic
  • TextChunk system - Universal format converted to ANSI (CLI) or StyledText (TUI)
  • Clean codebase - Removed 283 lines of dead legacy code (-18%)

🔧 Smart Behavior

  • TTY detection - Raw text when piped, formatted when interactive
  • Context-aware - GitHub bot doesn't load themes (no overhead for automation)
  • Streaming-friendly - No re-renders or flashing during message streaming

Technical Details

Files Changed

  • `markdown-renderer.ts` (new, 1297 lines) - Core rendering engine
  • `theme-loader.ts` (new, 98 lines) - Theme loading and conversion
  • `session/index.tsx` (+117 lines) - TUI integration with hybrid rendering
  • `run.ts` (+8 lines) - CLI theme integration
  • `ui.ts` (+5 lines) - Theme parameter support

Key Functions

  • `renderMarkdownThemedStyled()` - Main renderer, outputs TextChunks
  • `renderTableThemed()` - Table rendering with word wrap and inline markdown
  • `renderInlineThemed()` - Inline formatting (bold, italic, code, links)
  • `textChunksToAnsi()` - Converts TextChunks to ANSI for CLI
  • `loadTheme()` - Loads and converts theme JSON to rendering format

Rendering Flow

CLI:
```
User config → loadTheme() → MarkdownTheme
Markdown → renderMarkdownThemedStyled() → TextChunks
TextChunks → textChunksToAnsi() → ANSI string → stdout
```

TUI:
```
User config → Theme context → MarkdownTheme
Markdown → parseMarkdownSegments() → [text, code, text, code]
Text segments → renderMarkdownThemedStyled() → StyledText →
Code segments → tree-sitter →
```

Examples

Before/After: Tables

Before:
```
| Header | Value |
| A | B |
```

After:
```
┌────────┬───────┐
│ Header │ Value │
├────────┼───────┤
│ A │ B │
└────────┴───────┘
```

Theme Colors

All colors match user's selected theme:

  • Headers - Accent color with background
  • Code - Monospace with code color
  • Links - Link color + underline
  • Bold/Italic - Distinct from regular text
  • Borders - Border color from theme

Testing

✅ CLI output verified with multiple themes
✅ TUI rendering stable during streaming
✅ Tables with complex content (inline code, word wrap, unicode)
✅ Escaped pipes (\|) for union types
✅ Double-width characters (emoji, CJK)
✅ TTY detection (piped vs interactive)
✅ All 12+ built-in themes load correctly

Breaking Changes

None - backward compatible. Existing markdown rendering continues to work.

Performance

  • Minimal overhead - Only loads theme once per session
  • No flashing - Stable rendering during streaming
  • Smart caching - Theme colors resolved once
  • Efficient word wrap - Token-based wrapping preserves inline code

Migration Notes

No migration needed. The feature is automatically available in both CLI and TUI.

Commits

22 commits with iterative improvements:

  • Initial implementation
  • Stability fixes (flashing, streaming)
  • Feature additions (tables, themes, inline markdown)
  • Code cleanup (removed 283 lines of dead code)
  • Bug fixes (escaped pipes, unicode width)
  • Refactoring (unified architecture)
**Original Pull Request:** https://github.com/anomalyco/opencode/pull/8077 **State:** closed **Merged:** No --- ## Related Issues **Tables & Formatting:** - Closes #3845 - Markdown tables display as plain text instead of formatted tables - Closes #7671 - Markdown table formatting - Closes #4988 - [FEATURE]: Support Table Rendering in Markdown Format - Closes #5675 - markdown user messages aren't formatted ## Summary Comprehensive markdown rendering overhaul for both CLI and TUI with proper table support, theme integration, syntax highlighting, and unified rendering architecture. ## Key Features ### 📊 Table Rendering - ✅ **Box-drawing borders** - Unicode characters (┌─┬─┐) instead of ASCII pipes - ✅ **Automatic column sizing** - Proportional width distribution based on content - ✅ **Word wrapping** - Long content wraps within cells without breaking inline code - ✅ **Backtick preservation** - Never breaks \`code\` across lines - ✅ **Inline markdown in cells** - Bold, italic, code, links all work in table cells - ✅ **Escaped pipes** - Support for \\\| to show literal pipes (TypeScript union types: \`number | undefined\`) - ✅ **Double-width character support** - Proper alignment with Unicode/emoji ### 🎨 Theme Support - ✅ **Unified theme system** - CLI and TUI use identical colors from user's theme - ✅ **12+ built-in themes** - opencode, dracula, nord, catppuccin, tokyo-night, etc. - ✅ **Theme loader** - Loads theme JSON files and converts to rendering format - ✅ **Automatic detection** - Reads from user config, no manual setup needed ### 💻 Syntax Highlighting - ✅ **Tree-sitter integration** - Uses OpenTUI's tree-sitter for code blocks - ✅ **10+ languages** - JavaScript, TypeScript, Python, Go, Rust, Shell, etc. - ✅ **Diff highlighting** - Red/green colors for added/removed lines - ✅ **Stable rendering** - No flashing during streaming ### 🎯 Advanced Formatting - ✅ **Inline markdown** - \*\*bold\*\*, \*italic\*, \`code\`, [links](url), ~~strikethrough~~ - ✅ **Lists** - Numbered and bulleted with colored markers - ✅ **Blockquotes** - Bar with proper formatting - ✅ **Headers** - Background color for h1/h2, bold for h3+ - ✅ **Horizontal rules** - Clean separator lines ### 🏗️ Architecture - ✅ **Unified rendering** - Single source of truth (\`renderMarkdownThemedStyled()\`) - ✅ **Code deduplication** - CLI and TUI share rendering logic - ✅ **TextChunk system** - Universal format converted to ANSI (CLI) or StyledText (TUI) - ✅ **Clean codebase** - Removed 283 lines of dead legacy code (-18%) ### 🔧 Smart Behavior - ✅ **TTY detection** - Raw text when piped, formatted when interactive - ✅ **Context-aware** - GitHub bot doesn't load themes (no overhead for automation) - ✅ **Streaming-friendly** - No re-renders or flashing during message streaming ## Technical Details ### Files Changed - **\`markdown-renderer.ts\`** (new, 1297 lines) - Core rendering engine - **\`theme-loader.ts\`** (new, 98 lines) - Theme loading and conversion - **\`session/index.tsx\`** (+117 lines) - TUI integration with hybrid rendering - **\`run.ts\`** (+8 lines) - CLI theme integration - **\`ui.ts\`** (+5 lines) - Theme parameter support ### Key Functions - \`renderMarkdownThemedStyled()\` - Main renderer, outputs TextChunks - \`renderTableThemed()\` - Table rendering with word wrap and inline markdown - \`renderInlineThemed()\` - Inline formatting (bold, italic, code, links) - \`textChunksToAnsi()\` - Converts TextChunks to ANSI for CLI - \`loadTheme()\` - Loads and converts theme JSON to rendering format ### Rendering Flow **CLI:** \`\`\` User config → loadTheme() → MarkdownTheme Markdown → renderMarkdownThemedStyled() → TextChunks TextChunks → textChunksToAnsi() → ANSI string → stdout \`\`\` **TUI:** \`\`\` User config → Theme context → MarkdownTheme Markdown → parseMarkdownSegments() → [text, code, text, code] Text segments → renderMarkdownThemedStyled() → StyledText → <text> Code segments → tree-sitter → <code> \`\`\` ## Examples ### Before/After: Tables **Before:** \`\`\` | Header | Value | | A | B | \`\`\` **After:** \`\`\` ┌────────┬───────┐ │ Header │ Value │ ├────────┼───────┤ │ A │ B │ └────────┴───────┘ \`\`\` ### Theme Colors All colors match user's selected theme: - **Headers** - Accent color with background - **Code** - Monospace with code color - **Links** - Link color + underline - **Bold/Italic** - Distinct from regular text - **Borders** - Border color from theme ## Testing ✅ CLI output verified with multiple themes ✅ TUI rendering stable during streaming ✅ Tables with complex content (inline code, word wrap, unicode) ✅ Escaped pipes (\\\|) for union types ✅ Double-width characters (emoji, CJK) ✅ TTY detection (piped vs interactive) ✅ All 12+ built-in themes load correctly ## Breaking Changes None - backward compatible. Existing markdown rendering continues to work. ## Performance - **Minimal overhead** - Only loads theme once per session - **No flashing** - Stable rendering during streaming - **Smart caching** - Theme colors resolved once - **Efficient word wrap** - Token-based wrapping preserves inline code ## Migration Notes No migration needed. The feature is automatically available in both CLI and TUI. ## Commits 22 commits with iterative improvements: - Initial implementation - Stability fixes (flashing, streaming) - Feature additions (tables, themes, inline markdown) - Code cleanup (removed 283 lines of dead code) - Bug fixes (escaped pipes, unicode width) - Refactoring (unified architecture)
yindo added the pull-request label 2026-02-16 18:17:30 -05:00
yindo closed this issue 2026-02-16 18:17:30 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: anomalyco/opencode#12612