Skip to content

Commit 0147dbc

Browse files
committed
fix(textinput): account for horizontal scroll offset in Cursor()
1 parent 492ed7d commit 0147dbc

2 files changed

Lines changed: 36 additions & 2 deletions

File tree

textinput/textinput.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -921,8 +921,9 @@ func (m Model) Cursor() *tea.Cursor {
921921
w := lipgloss.Width
922922

923923
promptWidth := w(m.promptView())
924-
xOffset := m.Position() +
925-
promptWidth
924+
// Like View, use the scroll-adjusted column (pos-offset) so the cursor
925+
// tracks the visible position when the value overflows the width.
926+
xOffset := max(0, m.pos-m.offset) + promptWidth
926927
if m.width > 0 {
927928
xOffset = min(xOffset, m.width+promptWidth)
928929
}

textinput/textinput_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88

99
tea "charm.land/bubbletea/v2"
10+
"charm.land/lipgloss/v2"
1011
)
1112

1213
func Test_CurrentSuggestion(t *testing.T) {
@@ -118,3 +119,35 @@ func sendString(m Model, str string) Model {
118119

119120
return m
120121
}
122+
123+
// See #1001: Cursor() must use the scroll-adjusted column (pos-offset) like View().
124+
func TestCursorXAccountsForScrollOffset(t *testing.T) {
125+
m := New()
126+
m.Focus()
127+
m.SetVirtualCursor(false)
128+
m.CharLimit = 200
129+
m.SetWidth(20)
130+
m.SetValue(strings.Repeat("a", 30))
131+
132+
// Scroll to the end, then move into the middle of the viewport, where the
133+
// width clamp doesn't mask the wrong column.
134+
m.CursorEnd()
135+
m.SetCursor(25)
136+
137+
if m.offset == 0 {
138+
t.Fatalf("test setup: expected a non-zero scroll offset for an overflowing input, got 0")
139+
}
140+
141+
cur := m.Cursor()
142+
if cur == nil {
143+
t.Fatal("Cursor() returned nil")
144+
}
145+
146+
promptWidth := lipgloss.Width(m.promptView())
147+
want := promptWidth + (m.pos - m.offset)
148+
if cur.X != want {
149+
t.Errorf("Cursor().X = %d, want %d (promptWidth=%d, pos=%d, offset=%d); "+
150+
"Cursor() must use the scroll-adjusted column (pos-offset) like View(), not the absolute Position()",
151+
cur.X, want, promptWidth, m.pos, m.offset)
152+
}
153+
}

0 commit comments

Comments
 (0)