joeyates
Green - format your code according to a style guide
Today I’m releasing Green - a style guide enforcer for Elixir.
Green acts as a plugin to Mix Format and automates the application of a full set of formatting rules.
Status
Currently, Green implements the set of rules defined in lexmag’s Elixir Style Guide.
For example, it transforms this:
foo(bar(baz(quux), 42))
into this
baz(quux) |> bar(42) |> foo()
See the relevant section of the docs for full details.
Usage
Add the library to your dependencies:
defp deps do
[
{:green, ">= 0.1.3", only: :dev}
]
end
Add the following to .formatter.exs:
plugins: [Green.Lexmag.ElixirStyleGuideFormatter]
Configuration
While Green aims to work with no configuration, there will be cases where a little is needed.
Specifically, Green sometimes needs help in recognising function (and macro) calls that shouldn’t be pipelined. One example is assert/1, which isn’t part of the default :locals_without_parens configuration. To avoid assert foo(1) being turned into 1 |> foo() |> assert(), add this to .formatter.exs:
locals_without_parens: [assert: 1],
Links
Most Liked
Eiji
Personally I really don’t like such a default behaviour. In my opinion you should support all assert-like macros based on the official documentation.
use,import,assignorrequire
Should be:
use,import,aliasorrequire
Don’t use anonymous functions in pipelines (L3),
I guess you can easily consider it as outdated. I would recommend to rewrite it in this way:
# Bad
sentence
|> String.split(~r/\s/)
|> (fn words -> [@sentence_start | words] end).()
|> Enum.join(" ")
# Good
sentence
|> String.split(~r/\s/)
|> then(&[@sentence_start | &1])
|> Enum.join(" ")
Enforce predicate functions to end with a question mark (N3),
That should be easy as long as you require the @spec, simply remove prefix is_ and add ? suffix if such character is not already at the end of the function name.
Avoid superfluous comments (C2).
This is handled by the Elixir formatter. It moves the comment after the expression to above said expression.
Put the expression being tested by comparison on the left side (U1)
I would not implement this. I’m not sure if it’s too far. However it should be easy to implement assuming “standardised” describe block naming:
describe "foo/1" do
test ":default works as same as in foo/0" do
# Bad
assert MyApp.foo() == MyApp.foo(:default)
# Good
assert MyApp.foo(:default) == MyApp.foo()
end
end
garrison
You guys have been debating the comment rule but in fairness to the OP his docs explicitly marked that particular rule as being impossible to implement because it’s subjective.
I think what the rule is getting at is that new programmers can sometimes fall into a habit of over-commenting every line, even what it’s obvious what the code does. Everyone posting in this thread is probably experienced enough to have learned not to do that long ago ![]()
slouchpie
This looks great. Does it work alongside :styler or do they diverge in places? I am on the phone so lazily asking without reading docs.
Last Post!
adworse
I really like it!
One small concern: I haven’t tested it yet, but if your algo forces use to be closer to the module’s headline, it’s not a safe behavior, because resulting code sometimes depends of the macro call placement
Popular in Announcing
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









