Skip to content

Conversation

@remorses
Copy link
Contributor

@remorses remorses commented Nov 30, 2025

Adds word-level highlighting to show which words changed within modified lines (like GitHub's diff view).

Algorithm:

  1. Parse diff and group consecutive remove/add lines into change blocks
  2. Pair lines positionally within each block (1st remove with 1st add, etc.)
  3. For each pair, compute similarity score using character-level diff
  4. If similarity >= 40%, compute word boundaries with diffWordsWithSpace
  5. Pass highlight column ranges to LineNumberRenderable for rendering

Complexity is O(L + B×P×C²) where L=lines, B=change blocks, P=pairs per block, C=chars per line. In practice C is small (~100) and only change blocks are processed.

Performance guards: skips word diff for dissimilar lines, skips entirely for large blocks (>50 lines).

Screenshot 2025-11-30 at 18 01 50

New options:

  • disableWordHighlights - Turn off word-level highlighting (default: false)
  • addedWordBg - Background color for added words (default: brighter addedBg)
  • removedWordBg - Background color for removed words (default: brighter removedBg)
  • lineSimilarityThreshold - Min similarity (0-1) to pair lines for word diff (default: 0.4)

Also includes:

  • Fix for word highlights scrolling with content when wrapMode: "none" and horizontal scrolling is used

@kommander
Copy link
Collaborator

This would be cool. I'd make it an option though so both view styles work.

I am concerned about multi width graphemes though, it cannot use String.length or utf16 char offsets from js as the highlights operate on display width currently.

That's a bit tricky. What could work to get content start and end for the highlight offsets would be to measure the string before the content starts with Bun.stringWidth, then the content that should be highlighted itself with Bun.stringWidth and add that to the former for the end offset.

@remorses remorses marked this pull request as ready for review December 14, 2025 16:41
Copilot AI review requested due to automatic review settings December 14, 2025 16:41
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds word-level highlighting to diff views, showing which specific words changed within modified lines (similar to GitHub's diff view). The implementation uses character-level similarity scoring to intelligently pair removed/added lines, then applies word-based diffing to compute highlight positions.

Key changes:

  • New computeLineSimilarity and computeInlineHighlights functions for word-level diff analysis
  • Modified unified and split view rendering to integrate inline highlights
  • Added LineInlineHighlight interface and rendering support in LineNumberRenderable

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
packages/core/src/renderables/Diff.ts Implements word-level diff algorithm with similarity-based line pairing, adds new options (disableWordHighlights, addedWordBg, removedWordBg, lineSimilarityThreshold) and integrates highlights into both unified and split view rendering
packages/core/src/renderables/LineNumberRenderable.ts Adds LineInlineHighlight interface and rendering logic to draw word-level highlight backgrounds, includes new public API methods for managing highlights
packages/core/src/renderables/Diff.test.ts Comprehensive test coverage for similarity computation, inline highlight calculation (including CJK/emoji edge cases), and option handling
packages/react/examples/diff.tsx Updates example diff content to include emoji and CJK characters for better visual testing of word-level highlighting

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

- Added scrollX offset to inline highlight positions in LineNumberRenderable
- Added tests for word highlights with horizontal scrolling in unified and split views
When text wraps to multiple visual lines, highlights now only appear on the
correct wrapped line(s) by using lineWraps offset to calculate visibility.
lineWraps contains wrap INDEX (0,1,2...), not column offset.
Now properly computes column offset by summing widths of previous
wrapped segments belonging to the same logical line.
@remorses
Copy link
Contributor Author

Also works with text wrapping:

Screenshot 2025-12-14 at 18 22 01

@remorses
Copy link
Contributor Author

Here is how it looks in opencode

Screenshot 2025-12-16 at 17 50 23

Copy link
Collaborator

@Hona Hona left a comment

Choose a reason for hiding this comment

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

on pure aesthetics i think it shouldnt be green it should be a more opaque version of the + bg color
thinking about themes and how github does it:

image

you may have already covered that in config right as a new option?
maybe the config you've already done is the way to go

@remorses
Copy link
Contributor Author

I now increase opacity, previously it was only increasing brightness

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.

3 participants