diff --git a/lib/style.ex b/lib/style.ex index 07c39ea4..f6ae8f41 100644 --- a/lib/style.ex +++ b/lib/style.ex @@ -64,6 +64,9 @@ defmodule Styler.Style do |> Zipper.root() end + # useful for comparing AST line numbers interfering + def without_meta(ast), do: update_all_meta(ast, fn _ -> nil end) + @doc """ Returns the current node (wrapped in a `__block__` if necessary) if it's a valid place to insert additional nodes """ diff --git a/lib/style/blocks.ex b/lib/style/blocks.ex index 54a45118..1f3ac718 100644 --- a/lib/style/blocks.ex +++ b/lib/style/blocks.ex @@ -254,10 +254,7 @@ defmodule Styler.Style.Blocks do defp left_arrow?({:<-, _, _}), do: true defp left_arrow?(_), do: false - defp nodes_equivalent?(a, b) do - # compare nodes without metadata - Style.update_all_meta(a, fn _ -> nil end) == Style.update_all_meta(b, fn _ -> nil end) - end + defp nodes_equivalent?(a, b), do: Style.without_meta(a) == Style.without_meta(b) defp if_ast(zipper, head, {_, _, _} = do_body, {_, _, _} = else_body, ctx) do do_ = {{:__block__, [line: nil], [:do]}, do_body} diff --git a/lib/style/configs.ex b/lib/style/configs.ex index 05721992..d9a9b424 100644 --- a/lib/style/configs.ex +++ b/lib/style/configs.ex @@ -41,13 +41,30 @@ defmodule Styler.Style.Configs do Delete the duplicative/erroneous stanza and life will be good. """ + alias Styler.Style + def run({{:import, _, [{:__aliases__, _, [:Config]}]}, _} = zipper, %{config?: true} = ctx) do {:skip, zipper, Map.put(ctx, :mix_config?, true)} end - def run({{:config, _, args} = config, zm}, %{mix_config?: true} = ctx) when is_list(args) do - {configs, others} = Enum.split_while(zm.r, &match?({:config, _, [_ | _]}, &1)) - [config | configs] = Enum.sort_by([config | configs], &Styler.Style.update_all_meta(&1, fn _ -> nil end), :desc) + def run({{:config, _, [_, _ | _]} = config, zm}, %{mix_config?: true} = ctx) do + {configs, others} = Enum.split_while(zm.r, &match?({:config, _, [_, _| _]}, &1)) + + [config | configs] = + [config | configs] + |> Enum.group_by(fn + {:config, _, [{:__block__, _, [app]} | _]} -> app + {:config, _, [arg | _]} -> Style.without_meta(arg) + end) + |> Enum.sort(:desc) + |> Enum.flat_map(fn {_app, configs} -> + configs + |> Enum.sort_by(&Style.without_meta/1, :asc) + |> Style.reset_newlines() + |> Enum.reverse() + end) + |> Style.fix_line_numbers(List.first(others)) + zm = %{zm | l: configs ++ zm.l, r: others} {:skip, {config, zm}, ctx} end diff --git a/test/style/configs_test.exs b/test/style/configs_test.exs index f1fa54c7..0e5edc32 100644 --- a/test/style/configs_test.exs +++ b/test/style/configs_test.exs @@ -26,7 +26,7 @@ defmodule Styler.Style.ConfigsTest do end end - test "orders configs!" do + test "orders configs stanzas" do assert_style """ config :z, :x config :a, :b @@ -35,22 +35,40 @@ defmodule Styler.Style.ConfigsTest do assert_style( """ import Config - config :z, :x, :woof + config :a, :b, :c + config :a, :c, :d + import_config "my_config" + config :z, a: :meow - config :a, :b + config :a, :b, :x """, """ import Config - config :a, :b + config :a, :b, :c + config :a, :c, :d + config :z, :x, :woof + + import_config "my_config" + + config :a, :b, :x + config :z, a: :meow """ ) end - test "ignores config when import Config wasn't called" do + test "ignores things that look like config/2,3" do + assert_style """ + import Config + + config :a, :b + + config(a) + config :c, :d + """ end test "moves assignments to before configs"