defmodule MyFormatter do @moduledoc false # Custom formatter plugin that uses TAB characters for indentation instead of spaces. # This formatter: # - Uses TAB character for indentation # - Uses SPACE character for alignment # - Follows British English conventions for comments and names @behaviour Mix.Tasks.Format def features(_opts) do [extensions: ~w(.ex .exs)] end def format(contents, _opts) do contents |> Code.format_string!() |> IO.iodata_to_binary() |> convert_spaces_to_tabs() end # Convert leading spaces to tabs while preserving alignment spaces defp convert_spaces_to_tabs(formatted_code) do formatted_code |> String.split("\n") |> Enum.map_join("\n", &process_line/1) end # Process each line to convert indentation spaces to tabs defp process_line(line) do case Regex.run(~r/^(\s*)(.*)$/, line) do [_, leading_whitespace, rest] -> tab_indentation = convert_leading_spaces(leading_whitespace) tab_indentation <> rest _ -> line end end # Convert groups of 2 spaces at the beginning to single tab defp convert_leading_spaces(whitespace) do # Count leading spaces (ignoring any tabs that might already be there) space_count = String.length(String.replace(whitespace, "\t", "")) # Convert pairs of spaces to tabs tab_count = div(space_count, 2) remaining_spaces = rem(space_count, 2) # Build result with tabs for indentation and remaining space for alignment String.duplicate("\t", tab_count) <> String.duplicate(" ", remaining_spaces) end end