From 5a6fce1e41843efa669dc0aba28d542233cf1189 Mon Sep 17 00:00:00 2001 From: Dinakar Sarbada Date: Thu, 7 May 2026 18:11:39 -0700 Subject: [PATCH] fix: truncate table output by rune --- cmd/wacli/helpers.go | 10 +++++++--- cmd/wacli/messages_test.go | 11 +++++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/cmd/wacli/helpers.go b/cmd/wacli/helpers.go index 15a7c7b..38bb99a 100644 --- a/cmd/wacli/helpers.go +++ b/cmd/wacli/helpers.go @@ -38,13 +38,17 @@ func sanitize(s string) string { func truncate(s string, max int) string { s = sanitize(s) - if max <= 0 || len(s) <= max { + if max <= 0 { + return s + } + runes := []rune(s) + if len(runes) <= max { return s } if max <= 1 { - return s[:max] + return string(runes[:max]) } - return s[:max-1] + "…" + return string(runes[:max-1]) + "…" } func fullTableOutput(forceFull bool) bool { diff --git a/cmd/wacli/messages_test.go b/cmd/wacli/messages_test.go index 444288c..fa2c962 100644 --- a/cmd/wacli/messages_test.go +++ b/cmd/wacli/messages_test.go @@ -9,6 +9,7 @@ import ( "strings" "testing" "time" + "unicode/utf8" "github.com/spf13/cobra" "github.com/steipete/wacli/internal/store" @@ -35,6 +36,16 @@ func TestTruncate(t *testing.T) { } } +func TestTruncatePreservesUTF8(t *testing.T) { + got := truncate("🙂🙂🙂", 2) + if got != "🙂…" { + t.Fatalf("truncate emoji = %q, want first rune plus ellipsis", got) + } + if !utf8.ValidString(got) { + t.Fatalf("truncate produced invalid UTF-8: %q", got) + } +} + func TestTruncateForDisplay(t *testing.T) { const longID = "3EB0B0E8A1B2C3D4E5F6A7B8C9D0" if got := tableCell(longID, 14, true); got != longID {