Current section
Files
Jump to
Current section
Files
src/birdie@internal@diff.erl
-module(birdie@internal@diff).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([line_by_line/2]).
-export_type([diff_line/0, diff_line_kind/0]).
-type diff_line() :: {diff_line, integer(), binary(), diff_line_kind()}.
-type diff_line_kind() :: old | new | shared.
-spec do_map2_index(
list(IDZ),
list(IEB),
fun((IDZ, IEB, integer()) -> IED),
list(IED),
integer()
) -> {list(IED), list(IDZ), list(IEB), integer()}.
do_map2_index(One, Other, Fun, Acc, Index) ->
case {One, Other} of
{Rest_one, []} ->
{gleam@list:reverse(Acc), Rest_one, [], Index};
{[], Rest_other} ->
{gleam@list:reverse(Acc), [], Rest_other, Index};
{[One@1 | Rest_one@1], [Other@1 | Rest_other@1]} ->
_pipe = [Fun(One@1, Other@1, Index) | Acc],
do_map2_index(Rest_one@1, Rest_other@1, Fun, _pipe, Index + 1)
end.
-spec map2_index(list(IDR), list(IDT), fun((IDR, IDT, integer()) -> IDV)) -> {list(IDV),
list(IDR),
list(IDT),
integer()}.
map2_index(One, Other, Fun) ->
do_map2_index(One, Other, Fun, [], 1).
-spec line_by_line(binary(), binary()) -> list(diff_line()).
line_by_line(Old, New) ->
Old_lines = gleam@string:split(Old, <<"\n"/utf8>>),
New_lines = gleam@string:split(New, <<"\n"/utf8>>),
{Diffs, Rest_old, Rest_new, Line_number} = (map2_index(
Old_lines,
New_lines,
fun(Old_line, New_line, Line) ->
Equal_lines = Old_line =:= New_line,
Shared_diff_line = {diff_line, Line, Old_line, shared},
gleam@bool:guard(
Equal_lines,
[Shared_diff_line],
fun() ->
Comparison = begin
_pipe = gap:compare_strings(New_line, Old_line),
_pipe@1 = gap@styling:from_comparison(_pipe),
_pipe@2 = gap@styling:highlight(
_pipe@1,
fun gleam_community@ansi:underline/1,
fun gleam_community@ansi:underline/1,
fun gap@styling:no_highlight/1
),
gap@styling:to_styled_comparison(_pipe@2)
end,
[{diff_line, Line, erlang:element(3, Comparison), old},
{diff_line, Line, erlang:element(2, Comparison), new}]
end
)
end
)),
_pipe@3 = gleam@list:concat(Diffs),
_pipe@4 = gleam@list:append(
_pipe@3,
gleam@list:index_map(
Rest_old,
fun(Line@1, I) ->
{diff_line, (Line_number + I) + 1, Line@1, old}
end
)
),
gleam@list:append(
_pipe@4,
gleam@list:index_map(
Rest_new,
fun(Line@2, I@1) ->
{diff_line, (Line_number + I@1) + 1, Line@2, new}
end
)
).