diff --git a/internal/tui/components/chat/messages/renderer.go b/internal/tui/components/chat/messages/renderer.go index 11bb9f923456b6d16566d06951757e6be6ecbbf1..6bf3fbc3fa0c4fe6a6ba44d930bf3418696ea1d3 100644 --- a/internal/tui/components/chat/messages/renderer.go +++ b/internal/tui/components/chat/messages/renderer.go @@ -793,7 +793,10 @@ func escapeLine(t *styles.Theme, text string) string { n int w int ) - faint := t.S().Muted.Faint(true) + var faint lipgloss.Style + if t != nil { + faint = t.S().Muted.Faint(true) + } for len(text) > 0 { seq, w, n, state = ansi.DecodeSequence(text, state, nil) if w > 0 { diff --git a/internal/tui/components/chat/messages/renderer_test.go b/internal/tui/components/chat/messages/renderer_test.go new file mode 100644 index 0000000000000000000000000000000000000000..cc20ed711aa16ab1bd2ab8f462cd9ee33e58b005 --- /dev/null +++ b/internal/tui/components/chat/messages/renderer_test.go @@ -0,0 +1,52 @@ +package messages + +import ( + "testing" +) + +func TestEscapeContent(t *testing.T) { + cases := []struct { + name string + input string + expected string + }{ + { + name: "nothing to escape", + input: "Hello, World!", + expected: "Hello, World!", + }, + { + name: "escape csi sequences", + input: "\x1b[31mRed Text\x1b[0m", + expected: "\\x1b[31mRed Text\\x1b[0m", + }, + { + name: "escape control characters", + input: "Hello\x00World\x7f!", + expected: "Hello\\x00World\\x7f!", + }, + { + name: "escape csi sequences with control characters", + input: "\x1b[31mHello\x00World\x7f!\x1b[0m", + expected: "\\x1b[31mHello\\x00World\\x7f!\\x1b[0m", + }, + { + name: "just unicode", + input: "こんにちは", // "Hello" in Japanese + expected: "こんにちは", + }, + { + name: "unicode with csi sequences and control characters", + input: "\x1b[31mこんにちは\x00World\x7f!\x1b[0m", + expected: "\\x1b[31mこんにちは\\x00World\\x7f!\\x1b[0m", + }, + } + for i, c := range cases { + t.Run(c.name, func(t *testing.T) { + result := escapeContent(nil, c.input) + if result != c.expected { + t.Errorf("case %d, expected %q, got %q", i+1, c.expected, result) + } + }) + } +}