[PR #368] feat(diff): add word-level highlighting for modified lines #486

Open
opened 2026-03-02 23:46:44 +03:00 by kerem · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/anomalyco/opentui/pull/368
Author: @remorses
Created: 11/30/2025
Status: 🔄 Open

Base: mainHead: word-highlights


📝 Commits (10+)

  • ec432ca add word highlights
  • c0ceee1 test: add word highlight tests
  • 85e2afd format
  • 45884fe fix: use Bun.stringWidth for multi-width character support in word highlights
  • ebfc48c fix: correct line counts in example diff hunk header
  • a5a9136 update react example
  • d663823 rename showWordHighlights to disableWordHighlights
  • 117e470 chore: remove verbose comments
  • 1c2e986 refactor: simplify word highlights code
  • 6cc3958 fix: revert unrelated simplifications to split view forEach loops

📊 Changes

7 files changed (+1009 additions, -84 deletions)

View changed files

📝 packages/core/package.json (+1 -0)
packages/core/src/benchmark/diff-word-highlights-benchmark.ts (+381 -0)
📝 packages/core/src/lib/RGBA.ts (+9 -0)
📝 packages/core/src/renderables/Diff.test.ts (+211 -2)
📝 packages/core/src/renderables/Diff.ts (+321 -79)
📝 packages/core/src/renderables/LineNumberRenderable.ts (+77 -1)
📝 packages/react/examples/diff.tsx (+9 -2)

📄 Description

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

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/anomalyco/opentui/pull/368 **Author:** [@remorses](https://github.com/remorses) **Created:** 11/30/2025 **Status:** 🔄 Open **Base:** `main` ← **Head:** `word-highlights` --- ### 📝 Commits (10+) - [`ec432ca`](https://github.com/anomalyco/opentui/commit/ec432cac1a9527d332685e57476bf1bc8a97eb2a) add word highlights - [`c0ceee1`](https://github.com/anomalyco/opentui/commit/c0ceee17aecec87b2b700d136af9b88bdc330085) test: add word highlight tests - [`85e2afd`](https://github.com/anomalyco/opentui/commit/85e2afd47598537dbfc61307f75a43e97d918e56) format - [`45884fe`](https://github.com/anomalyco/opentui/commit/45884fe3fe62c4bcef341b3a2f539b88f7a694c5) fix: use Bun.stringWidth for multi-width character support in word highlights - [`ebfc48c`](https://github.com/anomalyco/opentui/commit/ebfc48cbaa43898be5f8aab6265cf6a7a964cc28) fix: correct line counts in example diff hunk header - [`a5a9136`](https://github.com/anomalyco/opentui/commit/a5a913680945837295bcb39cc2b018b6d4b17191) update react example - [`d663823`](https://github.com/anomalyco/opentui/commit/d663823ee403f6947e7c01f6addd1d137ed964a2) rename showWordHighlights to disableWordHighlights - [`117e470`](https://github.com/anomalyco/opentui/commit/117e4708abbc9bc38314d1d714d6bbe6414d2bc2) chore: remove verbose comments - [`1c2e986`](https://github.com/anomalyco/opentui/commit/1c2e9860084de5c7ec92ada0663d9b758866e1a5) refactor: simplify word highlights code - [`6cc3958`](https://github.com/anomalyco/opentui/commit/6cc3958a0389f7a6aca22ee3353e4ba02ab3987f) fix: revert unrelated simplifications to split view forEach loops ### 📊 Changes **7 files changed** (+1009 additions, -84 deletions) <details> <summary>View changed files</summary> 📝 `packages/core/package.json` (+1 -0) ➕ `packages/core/src/benchmark/diff-word-highlights-benchmark.ts` (+381 -0) 📝 `packages/core/src/lib/RGBA.ts` (+9 -0) 📝 `packages/core/src/renderables/Diff.test.ts` (+211 -2) 📝 `packages/core/src/renderables/Diff.ts` (+321 -79) 📝 `packages/core/src/renderables/LineNumberRenderable.ts` (+77 -1) 📝 `packages/react/examples/diff.tsx` (+9 -2) </details> ### 📄 Description 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). <img width="1702" height="850" alt="Screenshot 2025-11-30 at 18 01 50" src="https://github.com/user-attachments/assets/45c01136-21bb-483f-8931-fe431efdac33" /> **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 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/opentui#486
No description provided.