Raxol. UI. Components. Harness. WordDiff
(Raxol v2.6.1)
View Source
Intra-line word diff for a paired deletion/addition line.
Ports the intra-line model from
docs/proposals/in-flight/pierre-diffs-analysis.md §1.3: for a paired
change row (the i-th deletion of a changed hunk against its i-th
addition -- purely positional, no similarity matching), tokenize both
lines into words and whitespace runs, diff the token sequences (LCS),
and collapse the changed token runs into {char_start, char_length}
ranges per side. The word-alt join rule merges two changed spans
separated by a single unchanged whitespace token into one span (e.g.
"red apple pie" -> "blue mango pie" highlights "red apple" as one
region, not two words with a highlighted gap between them).
Pairing itself (which deletion goes with which addition) is the
caller's job -- Raxol.UI.Components.Harness.DiffViewer does that at
the change-block level. This module only diffs one already-paired pair
of lines.
Ranges are grapheme offsets into the line text, not display-width
columns: they exist to slice a string (String.slice/3), and a cut
position between two graphemes is correct regardless of how many
terminal columns a wide grapheme occupies. Column math for layout
(padding, gutter width, pane-fit) is a separate concern already handled
via Raxol.UI.TextMeasure elsewhere in the diff viewer.
Summary
Functions
Computes changed-word ranges for a paired deletion/addition line pair.
Types
@type range() :: {non_neg_integer(), pos_integer()}
Functions
Computes changed-word ranges for a paired deletion/addition line pair.
Returns {old_ranges, new_ranges}. Either side is [] (no ranges) when
the line has no word-level differences, or -- the guard -- when either
line exceeds 1000 characters.
Examples
iex> Raxol.UI.Components.Harness.WordDiff.word_ranges("foo bar", "baz bar")
{[{0, 3}], [{0, 3}]}
iex> Raxol.UI.Components.Harness.WordDiff.word_ranges("same", "same")
{[], []}