Skip to content

Commit

Permalink
Fix truncate of table cells containing ANSI
Browse files Browse the repository at this point in the history
Table cells (including the header) may contain ANSI codes. When
determining the width of these cells, ANSI was not excluded.

The `reflow` package has the same truncate function that is aware of
ANSI. This improves cell width calculation and correctly truncates.

Signed-off-by: Michael Lorant <[email protected]>
  • Loading branch information
mikelorant committed Feb 2, 2024
1 parent 92946d3 commit b81c89f
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 3 deletions.
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ retract v0.7.0 // v0.7.0 introduces a bug that causes some apps to freeze.
go 1.17

require (
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d
github.com/mattn/go-runewidth v0.0.15
github.com/muesli/reflow v0.3.0
github.com/muesli/termenv v0.15.2
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8=
github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
Expand Down
6 changes: 3 additions & 3 deletions table/table.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import (
"strings"

"github.com/charmbracelet/lipgloss"
"github.com/mattn/go-runewidth"
"github.com/muesli/reflow/truncate"
)

// StyleFunc is the style function that determines the style of a Cell.
Expand Down Expand Up @@ -437,7 +437,7 @@ func (t *Table) constructHeaders() string {
MaxHeight(1).
Width(t.widths[i]).
MaxWidth(t.widths[i]).
Render(runewidth.Truncate(header, t.widths[i], "…")))
Render(truncate.StringWithTail(header, uint(t.widths[i]), "…")))
if i < len(t.headers)-1 && t.borderColumn {
s.WriteString(t.borderStyle.Render(t.border.Left))
}
Expand Down Expand Up @@ -488,7 +488,7 @@ func (t *Table) constructRow(index int) string {
MaxHeight(height).
Width(t.widths[c]).
MaxWidth(t.widths[c]).
Render(runewidth.Truncate(cell, t.widths[c]*height, "…")))
Render(truncate.StringWithTail(cell, uint(t.widths[c]*height), "…")))

if c < t.data.Columns()-1 && t.borderColumn {
cells = append(cells, left)
Expand Down
48 changes: 48 additions & 0 deletions table/table_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package table
import (
"strings"
"testing"
"unicode"

"github.com/acarl005/stripansi"
"github.com/charmbracelet/lipgloss"
)

Expand Down Expand Up @@ -941,6 +943,52 @@ func TestFilterInverse(t *testing.T) {
}
}

func TestTableANSI(t *testing.T) {
const code = "\x1b[31mC\x1b[0m\x1b[32mo\x1b[0m\x1b[34md\x1b[0m\x1b[33me\x1b[0m"

rows := [][]string{
{"Apple", "Red", "\x1b[31m31\x1b[0m"},
{"Lime", "Green", "\x1b[32m32\x1b[0m"},
{"Banana", "Yellow", "\x1b[33m33\x1b[0m"},
{"Blueberry", "Blue", "\x1b[34m34\x1b[0m"},
}

table := New().
Width(29).
StyleFunc(TableStyle).
Border(lipgloss.NormalBorder()).
Headers("Fruit", "Color", code).
Rows(rows...)

expected := strings.TrimSpace(`
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”
β”‚ Fruit β”‚ Color β”‚ Code β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€
β”‚ Apple β”‚ Red β”‚ 31 β”‚
β”‚ Lime β”‚ Green β”‚ 32 β”‚
β”‚ Banana β”‚ Yellow β”‚ 33 β”‚
β”‚ Blueberry β”‚ Blue β”‚ 34 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”˜
`)

if stripString(table.String()) != expected {
t.Fatalf("expected:\n\n%s\n\ngot:\n\n%s", expected, stripString(table.String()))
}
}

func debug(s string) string {
return strings.ReplaceAll(s, " ", ".")
}

func stripString(str string) string {
s := stripansi.Strip(str)
ss := strings.Split(s, "\n")

var lines []string
for _, l := range ss {
trim := strings.TrimRightFunc(l, unicode.IsSpace)
lines = append(lines, trim)
}

return strings.Join(lines, "\n")
}

0 comments on commit b81c89f

Please sign in to comment.