Green

Version

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:

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:

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 test

Code Coverage

To generate a coverage report:

# Terminal output
mix coveralls

# HTML report (saved to cover/index.html)
mix coveralls.html

The project maintains >90% overall test coverage.

Code Formatting

To check code formatting:

mix format --check-formatted