Skip to content

Add wrapped lines option to diff views - #1

Open
atacan wants to merge 1 commit into
mainfrom
feature/wrapped-lines
Open

atacan wants to merge 1 commit into
mainfrom
feature/wrapped-lines

Conversation

@atacan

@atacan atacan commented Aug 24, 2026

Copy link
Copy Markdown
Owner

Summary

Adds an opt-in wrapped lines mode to JSDiffUI so long diff lines wrap onto multiple visual rows (with a ↪ continuation marker) instead of being truncated or overflowing.

Changes

  • DiffStyle: new wrapLongLines: Bool = false and wrapMarker: String = "↪ " options, plus a withWrapLongLines(_:marker:) builder method
  • DiffLineWrapper (new): word-boundary chunking engine — hard-splits words longer than the limit, consumes break spaces, and accounts for marker width on continuation rows. Also includes DiffMetrics for estimating characters-per-line from available width using platform monospaced fonts (UIKit/AppKit)
  • DiffWrappedContentView (new): shared view rendering a line as stacked visual rows; continuation rows get the marker, dimmed text, the same background highlight, and blank line-number gutters so alignment is preserved
  • Views: UnifiedDiffView, UnifiedPatchView, InlineDiffLineView, and side-by-side columns measure their own width via GeometryReader and thread the wrap limit down
  • API: .wrapLines(_:) / .wrapLines(_:marker:) modifiers on DiffView, PatchView, and PatchesView
  • Tests: 6 unit tests covering short text, word-boundary breaks, hard splits, marker capacity accounting, empty input, and tiny limits
  • README documentation + wrapped-lines SwiftUI preview

Default behavior is unchanged (wrapLongLines defaults to false).

Usage

DiffView(changes: changes, displayStyle: .unified)
    .wrapLines(true)

// Custom continuation marker
DiffView(changes: changes)
    .wrapLines(true, marker: "… ")

Implementation note

SwiftUI's AttributedString doesn't support paragraph-level hanging indents, so wrapping is done by pre-splitting into estimated-width segments rather than relying on native text layout. A TextKit-based implementation could replace the estimator later for pixel-perfect wrapping.

Testing

  • swift build ✅
  • swift test — all 32 tests pass (including 6 new wrapper tests) ✅

- DiffStyle gains wrapLongLines and wrapMarker (withWrapLongLines builder)
- DiffLineWrapper splits content into word-boundary segments with a
  configurable continuation marker; DiffMetrics estimates characters
  per line from available width via GeometryReader + platform fonts
- Unified, inline, and side-by-side views render wrapped rows with the
  marker, dimmed continuation text, and blank line-number gutters
- New .wrapLines(_:marker:) modifiers on DiffView/PatchView/PatchesView
- Unit tests for the wrapping logic; README documentation
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