Skip to content

Instantly share code, notes, and snippets.

@atomkirk
Created September 21, 2018 02:03
Show Gist options
  • Save atomkirk/eb2ddc0fa39241b9ad4ee737d90b4c2c to your computer and use it in GitHub Desktop.
Save atomkirk/eb2ddc0fa39241b9ad4ee737d90b4c2c to your computer and use it in GitHub Desktop.
Elixir format difference in strings
@doc """
Truncates the middle of a string
iex> Utils.String.truncate_middle("some really long string that needs truncating", 10)
"some..ting"
iex> Utils.String.truncate_middle("some really long string that needs truncating", 100)
"some really long string that needs truncating"
"""
def truncate_middle(str, count) when is_binary(str) and is_integer(count) do
if String.length(str) < count do
str
else
edges = Integer.floor_div(count, 2) - 2
front = String.slice(str, 0..edges)
back = String.slice(str, -(edges + 1)..-1)
"#{front}..#{back}"
end
end
@doc """
Formats the difference between to strings for output
iex> Utils.String.format_diff("zip growth", "zip books")
"\e[39mzip \e[31mgr\e[32mb\e[39mo\e[31mwth\e[32moks"
"""
def format_diff(string1, string2) do
String.myers_difference(string1, string2)
|> Enum.reduce([], fn
{:eq, str}, acc -> [IO.ANSI.default_color() <> Utils.String.truncate_middle(str, 50) | acc]
{:del, str}, acc -> [IO.ANSI.red() <> str | acc]
{:ins, str}, acc -> [IO.ANSI.green() <> str | acc]
end)
|> Enum.reverse()
|> Enum.join("")
end

This helper prints a pretty diff between two strings:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment