Raxol. UI. Components. Harness. DiffViewer
(Raxol v2.6.1)
View Source
Pre-apply file diff viewer.
Renders the line-based diff between a file's current content (old) and
a proposed edit (new) BEFORE the edit is applied. This is the
"pre-apply confirmation over post-hoc undo" surface described in
docs/proposals/in-flight/harness-spec-frontend.md: framing always
reads as "this WILL change" -- a "Proposed change" header and a "Not yet
applied" caption, never past tense.
Visual language
Ports the Pierre (@pierre/diffs) visual language --
docs/proposals/in-flight/pierre-diffs-analysis.md -- flattened for a
terminal cell grid (one bg + one fg per cell, no alpha compositing):
- Diff paints background only; syntax tokens own foreground and are never overridden. Added rows get a dark-green bg wash, removed rows dark-red, with a brighter "emphasis" bg tier on the word-level-changed sub-ranges of a paired change row -- syntax colors show through both tiers unchanged.
- A
▌gutter bar (green/red) replaces the classic+/-text marker, per Pierre'sbarsindicator style. - Long unchanged runs (>
2 * context + 1lines) fold into a single dim "N unchanged lines" row;context: :alldisables folding. - Split mode is borderless and label-less -- the red/green gutters carry the old/new identity -- and the unpaired side of a change block stays blank to keep the panes vertically aligned.
Line differencing is computed by Raxol.UI.Components.Harness.LineDiff
(a plain LCS line diff). Intra-line word ranges come from
Raxol.UI.Components.Harness.WordDiff (positional deletion/addition
pairing within a changed hunk, word-level LCS, word-alt span
merging). Syntax tokens come from Raxol.UI.SyntaxHighlighter
(Makeup-based; language: nil skips highlighting entirely).
Props
:path- file path shown in the header (default"").:old- original file content (default"").:new- proposed file content (default"").:mode-:auto(default),:unified, or:split. In:auto, split is chosen when both rendered panes fit side by side in the available width, otherwise unified. Width comes from the:widthprop, else from the render context (:available_width,:width, ordimensions.width); with no width information auto falls back to unified (the safe narrow default). *:width- available width in terminal columns, used only by:auto(defaultnil). *:language- source language for syntax highlighting (e.g."elixir"), passed toRaxol.UI.SyntaxHighlighter.highlight_lines/3.nil(default) disables highlighting -- lines render as plain diff-tinted text. *:syntax_theme- Makeup style atom (e.g.:one_dark,:dracula) or a%Makeup.Styles.HTML.Style{}, passed through to the highlighter (default:one_dark). Distinct from the:themeprop below, which is the Raxol UI theme override map, not a code theme. *:context- number of unchanged lines kept visible at each edge of a folded hunk, or:allto disable folding entirely (default3). *:id,:style,:theme` - standard component props. ## Example {:ok, state} = DiffViewer.init( path: "lib/orders/total.ex", old: old_text, new: new_text, language: "elixir" ) DiffViewer.render(state, %{})
Summary
Functions
The single source of the merged diff visual language's hex tiers (row
wash, intra-line emphasis, gutter tint -- see the comment above
@diff_palette): add_base/add_row_bg/add_emphasis_bg/add_gutter_bg
and their del_* counterparts, each an "#RRGGBB" string. This
Component's own grid rendering (render/2) always reads it through the
private per-tier accessors above; diff_palette/0 exposes the SAME map
publicly so a second renderer of this diff visual language never forks
its own copy of these hexes. Raxol.Harness.DiffExpansion's per-row
line renderer (the full-screen diff expansion's row-level tier of this
same visual language -- gutter bar plus row wash, no word-level
emphasis or syntax highlighting) is the first such caller.
The mode render/2 will actually use for this state and context.
Callback implementation for Raxol.UI.Components.Base.Component.handle_event/3.
Callback implementation for Raxol.UI.Components.Base.Component.mount/1.
Callback implementation for Raxol.UI.Components.Base.Component.unmount/1.
Callback implementation for Raxol.UI.Components.Base.Component.update/2.
Types
Functions
@spec diff_palette() :: %{ add_base: String.t(), add_row_bg: String.t(), add_emphasis_bg: String.t(), add_gutter_bg: String.t(), del_base: String.t(), del_row_bg: String.t(), del_emphasis_bg: String.t(), del_gutter_bg: String.t() }
The single source of the merged diff visual language's hex tiers (row
wash, intra-line emphasis, gutter tint -- see the comment above
@diff_palette): add_base/add_row_bg/add_emphasis_bg/add_gutter_bg
and their del_* counterparts, each an "#RRGGBB" string. This
Component's own grid rendering (render/2) always reads it through the
private per-tier accessors above; diff_palette/0 exposes the SAME map
publicly so a second renderer of this diff visual language never forks
its own copy of these hexes. Raxol.Harness.DiffExpansion's per-row
line renderer (the full-screen diff expansion's row-level tier of this
same visual language -- gutter bar plus row wash, no word-level
emphasis or syntax highlighting) is the first such caller.
The mode render/2 will actually use for this state and context.
Resolves :auto against the available width: :split when both panes
fit side by side, :unified otherwise (including when no width is
known). Explicit :unified/:split pass through unchanged. Exposed so
demos and callers can display or act on the auto decision.
Callback implementation for Raxol.UI.Components.Base.Component.handle_event/3.
Callback implementation for Raxol.UI.Components.Base.Component.mount/1.
Callback implementation for Raxol.UI.Components.Base.Component.unmount/1.
Callback implementation for Raxol.UI.Components.Base.Component.update/2.