Skip to content

Fix textarea scrolling past end of content#105

Open
only-keval wants to merge 1 commit into
jesseduffield:masterfrom
only-keval:fix/textarea-scroll-backspace
Open

Fix textarea scrolling past end of content#105
only-keval wants to merge 1 commit into
jesseduffield:masterfrom
only-keval:fix/textarea-scroll-backspace

Conversation

@only-keval
Copy link
Copy Markdown

Fixes jesseduffield/lazygit#5633

Problem

When a textarea's content overflows the view and is then deleted or shortened, the view remains scrolled past the end of the content, showing blank space instead of snapping back to display the remaining content. This affects both horizontal scrolling in single-line textareas and vertical scrolling in multi-line textareas.

Root Cause

The updatedCursorAndOrigin() function only considered the cursor position when calculating the view's origin (scroll offset), not the actual content length. When content was deleted, the cursor position might still satisfy the scrolling condition (cursor > origin + usableSize mathematically), leaving the view scrolled even though no content existed in that region.

Additionally, when content ended with a newline, the blank line that should follow wasn't being rendered because the dimension calculation didn't account for it.

Solution

  1. Cache content dimensions: Added maxContentX and maxContentY fields to TextArea that are updated whenever cells are rebuilt. This provides O(1) access to content dimensions during rendering.

  2. Clamp origin to content bounds: Modified updatedCursorAndOrigin() to accept a contentLen parameter and ensure the origin never exceeds contentLen - usableSize. This prevents scrolling into blank space past the actual content.

  3. Account for trailing newlines: When content ends with a newline, increment the max Y dimension to account for the blank line that follows, ensuring proper rendering and cursor positioning.

Changes

  • TextArea: Added maxContentX, maxContentY caching with computeMaxDimensions() and GetContentDimensions()
  • updatedCursorAndOrigin(): Now takes content length parameter and clamps origin appropriately
  • RenderTextArea(): Passes content dimensions to updatedCursorAndOrigin()
  • Tests: Added comprehensive test cases covering content of various lengths, scrolling scenarios, and edge cases

Testing

  • All existing gocui tests pass
  • New test cases verify:
    • Content shorter than view (origin clamped to 0)
    • Content just longer than view
    • Content significantly longer than view
    • Origin clamping when content shrinks after scrolling
    • Cursor positioning at content end
    • Trailing newline rendering

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Input field keeps stale horizontal scroll offset after deletion

1 participant