[TUI] Add line+word diff highlighting to the TUI diff viewer
What feature would you like to see?
The Codex CLI TUI diff viewer to support intra-line diff highlighting (word-level or token-level), not just whole-line insert/delete indicators.
Today, any change inside a long line (e.g. adding a single identifier in a long statement, tweaking a string, or small doc edits) shows the entire line as added or removed, which makes it harder to visually scan what actually changed.
Rationale / impact:
- Speeds up code review inside the CLI.
- Reduces cognitive load when scanning large diffs with minor edits.
- Aligns with expectations set by tools like
git diff --word-diff, GitHub’s web UI, and popular TUI diff viewers.
Example:
Existing TUI line diff:
<img width="673" height="227" alt="Image" src="https://github.com/user-attachments/assets/405973a7-7df2-4f09-a6a6-276c6e83e3cd" />
Example of improved 'line+word highlight' diff:
<img width="666" height="213" alt="Image" src="https://github.com/user-attachments/assets/765a0699-216e-4593-a3eb-9ec9147b9d1e" />
This example was generated with this diff-strings helper from my dotfiles:
It basically just does a normal git diff --no-index to pass the 2 strings in; but the real 'line+word' highlighting magic comes from delta:
- https://github.com/dandavison/delta
- > delta
- > A syntax-highlighting pager for git, diff, grep, and blame output
- https://github.com/dandavison/delta#features
- > Features
- > Word-level diff highlighting using a Levenshtein edit inference algorithm
Since delta is also rust-based, maybe the same method / underlying libraries / etc can be used directly?
Are you interested in implementing this feature?
I don’t currently have the Rust familiarity or bandwidth to implement it, so I’m filing this as a feature request for consideration.
Additional information
The following proposed implementation was generated by GitHub Copilot (GPT-5); and I haven't manually validated it for viability:
Proposed capabilities: 1. Inline highlighting mode that emphasizes only the changed spans within modified lines. 2. Support at least word-level granularity (splitting on whitespace and punctuation); optionally fall back to character-level for very long tokens. 3. (Optional) A toggle key in the TUI (e.g. w) to switch between: - Line-only mode (current behavior) - Word-diff mode 4. (Optional) A configuration option (env var or config file) to set the default mode. 5. Sensible styling: - Keep existing + / - line indicators. - Within an inserted line, highlight only the newly added segments (e.g. bold or different background). - For replaced portions, consider showing deletions and insertions side-by-side (current approach) but with finer-grain highlights per changed span. Possible implementation sketch: - When processing adiffy::Line::Deletefollowed immediately by adiffy::Line::Insertwith similar line numbers (a replace), run an intra-line diff algorithm on the pair. - Use a lightweight algorithm: - Tokenize into words (split on Unicode whitespace + punctuation). - Run a Myers or patience diff at the token level (crates:similar,difference, or implement a small LCS). - For each token classified as changed, wrap it in styled spans (ratatui::text::Spanwith distinct background or color). - Fallback to character-level diff if tokenization yields too few tokens or tokens are huge. - Provide an abstraction likecompute_inline_spans(old: &str, new: &str) -> (Vec<Span>, Vec<Span>) returning styled spans for each line variation. - Integrate intopush_wrapped_diff_lineor a companion function that can accept a pre-tokenized styledVec<Span>instead of a plain&str. Open questions / nice-to-haves: - Should deletions be shown inline (e.g. strikethrough) on the inserted line, or kept as a separate deleted line? (Initial version can keep current separate-line layout.) - Add a minimal legend/help panel update indicating the toggle key and meaning of inline highlighting. - Option for users with limited color support or accessibility needs to choose underline/bold instead of color changes.
---
Tangentially related:
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗