Skip to content

Feature request: --wrapLines flag to wrap long lines instead of scrolling horizontally #182

Description

@raffaelemancuso

Problem

Every diff line is rendered with white-space: pre (.d2h-code-line-ctn) and the panes scroll
horizontally (.d2h-file-side-diff { overflow-x: scroll }).

That is the right default for code, but it makes the CLI hard to use for prose diffs
Markdown / LaTeX / plain-text documents where a paragraph is one very long line. The report
becomes a stack of horizontal scrollbars showing a dozen words each.

There is no CLI flag for this today. The only workaround is --htmlWrapperTemplate with a
hand-maintained copy of template.html, which has to be re-checked against upstream on every
bump.

Request

An opt-in flag, e.g. --wrapLines (default false, so nothing changes for existing users),
that injects the CSS below.

Prior art

In #569: "Historically, getting scrolling and word wrapping to work well together has been
challenging. If you manage to make them coexist, please open a PR and I'll gladly review it."

The difficulty flagged in #99 is real and specific: in side-by-side mode the two panes are two
independent <table>s, so a line that wraps on one side grows that row only, and every
following row drifts out of step with its counterpart.

A recipe that works

CSS — making the line a flex row is what keeps the +/- prefix in its own column, so
continuation lines hang under the text rather than under the prefix:

.d2h-code-line,
.d2h-code-side-line { display: flex; align-items: flex-start; white-space: pre-wrap; }
.d2h-code-line-prefix { flex: 0 0 auto; }
.d2h-code-line-ctn {
  flex: 1 1 auto; width: auto; min-width: 0;
  white-space: pre-wrap; word-wrap: break-word; overflow-wrap: anywhere;
}
.d2h-file-diff,
.d2h-file-side-diff { overflow-x: hidden; }
.d2h-file-side-diff { min-width: 0; }

For side-by-side that leaves the row drift, which a small script fixes: for each
.d2h-files-diff, walk the two tbody.d2h-diff-tbody row lists in parallel, measure every pair
first and only then write style.height = max(left, right) on both. Measuring and writing in one
interleaved pass thrashes layout badly on large diffs. Re-run debounced on resize, on
document.fonts.ready, and on change of a .d2h-file-collapse-input (a file hidden by its
"Viewed" checkbox measures as zero-height).

Horizontal scrolling and wrapping do coexist under this approach because wrapping makes the
overflow disappear entirely — --synchronisedScroll then simply has nothing left to sync, which
is why the flag should stay opt-in rather than become the default.

Verified

Chromium, on a 3-file Markdown diff (456 code lines, 148 of which wrap):

  • 0 panes overflowing horizontally, 0 px page overflow
  • worst row-pair drift 0 px across 238 visible row pairs, at both 1600 px and 900 px viewport
  • the +/- prefix stays on the first visual line of its text

Happy to turn this into a PR if the flag sounds welcome, and to take it to diff2html#99 instead
if you would rather the CSS live upstream in the core package.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions