Skip to content

EXC-1936 Mark files viewed in the sidebar - #39

Merged
macintacos merged 12 commits into
mainfrom
EXC-1936/mark-files-viewed
Oct 11, 2026
Merged

macintacos merged 12 commits into
mainfrom
EXC-1936/mark-files-viewed

Conversation

@macintacos

@macintacos macintacos commented Oct 11, 2026 •

Copy link
Copy Markdown
Owner

Part of: EXC-1936

Change Kind: new feature

What changed

A reviewer can now mark a file viewed in the sidebar with x, as with GitHub's "Viewed" checkbox, and the file steps back. Its rows take a faint grey wash (ChangesetViewed), its icon becomes a grey ✔ (ChangesetViewedIcon), its row says viewed beside the stat, and it folds in every section it shows in. The cursor moves on to the next file not yet viewed, and the file's buffer drops changeset's unified diff, so it goes back to gitsigns' own signs. X marks every file viewed at once, or clears every mark once all are viewed.

Each mark is saved in stdpath("state")/changeset/viewed.json against a fingerprint of the file's diff, so it survives a restart and stops holding once that diff changes. The diff and the tint then come back, and they go again if the change is reverted. To get the fingerprint, each changed file now carries a sha256 digest of its patch. That digest also gives a file whose line is rewritten at the same counts a new identity, so its row redraws.

It also fixes an older bug that marking exposed. When a sidebar preview swapped another file into a window, gitsigns kept the first file's unified view while changeset forgot it, so the view came back without changeset's cover and nothing could close it. It now closes as the preview swaps it away.

What to test

  • Press x on a file row. The file's rows take a grey wash, its icon becomes ✔, the row says viewed, the file folds, and the cursor moves to the next file not yet viewed and previews it.
  • Press x on a symbol row and the file is marked. Press x on a viewed file to unfold it and bring its icon back.
  • Press X: every file is marked and folds. Press X again: every mark clears and the files unfold.
  • With 'mousemoveevent' on, move the pointer across a viewed file's rows: the ChangesetHover tint shows over the grey wash.
  • Open a viewed file. It shows no unified diff. Edit a line the branch already changed and write it: the mark clears, the diff comes back, and other files stay marked.
  • Restart Neovim and reopen the sidebar. The marks are still there and the viewed files start folded. A viewed file opened with l stays open.
  • A binary file edited in place keeps its mark. This is a known ceiling, marked ponytail: in diff.lua.

@linear-code

linear-code Bot commented Oct 11, 2026

Copy link
Copy Markdown

EXC-1936

- Give each File a digest: the sha256 of its section of the hunks
  diff (now run with --full-index), of an untracked file's content,
  or of its status and old path when the patch has no text.
- Add digest to FILE_FIELDS, so rewriting a changed line at the same
  counts gives the file a new identity.
- `v` (keymaps.toggle_viewed) marks the file under the cursor viewed,
  or clears its mark, from its file row or any row under it.
- A viewed file draws ✔ in ChangesetViewed (linked to Comment) in its
  icon's place.
- Marks live in stdpath("state")/changeset/viewed.json by repository
  root and path, each against the digest of the diff it was viewed
  at, so a mark stops showing once that diff changes.
- Document `v` / keymaps.toggle_viewed, ChangesetViewed and
  viewed.json in the vimdoc, and the key in the README.
- Record in design.md why a viewed file wears a check in its icon's
  place, and why a mark holds by digest rather than File identity.
- Cover loading marks from an earlier session and the untracked
  file's digest with specs.
- Build resolve_spec's File literals through one helper, and wait for
  the diff with Sidebar.await_diff.
- Move the viewed-icon policy out of draw.draw, and expose
  viewed.apply only to specs as viewed._apply.
- Say when another Neovim's marks show, and fix design.md's colour
  rationale, the vimdoc's row names and ChangesetViewed's place.
Rename keyed, section and close to section_path, section_lines and
digest_section, so the digest step reads as what it does.
- The toggle key moves to `x`.
- A viewed file's rows take a faint grey wash (`ChangesetViewed`,
  now background-only), drawn under the row-state tints; its check
  moves to `ChangesetViewedIcon`.
- Its row is labelled `viewed` beside the stat.
- Marking folds every copy of the file, once per digest: a restart
  starts it folded, and an unfold sticks. Unmarking unfolds it.
- Marking moves the cursor to the next file not yet viewed.
- While a file's viewed mark holds, the unified diff doesn't reach
  it: marking closes its views in every window, so the buffer is
  back to gitsigns' own signs, and none opens again.
- Unmarking, or the file's diff changing, reopens them; changing it
  back to the viewed diff closes them again.
- One `reaches` predicate replaces each `reach:allows` call, so
  every path that opens or covers a view asks the same question.
- The viewed key is `x` in the vimdoc tags, the README's key table
  and its `setup()` block.
- The key's entry lists the wash, the check, the label, the fold,
  the cursor moving on and the unified diff closing.
  `ChangesetViewed` is the row wash; `ChangesetViewedIcon` is new.
- design.md gives the reasons, and records the per-session fold
  digest beside the folds.
- `X` (`keymaps.toggle_viewed_all`) marks every file the tree lists
  viewed, or clears every mark when all already are, in one write.
- `x` and `X` share the step that shows new marks: the error on a
  failed write, the unified diff refresh, the fold or unfold, and
  the cursor's move.
- The vimdoc tags `X` and `keymaps.toggle_viewed_all`, and says
  what it covers and where the cursor goes.
- The README's key table and `setup()` block list it.
- design.md says why one key both finishes and restarts a review.
A preview swaps the buffer in a window without `BufWinLeave`, so
gitsigns kept changeset's view there while `sync` forgot it. When
the file came back, gitsigns handed the view back, and changeset
took it for the user's own: no cover, and `x`/`X` couldn't close
it, which left the diff half off. `sync` now closes that stale view
as it lets go of it.
Main's ChangesetHover and the viewed wash both drew one step below
the state tints. The wash now sits one step lower still, so the
pointer's tint shows across a viewed file's rows; the vimdoc and
design.md name it among the tints the wash draws under.
@macintacos
macintacos force-pushed the EXC-1936/mark-files-viewed branch from 163477a to df56f9a Compare October 11, 2026 21:12
@macintacos
macintacos merged commit 30641df into main Oct 11, 2026
2 checks passed
@macintacos
macintacos deleted the EXC-1936/mark-files-viewed branch October 11, 2026 21:51
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