From 8b55efb2944ed8eb81df685f8dcfabbbf8897698 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Mon, 31 Mar 2025 19:55:03 -0300 Subject: [PATCH 1/2] fix(textarea): placeholder with chinese chars (#767) --- go.mod | 2 +- textarea/textarea.go | 6 ++++-- textarea/textarea_test.go | 22 ++++++++++++++++++++++ 3 files changed, 27 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index e316a0ac0..42d6dd94a 100644 --- a/go.mod +++ b/go.mod @@ -7,6 +7,7 @@ toolchain go1.23.7 require ( github.com/MakeNowJust/heredoc v1.0.0 github.com/atotto/clipboard v0.1.4 + github.com/aymanbagabas/go-udiff v0.2.0 github.com/charmbracelet/bubbletea v1.3.4 github.com/charmbracelet/harmonica v0.2.0 github.com/charmbracelet/lipgloss v1.1.0 @@ -22,7 +23,6 @@ require ( require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/aymanbagabas/go-udiff v0.2.0 // indirect github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect github.com/charmbracelet/x/term v0.2.1 // indirect diff --git a/textarea/textarea.go b/textarea/textarea.go index 620201cfc..d82ae971e 100644 --- a/textarea/textarea.go +++ b/textarea/textarea.go @@ -1271,11 +1271,13 @@ func (m Model) placeholderView() string { case i == 0: // first character of first line as cursor with character m.Cursor.TextStyle = m.style.computedPlaceholder() - m.Cursor.SetChar(string(plines[0][0])) + + ch, rest, _, _ := uniseg.FirstGraphemeClusterInString(plines[0], 0) + m.Cursor.SetChar(ch) s.WriteString(lineStyle.Render(m.Cursor.View())) // the rest of the first line - s.WriteString(lineStyle.Render(style.Render(plines[0][1:] + strings.Repeat(" ", max(0, m.width-uniseg.StringWidth(plines[0])))))) + s.WriteString(lineStyle.Render(style.Render(rest))) // remaining lines case len(plines) > i: // current line placeholder text diff --git a/textarea/textarea_test.go b/textarea/textarea_test.go index 9b272c5f7..ea3e3ccd0 100644 --- a/textarea/textarea_test.go +++ b/textarea/textarea_test.go @@ -6,6 +6,7 @@ import ( "unicode" "github.com/MakeNowJust/heredoc" + "github.com/aymanbagabas/go-udiff" tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" "github.com/charmbracelet/x/ansi" @@ -1671,6 +1672,26 @@ func TestView(t *testing.T) { `), }, }, + { + name: "placeholder chinese character", + modelFunc: func(m Model) Model { + m.Placeholder = "输入消息..." + m.ShowLineNumbers = true + m.SetWidth(20) + return m + }, + want: want{ + view: heredoc.Doc(` + > 1 输入消息... + > + > + > + > + > + + `), + }, + }, } for _, tt := range tests { @@ -1689,6 +1710,7 @@ func TestView(t *testing.T) { wantView := stripString(tt.want.view) if view != wantView { + t.Log(udiff.Unified("expected", "got", wantView, view)) t.Fatalf("Want:\n%v\nGot:\n%v\n", wantView, view) } From 693a7ca7d42191309d0fc08f1e4a02464bbb50b6 Mon Sep 17 00:00:00 2001 From: Kapparina <116474667+Kapparina@users.noreply.github.com> Date: Sat, 5 Apr 2025 20:49:03 +1100 Subject: [PATCH 2/2] feat(key): add `Equal` method to compare key bindings - Implement `Equal` method to check for equality of keys and help text. - Import `slices` package to simplify key comparison logic. --- key/key.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/key/key.go b/key/key.go index 0682665d3..2091f55f9 100644 --- a/key/key.go +++ b/key/key.go @@ -36,7 +36,10 @@ // to render help text for keystrokes in your views. package key -import "fmt" +import ( + "fmt" + "slices" +) // Binding describes a set of keybindings and, optionally, their associated // help text. @@ -80,6 +83,15 @@ func WithDisabled() BindingOpt { } } +func (b Binding) Equal(o Binding) bool { + keysEqual := slices.Equal(slices.Sorted(slices.Values(b.keys)), slices.Sorted(slices.Values(o.keys))) + helpsEqual := b.help == o.help + if keysEqual && helpsEqual { + return true + } + return false +} + // SetKeys sets the keys for the keybinding. func (b *Binding) SetKeys(keys ...string) { b.keys = keys