Having trouble with `formatter` and `case`

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.