Skip to content

fix: cursor placed at end of block on first downward navigation #163

@oobagi

Description

@oobagi

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

  • Add ta.CursorStart() after ta.SetValue() in newTextareaForBlock()
  • Verify all callers of newTextareaForBlock() expect cursor at start
  • Test with wrapped content: navigate down into block, verify cursor at start
  • Test round-trip: down into block → up → down again → verify same position

Test plan

  • Navigate down into a paragraph with wrapped content — cursor at start
  • Navigate up into a block — cursor at end (existing correct behavior)
  • First visit and subsequent visits produce identical cursor placement
  • Empty blocks, single-line blocks, and multi-line wrapped blocks all behave consistently

Scope

Type: bug
Size: small

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions