Skip to content

Keep an opened message in place until you leave the reader - #106

Merged
allisonhere merged 2 commits into
mainfrom
fix/hold-read-position
Nov 9, 2026
Merged

allisonhere merged 2 commits into
mainfrom
fix/hold-read-position

Conversation

@allisonhere

Copy link
Copy Markdown
Owner

Problem

With Unread first on, opening an unread message marks it read (Mark read on open). When the server confirmed the read, the list re-sorted and the message dropped into the read block. The cursor followed it there by ID. Back in the list, you were at the bottom and had to scroll up to the unread messages to keep going. Unread only had the same jump: the message vanished from the list while you were reading it.

Change

  • While a message marked read on open is shown in the focused reader, it sorts as unread and stays listed under Unread only. Its row already shows as read.
  • When focus leaves the reader (Esc, Tab, clicking the list or sidebar) or another message opens, the hold ends. The message moves to its real place, and the cursor stays on the same row, which is now the next unread message.
  • A dialog opened over the reader (reply, help, palette) keeps the hold.
  • The read is sent and saved right away; only the list order waits.
  • Mark read on focus, x, and chronological order are unchanged.

Implementation

  • Model.heldReadID is set by openedMessageCmd when Unread first or Unread only is on.
  • sortsAsRead is used by the Unread only filter and by the conversation sort.
  • keepHeldUnreadPosition puts the held message back in the unread block by date, undoing the SQL read ASC placement.
  • Update wraps the existing handler (now handleUpdate) and calls releaseHeldRead once the reader no longer shows the held message with focus.

Tests

  • New held_read_test.go:
    • Unread first, both flat and threaded: the message stays in row 0 while open; after Esc it's first in the read block and the cursor is on the next unread message.
    • Unread only: the message stays listed while open and is gone after Esc.
    • Opening another message releases the hold.
    • With both settings off, nothing is held.
  • With the hold disabled, the Unread first and Unread only tests fail.
  • go test ./..., the race tests and go vet ./... pass.
  • Live on the test account with unread_first = true: I opened the top unread message, waited for the read to confirm, and checked it was still in row 1. After Esc the cursor was on the next unread message.

Docs

docs/guide.md covers this in two places: the message-ordering paragraph and "Pending read/unread changes". A CHANGELOG entry is under Unreleased → Changed. The help text, README, STATUS and keybindings.csv don't describe this ordering, and there are no new keys.

🤖 Generated with Claude Code

allisonhere and others added 2 commits November 9, 2026 07:53
With Unread first or Unread only on, a message marked read on open used to
re-sort into the read block (or drop out of the list) as soon as the server
confirmed, and the cursor followed it down. Now it keeps its unread
position while it is open in the focused reader. When focus leaves the
reader or another message opens, it moves to its place and the cursor
stays on the same row, which is now the next unread message.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@allisonhere
allisonhere merged commit b67a117 into main Nov 9, 2026
2 checks passed
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.

1 participant