feat: better assistant message visual

This commit is contained in:
adamdotdevin
2025-08-05 19:00:08 -05:00
parent 030a3a7446
commit 6b25b7e95e
2 changed files with 32 additions and 76 deletions

View File

@@ -23,17 +23,18 @@ import (
) )
type blockRenderer struct { type blockRenderer struct {
textColor compat.AdaptiveColor textColor compat.AdaptiveColor
border bool backgroundColor compat.AdaptiveColor
borderColor *compat.AdaptiveColor border bool
borderLeft bool borderColor *compat.AdaptiveColor
borderRight bool borderLeft bool
paddingTop int borderRight bool
paddingBottom int paddingTop int
paddingLeft int paddingBottom int
paddingRight int paddingLeft int
marginTop int paddingRight int
marginBottom int marginTop int
marginBottom int
} }
type renderingOption func(*blockRenderer) type renderingOption func(*blockRenderer)
@@ -44,6 +45,12 @@ func WithTextColor(color compat.AdaptiveColor) renderingOption {
} }
} }
func WithBackgroundColor(color compat.AdaptiveColor) renderingOption {
return func(c *blockRenderer) {
c.backgroundColor = color
}
}
func WithNoBorder() renderingOption { func WithNoBorder() renderingOption {
return func(c *blockRenderer) { return func(c *blockRenderer) {
c.border = false c.border = false
@@ -132,14 +139,15 @@ func renderContentBlock(
) string { ) string {
t := theme.CurrentTheme() t := theme.CurrentTheme()
renderer := &blockRenderer{ renderer := &blockRenderer{
textColor: t.TextMuted(), textColor: t.TextMuted(),
border: true, backgroundColor: t.BackgroundPanel(),
borderLeft: true, border: true,
borderRight: false, borderLeft: true,
paddingTop: 1, borderRight: false,
paddingBottom: 1, paddingTop: 1,
paddingLeft: 2, paddingBottom: 1,
paddingRight: 2, paddingLeft: 2,
paddingRight: 2,
} }
for _, option := range options { for _, option := range options {
option(renderer) option(renderer)
@@ -152,7 +160,7 @@ func renderContentBlock(
style := styles.NewStyle(). style := styles.NewStyle().
Foreground(renderer.textColor). Foreground(renderer.textColor).
Background(t.BackgroundPanel()). Background(renderer.backgroundColor).
PaddingTop(renderer.paddingTop). PaddingTop(renderer.paddingTop).
PaddingBottom(renderer.paddingBottom). PaddingBottom(renderer.paddingBottom).
PaddingLeft(renderer.paddingLeft). PaddingLeft(renderer.paddingLeft).
@@ -211,7 +219,7 @@ func renderText(
switch casted := message.(type) { switch casted := message.(type) {
case opencode.AssistantMessage: case opencode.AssistantMessage:
ts = time.UnixMilli(int64(casted.Time.Created)) ts = time.UnixMilli(int64(casted.Time.Created))
content = util.ToMarkdown(text, width, backgroundColor) content = util.ToMarkdown(text, width+2, t.Background())
case opencode.UserMessage: case opencode.UserMessage:
ts = time.UnixMilli(int64(casted.Time.Created)) ts = time.UnixMilli(int64(casted.Time.Created))
base := styles.NewStyle().Foreground(t.Text()).Background(backgroundColor) base := styles.NewStyle().Foreground(t.Text()).Background(backgroundColor)
@@ -286,14 +294,14 @@ func renderText(
width, width,
WithTextColor(t.Text()), WithTextColor(t.Text()),
WithBorderColor(t.Secondary()), WithBorderColor(t.Secondary()),
WithBorderRight(),
) )
case opencode.AssistantMessage: case opencode.AssistantMessage:
return renderContentBlock( return renderContentBlock(
app, app,
content, content,
width, width+2,
WithBorderColor(t.Accent()), WithNoBorder(),
WithBackgroundColor(t.Background()),
) )
} }
return "" return ""

View File

@@ -1,52 +0,0 @@
package util
import (
"regexp"
"strings"
"github.com/charmbracelet/lipgloss/v2"
)
// PreventHyphenBreaks replaces regular hyphens with non-breaking hyphens to prevent
// sparse word breaks in hyphenated terms like "claude-code-action".
// This improves readability by keeping hyphenated words together.
// Only preserves hyphens within words, not markdown syntax like bullet points.
func PreventHyphenBreaks(text string) string {
// Use regex to match hyphens that are between word characters
// This preserves hyphens in words like "claude-code-action" but not in "- [ ]"
re := regexp.MustCompile(`(\w)-(\w)`)
return re.ReplaceAllString(text, "$1\u2011$2")
}
// RestoreHyphens converts non-breaking hyphens back to regular hyphens.
// This should be called after text processing (like word wrapping) is complete.
func RestoreHyphens(text string) string {
return strings.ReplaceAll(text, "\u2011", "-")
}
// ProcessTextWithHyphens applies hyphen preservation to text during processing.
// It wraps the provided processFunc with hyphen handling.
func ProcessTextWithHyphens(text string, processFunc func(string) string) string {
preserved := PreventHyphenBreaks(text)
processed := processFunc(preserved)
return RestoreHyphens(processed)
}
// GetMessageContainerFrame calculates the actual horizontal frame size
// (padding + borders) for message containers based on current theme.
func GetMessageContainerFrame() int {
style := lipgloss.NewStyle().
BorderStyle(lipgloss.ThickBorder()).
BorderLeft(true).
BorderRight(true).
PaddingLeft(2).
PaddingRight(2)
return style.GetHorizontalFrameSize()
}
// GetMarkdownContainerFrame calculates the actual horizontal frame size
// for markdown containers based on current theme.
func GetMarkdownContainerFrame() int {
// Markdown containers use the same styling as message containers
return GetMessageContainerFrame()
}