refactor: move ansi escape function to the ansiext package

This commit is contained in:
Andrey Nering
2025-07-23 14:36:04 -03:00
parent e7f29adce9
commit 63efed61ac
2 changed files with 27 additions and 19 deletions

24
internal/ansiext/ansi.go Normal file
View File

@@ -0,0 +1,24 @@
package ansiext
import (
"strings"
"github.com/charmbracelet/x/ansi"
)
// Escape replaces control characters with their Unicode Control Picture
// representations to ensure they are displayed correctly in the UI.
func Escape(content string) string {
var sb strings.Builder
for _, r := range content {
switch {
case r >= 0 && r <= 0x1f: // Control characters 0x00-0x1F
sb.WriteRune('\u2400' + r)
case r == ansi.DEL:
sb.WriteRune('\u2421')
default:
sb.WriteRune(r)
}
}
return sb.String()
}

View File

@@ -6,6 +6,7 @@ import (
"strings"
"time"
"github.com/charmbracelet/crush/internal/ansiext"
"github.com/charmbracelet/crush/internal/fsext"
"github.com/charmbracelet/crush/internal/llm/agent"
"github.com/charmbracelet/crush/internal/llm/tools"
@@ -702,7 +703,7 @@ func renderPlainContent(v *toolCallCmp, content string) string {
if i >= responseContextHeight {
break
}
ln = escapeContent(ln)
ln = ansiext.Escape(ln)
ln = " " + ln // left padding
if len(ln) > width {
ln = v.fit(ln, width)
@@ -740,7 +741,7 @@ func renderCodeContent(v *toolCallCmp, path, content string, offset int) string
lines := strings.Split(truncated, "\n")
for i, ln := range lines {
lines[i] = escapeContent(ln)
lines[i] = ansiext.Escape(ln)
}
highlighted, _ := highlight.SyntaxHighlight(strings.Join(lines, "\n"), path, t.BgBase)
@@ -816,20 +817,3 @@ func prettifyToolName(name string) string {
return name
}
}
// escapeContent replaces control characters with their Unicode Control Picture
// representations to ensure they are displayed correctly in the UI.
func escapeContent(content string) string {
var sb strings.Builder
for _, r := range content {
switch {
case r >= 0 && r <= 0x1f: // Control characters 0x00-0x1F
sb.WriteRune('\u2400' + r)
case r == ansi.DEL:
sb.WriteRune('\u2421')
default:
sb.WriteRune(r)
}
}
return sb.String()
}