Current section
Files
Jump to
Current section
Files
lib/my_formatter.ex
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