Skip to content

Syntax highlighting in the diff view#2997

Open
stevenpollack wants to merge 1 commit into
gitui-org:masterfrom
stevenpollack:diff-syntax-highlight
Open

Syntax highlighting in the diff view#2997
stevenpollack wants to merge 1 commit into
gitui-org:masterfrom
stevenpollack:diff-syntax-highlight

Conversation

@stevenpollack

Copy link
Copy Markdown

Summary

Syntax-highlight the unified diff view. Each line's foreground is highlighted with the syntax set gitui already ships (syntect + two-face, the same stack behind the file/blame viewer — no new dependencies), while change status (add/delete) is conveyed by a selectable indicator. Both added and removed sides are kept.

UX

Shift+X cycles the change-status indicator (persisted per-repo, default tint):

  • off — the previous plain red/green rendering
  • gutter — the left bar colored by add/delete
  • sign — a green + / red - glyph
  • tint — a faint background on changed lines

The syntect foreground shows in all on-states.

Performance

Highlighting runs off the UI thread on the shared rayon threadpool (AsyncDiffHighlightJob, modeled on the blame view's AsyncSyntaxJob): the diff renders instantly and colors swap in when ready, so navigating between files never blocks regardless of diff size. Results are discarded if the user has since navigated away (diff-hash check). Highlighting is capped at 10k diff lines and falls back to the plain rendering for binary diffs / unknown languages / when off.

Notes

  • Reuses the existing SyntaxText highlighter (added a synchronous entry point alongside the async one).
  • Snapshot tests are unaffected (they capture text, not color).
  • make check green (fmt + clippy --all-features + nextest + tombi + deny).

I couldn't attach screenshots here, but it's easiest to see by running a build and toggling Shift+X on any code diff. Happy to adjust the default style, keybinding, or the tint colors (currently dark-theme-oriented) to your preference.

…yles)

Each diff line's foreground is now syntect-highlighted (reusing the
in-tree two-face syntax set that already powers the file/blame viewer
— no new deps, no external bat), keeping both added and removed sides.
Change status is shown by a selectable indicator; [Shift+X] cycles
off / gutter (colored bar) / sign (green + / red -) / tint (faint row
background). Default tint. Persisted per-repo.

Highlighting runs off the UI thread on the shared rayon threadpool
(AsyncDiffHighlightJob, modeled on the blame view's AsyncSyntaxJob):
the diff renders plain instantly and colors swap in when ready, so
file navigation never blocks regardless of diff size. The result is
self-polled in draw() and applied only if its diff hash still matches
(stale results discarded). Capped at 10k lines; horizontal scroll
preserved via byte-window clipping; falls back to the previous
red/green rendering when off, over cap, binary, or highlight fails.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BMQxBdr5f3B3jmDtdvGtTu
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