diff options
| -rw-r--r-- | go.mod | 4 | ||||
| -rw-r--r-- | go.sum | 2 | ||||
| -rw-r--r-- | internal/render/render.go | 25 |
3 files changed, 18 insertions, 13 deletions
@@ -4,8 +4,8 @@ go 1.24.1 require ( github.com/charmbracelet/bubbles v0.21.0 - github.com/charmbracelet/bubbletea v1.3.4 github.com/charmbracelet/lipgloss v1.1.0 + github.com/mattn/go-runewidth v0.0.16 github.com/pkg/sftp v1.13.9 github.com/rhogenson/deque v1.1.0 golang.org/x/crypto v0.37.0 @@ -14,6 +14,7 @@ require ( require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect + github.com/charmbracelet/bubbletea v1.3.4 // indirect github.com/charmbracelet/colorprofile v0.3.0 // indirect github.com/charmbracelet/harmonica v0.2.0 // indirect github.com/charmbracelet/x/ansi v0.8.0 // indirect @@ -24,7 +25,6 @@ require ( github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-localereader v0.0.1 // indirect - github.com/mattn/go-runewidth v0.0.16 // indirect github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/termenv v0.16.0 // indirect @@ -42,8 +42,6 @@ github.com/pkg/sftp v1.13.9 h1:4NGkvGudBL7GteO3m6qnaQ4pC0Kvf0onSVc9gR3EWBw= github.com/pkg/sftp v1.13.9/go.mod h1:OBN7bVXdstkFFN/gdnHPUb5TE8eb8G1Rp9wCItqjkkA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rhogenson/deque v1.0.1 h1:YWzJiImHBaITBHjQ6eXzc6v1oCTvk9r9vrHqjxB4aOk= -github.com/rhogenson/deque v1.0.1/go.mod h1:3JVW0+HcBcOClQtYlHhsyE5Q5cr/qG1jLEeC46prdtQ= github.com/rhogenson/deque v1.1.0 h1:3poepkqJjq3jp+s3eqQ/WTAtiX1hXOmpp+h8l2+PwFI= github.com/rhogenson/deque v1.1.0/go.mod h1:3JVW0+HcBcOClQtYlHhsyE5Q5cr/qG1jLEeC46prdtQ= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= diff --git a/internal/render/render.go b/internal/render/render.go index 18708f3..c43d2e8 100644 --- a/internal/render/render.go +++ b/internal/render/render.go @@ -6,7 +6,8 @@ import ( "bytes" "fmt" "os" - "unicode/utf8" + + runewidth "github.com/mattn/go-runewidth" ) // Renderer updates a terminal UI. Typical usage looks like @@ -46,9 +47,13 @@ func (r *Renderer) Clear(width int) { } func truncate(b []byte, width int) ([]byte, int) { - n := 0 + str := string(b) + currentWidth := 0 for i := 0; i < len(b); { - if bytes.HasPrefix(b[i:], []byte("\033[")) { + chunkBytes := bytes.Index(b[i:], []byte("\033[")) + if chunkBytes < 0 { + chunkBytes = len(b) - i + } else if chunkBytes == 0 { // An escape sequence usually starts with [, then has one or two numbers // separated by semicolon, and ends with some terminating character. To // try and munch the whole sequence, skip over any numbers and @@ -59,14 +64,16 @@ func truncate(b []byte, width int) ([]byte, int) { i++ continue } - if n+1 > width { - return b[:i], n + chunkWidth := runewidth.StringWidth(str[i : i+chunkBytes]) + if currentWidth+chunkWidth <= width { + i += chunkBytes + currentWidth += chunkWidth + continue } - _, runeWidth := utf8.DecodeRune(b[i:]) - i += runeWidth - n++ + lastChunk := runewidth.Truncate(str[i:i+chunkBytes], width-currentWidth, "") + return b[:i+len(lastChunk)], width } - return b, n + return b, currentWidth } // Write implements io.Writer. |
