Green
An Elixir code formatter.
Currently, it can enforce lexmag's Elixir style guide.
Motivation
The standard Elixir formatter only enforces a small number of rules. This project aims to enforce enough rules so that the "house style" of a project can be enforced by the formatter.
Name
The name "Green" is a reference to bikeshedding, i.e. "All bike sheds should be green."
Status
Currently, Green provides Green.Lexmag.ElixirStyleGuideFormatter which,
as far as is possible, implements the rules of lexmag's style guide
that are not already implemented by mix format.
Usage
Add the following to your mix.exs:
defp deps() do
[
{:green, "~> (See the badge above)", only: :dev}
]
end
Modify .formatter.exs to activate the formatter plugin:
[
plugins: [Green.Lexmag.ElixirStyleGuideFormatter]
]Limitations
Two rules change the order of lines:
PreferPipelinesgroupsuse,import,aliasandrequirestatements,RemoveNilFromStructDefinitionplaces the list ofnil-default fields at the top of the struct definition.
Where possible, when shifting lines around, Green will try to keep associated comments with the lines that follow them. However, this is not always possible. Please check the output of the formatter to ensure that comments are in the correct place.
Configuration
This library aims to avoid configuration as far as possible. However, there will be cases where you will want to tweak behaviour due to the specifics of your project.
Disabling Individual Rules
All Green rules can be individually enabled or disabled in .formatter.exs.
Each rule is enabled by default, but can be disabled like this:
[
plugins: [Green.Lexmag.ElixirStyleGuideFormatter],
green: [
# Disable specific rules
avoid_needless_pipelines: [enabled: false],
no_unless_with_else: [enabled: false],
use_parentheses_with_zero_arity_functions: [enabled: false]
]
]Available rules for configuration:
avoid_needless_pipelinesno_anonymous_functions_in_pipelinesno_unless_with_elseno_nil_elsetrue_in_condboolean_operatorsuse_string_concatenation_when_matching_binariesavoid_one_letter_variablespredicate_functionsupper_camel_case_for_modulessort_referencesuse_module_pseudo_variableremove_nil_from_struct_definitionuse_error_suffixlowercase_exception_messagesno_trailing_punctuation_in_exception_messagesprefer_pipelinesavoid_capsuse_parentheses_with_zero_arity_functions
Rule-Specific Configuration
Some rules have additional configuration options beyond just enabling/disabling.
For example, the PreferPipelines rule may be applied in some unwanted cases.
ExUnit's assert and refute are not, by default, in locals_without_parens -
the list of functions that can appear without parentheses.
As a result, these calls get converted to pipelines.
To avoid this, add the following to .formatter.exs:
locals_without_parens: [assert: 1, refute: 1],This works for locals, but not for function (and macro) calls on modules.
If you want to avoid conversion of these to pipelines, you can add
the following to .formatter.exs:
green: [
prefer_pipelines: [
ignore_functions: ["My.Module.foo": 1]
]
]Roadmap
Implement the other well-known Elixir style guides:
Development
Running Tests
To run the test suite:
mix testCode Coverage
To generate a coverage report:
# Terminal output
mix coveralls
# HTML report (saved to cover/index.html)
mix coveralls.htmlThe project maintains >90% overall test coverage.
Code Formatting
To check code formatting:
mix format --check-formatted