README.md

# TQFormat

> Applying the TruQu formatting preferences to our Erlang-ish code

TQFormat is a rebar3 plugin for applying our formatting preferences to our code.

It is highly opinionated and very much unconfigurable. The only configuration
option concerns the page-width.

It is roughly based on Jean-Philippe Bernardy's [A Pretty But Not Greedy
Printer](https://dl.acm.org/doi/pdf/10.1145/3110250), and uses
[erlfmt](https://github.com/WhatsApp/erlfmt/) for parsing Erlang-ish code into
an AST. That AST is then fed to the formatter, which turns the AST into a
document-tree. The document-tree, finally, is evaluated given the paper-width,
which produces a set of printable lines.

## Examples

Our formatting style is largely based on how Emacs formats comma-first Erlang
code. Hence, a map like this:

```erlang
#{this => is, a => record, with => many, keys => and_, values => and_, wont => fit, on => a, single => line}.
```

will result in the following:

```erlang formatted
#{ this => is
 , a => record
 , with => many
 , keys => and_
 , values => and_
 , wont => fit
 , on => a
 , single => line
 }.
```

We inline singular clauses in `case` (etc) expressions, though multiple
expressions will always be laid out as an indented block.

Therefore, this code:

```erlang
case Foo of bar -> do(something), ok; baz -> help end.
```

Will be formatted like so:

```erlang formatted
case Foo of
  bar ->
    do(something),
    ok;
  baz -> help
end.
```

## Usage

`tqformat` can be used as a standalone escript or as a rebar3 plugin.

### As a rebar3 plugin

`tqformat` can be used as a rebar3 plugin.

```erlang
{plugins, [tqformat]}.
```

After adding the plugin, running `rebar3 format` can be used to figure out what
flags and configuration options are available. As an example, the following
configuration in `rebar.config` will cause `rebar3 format` to format all
relevant files in an umbrella application, and cause `rebar3 format --verify` to
verify formatting in those same files.

```erlang
{ tqformat
, [ { files
    , ["apps/*/{src,test,include}/*.{hrl,erl,app.src}", "rebar.config", "config/*.config"]
    }
  ]
}.
```

### As a standalone escript

`tqformat` also exists as a standalone escript. This requires having Erlang
installed (but then, most Erlang developers do), and accepts the same command
line options as the rebar3 plugin.

You can download an escript from the Releases page, or compile your own using
`rebar3 as release escriptize`. This will build an escript into
`_build/release/bin/tqformat`.

## Integration with editors

Missing configuration for your favourite editor? Please let us know by opening
an issue!

### Emacs

Using [reformatter.el](https://github.com/purcell/reformatter.el), setting up
`tqformat` as a formatter can be as simple as this:

```elisp
(reformatter-define tqformat
    :program "tqformat"
    :args '("-")
    :lighter " TQF")
```

See also the instructions in the reformatter readme for how to set up
format-on-save.

### JetBrains IDE

The [intellij-tqformat](https://github.com/truqu/intellij-tqformat) plugin
allows using `tqformat` in all JetBrains IDE products.

## License

TQFormat is released under the Apache 2.0 license, as found in the `LICENSE`
file.