Erlfmt - opinionated formatter for Erlang

Erlfmt

This is the main thread for erlfmt, the opinionated formatter for Erlang.

Usage

In a rebar3 project, you can add this to your rebar.config file:

{project_plugins, [erlfmt]}.
{erlfmt, [write]}.

You’ll be able to then run:

$ rebar3 fmt # format all supported files in your project
$ rebar3 fmt --check # verify everything is formatted in CI

More detailed instructions are available in documentation.

The formatter can also be used as a standalone escript.

Design principles

Erlfmt has a set of reasoned principles that it attempts to follow, and major choices are documented in decision documents. Erlfmt will always preserve the exact AST of the code, changing only whitespace – this invariant is actively verified each time you format your code.
Erlfmt is designed to work with the engineer by respecting some of their formatting choices.

Incomplete code

Since erlfmt is intended to be used interactively in an editor for format-on-save, it can always format your code – in worst case it will reprint, without changing, sections of the file it can’t parse. Furthermore, it supports some edge cases that Erlang compiler considers errors, like trailing comas in containers (that are automatically removed) and case or receive expressions without clauses.

OTP support

We’ve recently released version 1.7.0 that adds support for new OTP 28 features like zip & strict generators in comprehensions, and nominal types. Minimum required version is OTP 21.

14 Likes

Hi @michalmuskala

I use erlfmt everyday - well on days that I’m coding Erlang - and love it, absolutely wonderful.

One thing I was wondering about is alignment of arrows, I tend to do this:

    Data = #{
      <<"id">>     => IdStr,
      <<"z">>      => ZStr,
      <<"_alias">> => IdStr,
      <<"path">>   => ZStr,
      <<"name">>   => NameStr,
      <<"msg">>    => jstr(ErrMsg),
      <<"format">> => <<"string">>
     },

but erlfmt removes that so I’ve got a erlfmt:ignore on the top of that.

Is there a way - is it already available - to get erlfmt to keep that alignment? I’m not a bookworm when it comes to the options of erlfmt, so please excuse my ignorance if its already possible …

Cheers again for a great tool!

Gerrit

1 Like

Hey, @gorenje.

erlfmt, as far as I’m aware, and the documentation shows, has only 2 “options”:

  1. line length (print_width)
  2. ignore this block (erlfmt:ignore-begin ... erlfmt:ignore-end)

and that’s by design:

The second principle is to provide as little configuration as possible. This removes contention points and makes it easier to achieve the goal of consistent code. Instead of providing configuration, the formatter respects a limited set of choices made in the original code to preserve intent and make it easier to achieve beautiful code based on contextual hints.

3 Likes

Thanks for pointing that out, that makes it clear what erlfmt aims to achieve.

2 Likes

Thanks @gorenje for the kind words.

We generally don’t support aligning things vertically in erlfmt. The main issue is with when you add another line that’s longer than existing lines – you either need to keep things not aligned anymore or realign all of the lines. This increases the diff between versions making it include unrelated lines – decreasing utility of blames, and increasing the chance of merge conflicts.

And yes, as Paulo pointed out, we generally avoid options and try to keep things as minimal as possible.

2 Likes