Skip to content

fix(files): real diff viewer for the changes view#3013

Merged
Vaibhaav-Tiwari merged 14 commits into
mainfrom
fix/diff-changes-view-ui
Jul 23, 2026
Merged

fix(files): real diff viewer for the changes view#3013
Vaibhaav-Tiwari merged 14 commits into
mainfrom
fix/diff-changes-view-ui

Conversation

@codebanditssss

@codebanditssss codebanditssss commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

Summary

Overhauls the session Files / changes view (SessionFilesView). It used to print the raw git diff output line-for-line with a sequential 1..N counter, showed the whole file for tiny changes, and had a cluttered header that overflowed in the narrow inspector rail. This turns it into a real diff viewer.

Now

image

What changed

Core fixes

  • Focused diff — the backend built the diff with git diff --unified=80, so any file under ~160 lines rendered in full even for a one-line change. Dropped to the standard --unified=3, so a change shows only the changed lines plus a little context.
  • Real diff rendering — hides the git file-header noise (diff --git, index, ---, +++, mode/rename lines), shows a real old# / new# gutter instead of the bogus sequential counter, and renders @@ hunks as their own band with the marker in a gutter column. Line endings are normalized (\r\n, lone \r, \n) so it behaves identically on macOS, Windows, and Linux.
  • Decluttered, responsive header — removed the redundant "Files" label (the tab already says Files), the file count text, and the +/- summary; the search collapses to an icon and the actions are icon-only, so the header fits at any rail width.

Enhancements

  • Hunk section context — shows the enclosing function/section from each hunk header.
  • Intra-line word highlighting — for a line-for-line replacement, token-diffs each pair (LCS over word tokens) and highlights only the characters that changed.
  • Side-by-side split view toggle (deletions left, additions right, context both sides).
  • Word-wrap toggle for long lines.
  • Copy-path action on each file row (hover-revealed).
  • j / k keyboard navigation between file rows.

Scope

Frontend-only except the one-word backend context change; the backend already returns the raw unified diff string, which is now parsed and rendered client-side.

Not included (follow-ups)

  • Syntax highlighting (needs a shiki/prism dependency + CSP review).
  • Binary/image preview (needs a backend raw-bytes endpoint; the API only returns text content today).
  • Expandable "show hidden lines between hunks" folds (larger; --unified=3 already keeps diffs focused).
  • Renamed-file old→new path (backend doesn't expose the old path).

Tests

  • SessionFilesView.test.tsx: 11 tests including realistic-diff + CRLF parsing, intra-line highlight, split-view toggle, wrap toggle, copy-path, and j/k focus movement.
  • cd frontend && npx tsc --noEmit clean; go build ./... clean.

The changes view printed the raw `git diff` output line-for-line and
numbered every physical line 1..N, so the git file headers showed as
content and "line 1" was the `diff --git` header rather than file line 1.

Parse the unified diff into typed rows: hide the git file-header noise
(`diff --git`, `index`, `---`, `+++`, mode/rename lines), keep hunk
headers as their own row, and render a two-column old#/new# gutter with
the +/- marker in its own column. Line endings are normalized (\r\n and
lone \r as well as \n) so numbering and marker detection behave the same
on macOS, Windows, and Linux.
The changes view stacked a "Files · N files changed" bar directly above a
second "Review" heading. Remove the redundant heading, fold the
Expand/Collapse-all control up into the top bar, and show an overall
+adds / -dels summary next to the file count so the totals are visible
without expanding anything.
Each expanded diff had its own horizontal scrollbar for long lines. Add a
wrap toggle in the header that switches the diff body between horizontal
scroll and soft-wrapped lines. Also separate the old#/new# line-number
gutter from the content with a hairline divider so the numbers read as a
gutter rather than floating in the code.
The workspace file diff was generated with `git diff --unified=80`, so any
file under ~160 lines rendered in full even for a one-line change. Drop to
the standard 3 lines of context so the diff shows only what changed plus a
little surrounding context.
The header stacked a redundant "Files" label (the tab already says Files),
a file count, a +adds/-dels summary, an always-open search box, and a
"Collapse all" text button, so it overflowed in the narrow inspector rail.

Strip it to the essentials: a compact "N files" count, a collapsible
search (icon that expands to the input), and icon-only actions for
expand/collapse-all, wrap, refresh, maximize, and close. Everything is
icon-width now, so the header fits at any rail width. Also give the diff
line-number gutter an opaque background so the add/remove row tint no
longer bleeds through the numbers.
Show the enclosing function/section from each hunk header (the text after
the @@ range) in the hunk band. Within a run of deleted lines that pairs
one-for-one with the following added lines, token-diff each pair (LCS over
word tokens) and highlight only the characters that actually changed
instead of tinting the whole line. Long lines skip the O(n^2) pass.
Add a copy-to-clipboard button on each changed-file row that copies the
file path and briefly confirms with a check icon. It stays hidden until
the row is hovered or the button is focused, so it does not add clutter.
Add a header toggle that switches the diff between the unified view and a
side-by-side split. Deletions align left, additions align right, context
spans both sides, and hunk headers span the full width. Intra-line
highlighting and per-side line numbers carry over to the split layout.
Pressing j / k moves focus to the next / previous changed-file row
(Vim-style), skipping the keys while the search box has focus. The rows
already handle Enter/Space to expand, so this rounds out mouse-free review.
@codebanditssss
codebanditssss marked this pull request as ready for review July 23, 2026 12:11

@Vaibhaav-Tiwari Vaibhaav-Tiwari left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

lgtm but there shouldn't be so much padding

Drop the content wrapper's horizontal padding (it doubled up with each
row's own px-4) and its vertical padding, and shorten the file rows, so
the list is not indented and spaced out. Addresses review feedback.
@codebanditssss

Copy link
Copy Markdown
Collaborator Author

tightened it up. the content wrapper was adding its own px-4/py-4 on top of each row already having px-4, so the list was double-indented and spaced out. dropped the wrapper padding and shortened the rows. pushed in 2551703, mind taking another look?

Long diff lines soft-wrap by default instead of scrolling horizontally,
and the wrap toggle button is removed since it is now the only behavior.
One fewer control in the header.
The two-column old#/new# gutter rendered an empty left column for
added lines, which on an all-additions file looked like a big block of
dead left padding. Collapse to one gutter column (new number, falling
back to the old number for deletions), halving the gutter.
@Vaibhaav-Tiwari
Vaibhaav-Tiwari merged commit 790d901 into main Jul 23, 2026
11 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.

2 participants