Current section
Files
Jump to
Current section
Files
examples/diff.exs
# Terminal-aware diff — compare two ANSI outputs by their visual content.
# Strips escape codes, handles cursor movement, carriage returns, etc.
#
# mix run examples/diff.exs
defmodule TermDiff do
def to_plain(ansi, cols \\ 120) do
{:ok, term} = Ghostty.Terminal.start_link(cols: cols, rows: 50)
Ghostty.Terminal.write(term, ansi)
{:ok, text} = Ghostty.Terminal.snapshot(term)
GenServer.stop(term)
String.trim_trailing(text)
end
end
before = "\e[32m 3 tests, 0 failures\e[0m\r\n\r\nFinished in 0.04 seconds\r\n"
after_ = "\e[31m 3 tests, 1 failure\e[0m\r\n\r\nFinished in 0.08 seconds\r\n"
plain_before = TermDiff.to_plain(before)
plain_after = TermDiff.to_plain(after_)
IO.puts("Before: #{inspect(plain_before)}")
IO.puts("After: #{inspect(plain_after)}")
diff = String.myers_difference(plain_before, plain_after)
IO.puts("\nMyers diff:")
for {op, text} <- diff do
case op do
:eq -> IO.write(text)
:del -> IO.write(IO.ANSI.red() <> IO.ANSI.crossed_out() <> text <> IO.ANSI.reset())
:ins -> IO.write(IO.ANSI.green() <> IO.ANSI.underline() <> text <> IO.ANSI.reset())
end
end
IO.puts("")