@@ -3,6 +3,7 @@ package messages
33import (
44 "encoding/json"
55 "fmt"
6+ "strconv"
67 "strings"
78 "time"
89
@@ -656,6 +657,7 @@ func joinHeaderBody(header, body string) string {
656657func renderPlainContent(v *toolCallCmp, content string) string {
657658 t := styles.CurrentTheme()
658659 content = strings.TrimSpace(content)
660+ content = escapeContent(t, content)
659661 lines := strings.Split(content, "\n")
660662
661663 width := v.textWidth() - 2 // -2 for left padding
@@ -694,6 +696,7 @@ func pad(v any, width int) string {
694696
695697func renderCodeContent(v *toolCallCmp, path, content string, offset int) string {
696698 t := styles.CurrentTheme()
699+ content = escapeContent(t, content)
697700 truncated := truncateHeight(content, responseContextHeight)
698701
699702 highlighted, _ := highlight.SyntaxHighlight(truncated, path, t.BgBase)
@@ -766,3 +769,41 @@ func prettifyToolName(name string) string {
766769 return name
767770 }
768771}
772+
773+// escapeContent escapes ANSI escape sequences and control characters in the
774+// content and styles it for display in the terminal.
775+func escapeContent(t *styles.Theme, content string) string {
776+ lines := strings.Split(content, "\n")
777+ for i, line := range lines {
778+ lines[i] = escapeLine(t, line)
779+ }
780+
781+ content = strings.Join(lines, "\n")
782+ return content
783+}
784+
785+// escapeLine escapes ANSI escape sequences and control characters and styles
786+// them for display in the terminal.
787+func escapeLine(t *styles.Theme, text string) string {
788+ var (
789+ sb strings.Builder
790+ state byte
791+ seq string
792+ n int
793+ w int
794+ )
795+ faint := ansi.NewStyle().Faint().ForegroundColor(t.FgMuted)
796+ for len(text) > 0 {
797+ seq, w, n, state = ansi.DecodeSequence(text, state, nil)
798+ if w > 0 {
799+ sb.WriteString(seq)
800+ } else {
801+ quote := strconv.Quote(seq)
802+ quote = strings.TrimPrefix(quote, "\"")
803+ quote = strings.TrimSuffix(quote, "\"")
804+ sb.WriteString(faint.Styled(quote))
805+ }
806+ text = text[n:]
807+ }
808+ return sb.String()
809+}