Problem
When first entering a note and scrolling down to a new block, the cursor is placed at the end of that block's content. When going back up and scrolling down again, the cursor is placed at the beginning. This inconsistency happens with wrapped content.
The behavior is not learnable — it changes based on invisible internal state (whether the textarea has been previously activated), so users cannot predict where the cursor will land.
Context
Root cause: newTextareaForBlock() in editor.go calls SetValue() on the textarea. Internally, SetValue() calls Reset() (cursor to 0,0) then InsertString(), which moves the cursor to the END of the inserted text. When navigateDown() subsequently calls CursorStart(), the command may not take effect before the first render due to Bubble Tea's command batching.
On re-activation (second visit), the textarea already exists with cursor at position 0 from the previous CursorStart() call, so it stays at the beginning.
Code path:
navigateDown() (editor.go:275-284): calls focusBlock() then CursorStart()
newTextareaForBlock() (editor.go:144-163): calls SetValue() which leaves cursor at end
focusBlock() (editor.go:250-262): handles focus transfer
Proposed approach
After SetValue() in newTextareaForBlock(), explicitly call m.CursorStart() to reset cursor to position 0. This ensures textareas always start with cursor at the beginning regardless of when they're first activated.
Verify no other code path depends on SetValue() leaving the cursor at the end (search for callers of newTextareaForBlock).
Tasks
Test plan
Scope
Type: bug
Size: small
Problem
When first entering a note and scrolling down to a new block, the cursor is placed at the end of that block's content. When going back up and scrolling down again, the cursor is placed at the beginning. This inconsistency happens with wrapped content.
The behavior is not learnable — it changes based on invisible internal state (whether the textarea has been previously activated), so users cannot predict where the cursor will land.
Context
Root cause:
newTextareaForBlock()ineditor.gocallsSetValue()on the textarea. Internally,SetValue()callsReset()(cursor to 0,0) thenInsertString(), which moves the cursor to the END of the inserted text. WhennavigateDown()subsequently callsCursorStart(), the command may not take effect before the first render due to Bubble Tea's command batching.On re-activation (second visit), the textarea already exists with cursor at position 0 from the previous
CursorStart()call, so it stays at the beginning.Code path:
navigateDown()(editor.go:275-284): callsfocusBlock()thenCursorStart()newTextareaForBlock()(editor.go:144-163): callsSetValue()which leaves cursor at endfocusBlock()(editor.go:250-262): handles focus transferProposed approach
After
SetValue()innewTextareaForBlock(), explicitly callm.CursorStart()to reset cursor to position 0. This ensures textareas always start with cursor at the beginning regardless of when they're first activated.Verify no other code path depends on
SetValue()leaving the cursor at the end (search for callers ofnewTextareaForBlock).Tasks
ta.CursorStart()afterta.SetValue()innewTextareaForBlock()newTextareaForBlock()expect cursor at startTest plan
Scope
Type: bug
Size: small