Hello! I am having issues with the Elixir formatter and a long case
expression. What’s happening is that this:
defmodule Test do
def evaluate_contract(%{from: from, to: to, value: value} = t, contract) do
case contract do
x when is_number(x) -> x
s when is_binary(s) -> s
[] -> true
{} -> true
true -> true
false -> false
{:if, co, tr, fa} -> if evaluate_contract(t, co), do: evaluate_contract(t, tr), else: evaluate_contract(t, fa)
{:+, left, right} -> evaluate_contract(t, left) + evaluate_contract(t, right)
{:*, left, right} -> evaluate_contract(t, left) * evaluate_contract(t, right)
{:-, left, right} -> evaluate_contract(t, left) - evaluate_contract(t, right)
{:==, left, right} -> evaluate_contract(t, left) == evaluate_contract(t, right)
{:>, left, right} -> evaluate_contract(t, left) > evaluate_contract(t, right)
{:<, left, right} -> evaluate_contract(t, left) < evaluate_contract(t, right)
{:and, left, right} -> evaluate_contract(t, left) and evaluate_contract(t, right)
{:or, left, right} -> evaluate_contract(t, left) or evaluate_contract(t, right)
:from -> from
:to -> to
:value -> value
_ -> false
end
end
end
gets formatted to:
defmodule Test do
def evaluate_contract(%{from: from, to: to, value: value} = t, contract) do
case contract do
x when is_number(x) ->
x
s when is_binary(s) ->
s
[] ->
true
{} ->
true
true ->
true
false ->
false
{:if, co, tr, fa} ->
if evaluate_contract(t, co), do: evaluate_contract(t, tr), else: evaluate_contract(t, fa)
{:+, left, right} ->
evaluate_contract(t, left) + evaluate_contract(t, right)
{:*, left, right} ->
evaluate_contract(t, left) * evaluate_contract(t, right)
{:-, left, right} ->
evaluate_contract(t, left) - evaluate_contract(t, right)
{:==, left, right} ->
evaluate_contract(t, left) == evaluate_contract(t, right)
{:>, left, right} ->
evaluate_contract(t, left) > evaluate_contract(t, right)
{:<, left, right} ->
evaluate_contract(t, left) < evaluate_contract(t, right)
{:and, left, right} ->
evaluate_contract(t, left) and evaluate_contract(t, right)
{:or, left, right} ->
evaluate_contract(t, left) or evaluate_contract(t, right)
:from ->
from
:to ->
to
:value ->
value
_ ->
false
end
end
end
You can try this with the online formatter. I think this is a pretty drastic format and greatly reduces the function’s readability. It also triples the case
expression’s body.
I expected the if
expression to get expanded to multiple lines but not have every other case expanded to multiple lines. I think after expanding the if
, the formatter could put spaces between the clauses (I wouldn’t), but I don’t see the reason why it puts all the short match results on a new line just because of one long result expression.
Is this expected? If so, does anyone know how to configure or any existing custom plugins that work a little better for case
? One option I have is to simply shorten the function name. Although not an ideal change due to formatting, that may be the easiest solution.