From 713b21848778b8de138890b41180561000851ec1 Mon Sep 17 00:00:00 2001 From: Haofan Zhang Date: Fri, 22 May 2026 06:20:58 +0000 Subject: [PATCH 1/2] Fix infinite loop in textarea wordLeft navigation When navigating left in a textarea, if we encounter spaces at the very beginning of the input (col=0, row=0), the loop to skip spaces would run infinitely because characterLeft does nothing at the beginning and the cursor never advances. This PR adds a boundary check to break the loop if the cursor reaches col=0, row=0. --- textarea/textarea.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/textarea/textarea.go b/textarea/textarea.go index f0c0ca54..5d5da090 100644 --- a/textarea/textarea.go +++ b/textarea/textarea.go @@ -959,6 +959,9 @@ func (m *Model) wordLeft() { if m.col < len(m.value[m.row]) && !unicode.IsSpace(m.value[m.row][m.col]) { break } + if m.col == 0 && m.row == 0 { + break + } } for m.col > 0 { From a80ec511eb0214e08abe4c85b90db336514e0e3b Mon Sep 17 00:00:00 2001 From: Haofan Zhang Date: Fri, 22 May 2026 06:25:20 +0000 Subject: [PATCH 2/2] Add regression test for textarea wordLeft infinite loop This adds TestWordLeftInfiniteLoopRepro to textarea_test.go to verify the wordLeft boundary fix. --- textarea/textarea_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/textarea/textarea_test.go b/textarea/textarea_test.go index 41d51f74..c575a1b9 100644 --- a/textarea/textarea_test.go +++ b/textarea/textarea_test.go @@ -4,6 +4,7 @@ import ( "fmt" "strings" "testing" + "time" "unicode" tea "charm.land/bubbletea/v2" @@ -2429,3 +2430,24 @@ func stripString(str string) string { return strings.Join(lines, "\n") } + +func TestWordLeftInfiniteLoopRepro(t *testing.T) { + m := New() + m.SetValue(" hello") + m.col = 0 + m.row = 0 + + done := make(chan struct{}) + go func() { + m.wordLeft() + close(done) + }() + + select { + case <-done: + t.Log("wordLeft finished") + case <-time.After(2 * time.Second): + t.Fatal("wordLeft timed out (likely infinite loop)") + } +} +