Skip to content

feat: add Hunk-backed diff viewing - #7

Merged
gingerhendrix merged 4 commits into
mainfrom
feat/hunk-diff
Aug 11, 2026
Merged

feat: add Hunk-backed diff viewing#7
gingerhendrix merged 4 commits into
mainfrom
feat/hunk-diff

Conversation

@gingerhendrix

Copy link
Copy Markdown
Owner

Summary

  • add @tooee/diff with Hunk-backed stacked and split patch rendering
  • add a first-class diff subview for files, stdin, and --renderer diff
  • render unified diff and patch Markdown fences through Hunk
  • add a runnable Markdown diff showcase

Verification

  • bun run check
  • bun run lint:check
  • bun run format:check
  • bun run test
  • git diff --check 953dbf0..36d72f5

Release

Includes a Tegami minor release note for the shared Tooee package group.

Renderers that must be told their width — a Hunk diff block, say — had no way
to learn it: `CodeBlockRendererProps` carried the block's indent but not its
columns. `MarkdownView` now measures the terminal, subtracts the row-document
gutter and the scrollbar reserve, and passes each block the columns left inside
`CodeBlockChrome`. Flex-sized renderers can keep ignoring it.

Also exports `SourceIndex` so packages outside `@tooee/renderers` can build
source spans for their own row models.
Wraps Hunk's public OpenTUI primitives (`hunkdiff/opentui`, pinned exactly
because Hunk is pre-1.0) behind one package so no other Tooee package imports
it.

`buildDiffModel` parses unified patch text into navigation rows — one per file
header, one per `@@` hunk — each carrying its own patch text and its span in
the original patch, recovered by scanning the same text since Hunk exposes no
source positions. A hunk row hands Hunk a copy of its file narrowed to a single
hunk while keeping the whole-file line arrays, so line numbers and
collapsed-gap counts still resolve against the complete file. Files Hunk
renders without hunks (binary, too large, untracked) get one body row.

`DiffView` renders those rows into a `row-document`, which stays the only
scroll owner, so the cursor, search decorations, marks, scroll-follow and mouse
routing keep working over diff rows. `diffCodeBlockRenderer` draws ```diff and
```patch Markdown fences the same way, falling back to the default code block
when the fence body is not a real unified diff.

Known limits — per-hunk line-number column width, approximated themes, and
Hunk's install weight — are documented in the package README.
`.patch`/`.diff` files — and patch text sniffed from stdin or an unhelpful
extension — now open a first-class diff subview instead of plain text.
`DiffSubview` runs a document controller over the diff rows, so `j`/`k` step
hunk by hunk, search and copy work in real patch text, and the status bar shows
file count, totals, layout and the current file:hunk.

Commands: `s` toggles split/unified, `w` toggles wrapping, `]`/`[` jump
between files, `f` opens a fuzzy file picker, and `h`/`l` pan wide hunks. The
picker sets the cursor through `navigation.setCursor` rather than `selectRow`,
which stands down while the modal overlay that owns the picker is still open.

```diff and ```patch fences in Markdown render as diff blocks by default; a
host's own `codeBlockRenderers` entry still wins.
@gingerhendrix
gingerhendrix merged commit e0e8ce5 into main Aug 11, 2026
1 check passed
@gingerhendrix
gingerhendrix deleted the feat/hunk-diff branch August 11, 2026 17:30
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