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

range()

@type range() :: {non_neg_integer(), pos_integer()}

Functions

word_ranges(old_line, new_line)

@spec word_ranges(String.t(), String.t()) :: {[range()], [range()]}

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")
{[], []}