Skip to content

Keep the cursor in place when marking a thread seen - #523

Merged
dhh merged 4 commits into
mainfrom
tui-seen-keeps-cursor-in-place
Sep 29, 2026
Merged

dhh merged 4 commits into
mainfrom
tui-seen-keeps-cursor-in-place

Conversation

@dhh

@dhh dhh commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

Pressing e on a thread in New for You used to move the cursor down to Previously Seen with the thread, and the list scrolled after it. Working down New for You meant hunting back up for the next thread after every e.

  • The change: when the thread under the cursor is marked seen, it moves down to Previously Seen on its own. The cursor stays on the same row, so it lands on the thread that came next, and the window doesn't scroll. The change is in markSeen in internal/tui/content.go.
  • Last thread in New for You: the cursor moves on to the thread that followed it, not back onto the one just marked. With the Imbox cover down, that thread is hidden, so the cursor settles on the last visible thread as before.
  • Selections: marking several threads hands the cursor on through each, so it ends up on the first thread after them that wasn't marked.
  • Opening a thread marks it seen through the same path, so leaving the thread lands on the next one.
  • The window stays still: the re-sort used to scroll the window down after the marked thread, then snap it back with the next thread on the top row, so every row on screen moved. markSeen now restores the scroll position before placing the cursor.
  • Live re-reads: when a re-read drops the thread under the cursor (read or filed from another device), keepPlaceIn now keeps the cursor on the same row, on the thread that moved up into it. It used to jump to the top of the list. Three selection tests assumed that jump and hardcoded the top row's id; they now use whatever thread is under the cursor.
  • Already-seen threads: e on a thread already in Previously Seen moves nothing, so the cursor stays put too. Found in review: it used to step to the neighbouring thread.
  • Unchanged: a thread marked seen while the cursor is elsewhere leaves the cursor on its own thread. resort() still keeps the cursor on its posting.

TestContentListMovesSeenBubbledUpPostingToItsSection now expects the cursor to stay put. New tests cover staying on the row, keeping the window still in a list long enough to scroll, marking the last thread in New for You, and a re-read that drops the cursor's thread.

🤖 Generated with Claude Code

Copilot AI balanced review requested due to automatic review settings September 29, 2026 19:19
@dhh
dhh requested a review from a team as a code owner September 29, 2026 19:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

The window can still scroll when resort() follows the moved posting before selecting its successor.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

Updates Imbox seen-state navigation so the cursor advances to the next thread instead of following the moved thread.

Changes:

  • Tracks the adjacent posting when marking the cursor’s thread seen.
  • Adds cursor-position and scrolling tests.
  • One scrolling bug remains when resort() changes a nonzero offset.

[!TIP]
If you aren't ready for review, convert to a draft PR.
Click "Convert to draft" or run gh pr ready --undo.
Click "Ready for review" or run gh pr ready to reengage.

File Description
internal/​tui/​content.go Changes cursor behavior when marking threads seen.
internal/​tui/​tui_test.go Updates and extends seen-navigation tests.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread internal/tui/content.go
Comment on lines 351 to +355
func (c *contentList) markSeen(index int) {
var nextID int64
if index == c.cursor && !c.hideSeenState {
if index+1 < len(c.postings) {
nextID = c.postings[index+1].ID
dhh and others added 4 commits September 29, 2026 22:04
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Marking the cursor's thread seen re-sorted with the cursor still on it, so the
window scrolled down after it and then snapped back with the next thread on the
top row. A live re-read that dropped the cursor's thread sent the cursor to the
top of the list. Both now leave the window and the cursor's row where they were.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dhh
dhh force-pushed the tui-seen-keeps-cursor-in-place branch from f4cd9b0 to 0ceb56c Compare September 29, 2026 20:05
@dhh
dhh merged commit f79b634 into main Sep 29, 2026
25 checks passed
@dhh
dhh deleted the tui-seen-keeps-cursor-in-place branch September 29, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants