@@ -101,3 +101,55 @@ func TestBackspaceCursorPosition(t *testing.T) {
101101 assert .Equal (t , "CCC" , lines [2 ])
102102 })
103103}
104+
105+ func TestBackspaceOnSoftWrappedLine (t * testing.T ) {
106+ t .Parallel ()
107+
108+ t .Run ("backspace after newline on soft-wrapped text" , func (t * testing.T ) {
109+ t .Parallel ()
110+
111+ ta := textarea .New ()
112+ ta .SetWidth (20 ) // Small width to force wrapping
113+ ta .SetHeight (10 )
114+ ta .Focus ()
115+
116+ e := & editor {
117+ textarea : ta ,
118+ userTyped : true ,
119+ }
120+
121+ // Enter text that overflows to line 2 (soft-wraps)
122+ longText := "this is a long text that wraps"
123+ e .textarea .SetValue (longText )
124+ e .textarea .MoveToEnd ()
125+
126+ t .Logf ("After long text - Line: %d, LineInfo: %+v, Value: %q" ,
127+ e .textarea .Line (), e .textarea .LineInfo (), e .textarea .Value ())
128+
129+ // Press shift+enter to add a newline (simulated by directly adding \n)
130+ e .textarea .InsertString ("\n " )
131+
132+ t .Logf ("After newline - Line: %d, LineInfo: %+v, Value: %q" ,
133+ e .textarea .Line (), e .textarea .LineInfo (), e .textarea .Value ())
134+
135+ // Type a few characters
136+ e .textarea .InsertString ("abc" )
137+
138+ t .Logf ("After typing abc - Line: %d, LineInfo: %+v, Value: %q" ,
139+ e .textarea .Line (), e .textarea .LineInfo (), e .textarea .Value ())
140+
141+ // Now backspace
142+ _ , _ = e .handleGraphemeBackspace ()
143+
144+ value := e .textarea .Value ()
145+ t .Logf ("After backspace - Line: %d, LineInfo: %+v, Value: %q" ,
146+ e .textarea .Line (), e .textarea .LineInfo (), value )
147+
148+ // The value should be the long text + newline + "ab"
149+ expectedValue := longText + "\n ab"
150+ assert .Equal (t , expectedValue , value , "value should have one char removed" )
151+
152+ // Cursor should still be on logical line 1 (the line after the newline)
153+ assert .Equal (t , 1 , e .textarea .Line (), "cursor should stay on line 1" )
154+ })
155+ }
0 commit comments