From dbd982eba2a041d88d398cce01cb708c4c3503f7 Mon Sep 17 00:00:00 2001 From: Maas Lalani Date: Mon, 29 Apr 2024 12:32:21 -0400 Subject: [PATCH] Use `lipgloss.Width` to calculate `DisplayWidth` (#159) This accounts correctly for grapheme clusters that span multiple runes. --- go.mod | 4 +++- go.sum | 8 ++++++-- pkg/text/text.go | 4 ++-- pkg/text/text_test.go | 5 +++++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 0a51365..b5e74ca 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/AlecAivazis/survey/v2 v2.3.7 github.com/MakeNowJust/heredoc v1.0.0 github.com/charmbracelet/glamour v0.7.0 + github.com/charmbracelet/lipgloss v0.10.1-0.20240413172830-d0be07ea6b9c github.com/cli/browser v1.3.0 github.com/cli/safeexec v1.0.0 github.com/cli/shurcooL-graphql v0.0.4 @@ -17,7 +18,7 @@ require ( github.com/muesli/termenv v0.15.2 github.com/stretchr/testify v1.7.0 github.com/thlib/go-timezone-local v0.0.0-20210907160436-ef149e42d28e - golang.org/x/sys v0.18.0 + golang.org/x/sys v0.19.0 golang.org/x/term v0.13.0 golang.org/x/text v0.13.0 gopkg.in/h2non/gock.v1 v1.1.2 @@ -28,6 +29,7 @@ require ( github.com/alecthomas/chroma/v2 v2.8.0 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect + github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/dlclark/regexp2 v1.4.0 // indirect github.com/gorilla/css v1.0.0 // indirect diff --git a/go.sum b/go.sum index 858746d..81011e4 100644 --- a/go.sum +++ b/go.sum @@ -16,6 +16,10 @@ github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuP github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/charmbracelet/glamour v0.7.0 h1:2BtKGZ4iVJCDfMF229EzbeR1QRKLWztO9dMtjmqZSng= github.com/charmbracelet/glamour v0.7.0/go.mod h1:jUMh5MeihljJPQbJ/wf4ldw2+yBP59+ctV36jASy7ps= +github.com/charmbracelet/lipgloss v0.10.1-0.20240413172830-d0be07ea6b9c h1:0FwZb0wTiyalb8QQlILWyIuh3nF5wok6j9D9oUQwfQY= +github.com/charmbracelet/lipgloss v0.10.1-0.20240413172830-d0be07ea6b9c/go.mod h1:EPP2QJ0ectp3zo6gx9f8oJGq8keirqPJ3XpYEI8wrrs= +github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f h1:1BXkZqDueTOBECyDoFGRi0xMYgjJ6vvoPIkWyKOwzTc= +github.com/charmbracelet/x/exp/term v0.0.0-20240425164147-ba2a9512b05f/go.mod h1:yQqGHmheaQfkqiJWjklPHVAq1dKbk8uGbcoS/lcKCJ0= github.com/cli/browser v1.3.0 h1:LejqCrpWr+1pRqmEPDGnTZOjsMe7sehifLynZJuqJpo= github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEfBTk= github.com/cli/safeexec v1.0.0 h1:0VngyaIyqACHdcMNWfo6+KdUYnqEr2Sg+bSP1pdF+dI= @@ -115,8 +119,8 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= -golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= +golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek= diff --git a/pkg/text/text.go b/pkg/text/text.go index af4e979..687517f 100644 --- a/pkg/text/text.go +++ b/pkg/text/text.go @@ -8,7 +8,7 @@ import ( "time" "unicode" - "github.com/muesli/reflow/ansi" + "github.com/charmbracelet/lipgloss" "github.com/muesli/reflow/truncate" "golang.org/x/text/runes" "golang.org/x/text/transform" @@ -33,7 +33,7 @@ func Indent(s, indent string) string { // DisplayWidth calculates what the rendered width of string s will be. func DisplayWidth(s string) int { - return ansi.PrintableRuneWidth(s) + return lipgloss.Width(s) } // Truncate returns a copy of the string s that has been shortened to fit the maximum display width. diff --git a/pkg/text/text_test.go b/pkg/text/text_test.go index 4ce5112..37d0281 100644 --- a/pkg/text/text_test.go +++ b/pkg/text/text_test.go @@ -351,6 +351,11 @@ func TestDisplayWidth(t *testing.T) { text: `👍`, want: 2, }, + { + name: "multi-byte emoji", + text: `👨‍đŸ’ģ`, + want: 2, + }, { name: "accent character", text: `ÊĖĖ`,