# rebar3_format
A rebar plugin for code formatting
## Build
$ rebar3 compile
## Use
Add the plugin to your rebar config:
```erlang
{plugins, [rebar3_format]}
```
Then just call your plugin directly in an existing application:
$ rebar3 format
This will format every Erlang file under `/src` by default. You can specify the directory/file to format as following:
$ rebar3 format --files src/my_subdir/*.erl
$ rebar3 format --files src/other_subdir/my_file.erl
$ rebar3 format --files test/**/*.erl
To save the formatted files in a different directory you have to pass it as a parameter:
$ rebar3 format --output formatted/
## Configuration
The plugin supports the following configuration options in the `format` section of `rebar.config`:
* `formatter` (`module()`):
- This is the module that will dictate the style in which all the code will be formatted. It must implement the `rebar3_formatter` behavior. This project itself provides 2 formatters:
+ `otp_formatter`: Based on the default formatter that comes with Erlang/OTP (`erl_prettypr`), we only fixed some bugs but then respected the original format it produced in its entirety. This formatter only recognizes 2 options:
* `paper`(`pos_integer()`):
- Specifies the preferred maximum number of characters on any line, including indentation.
- The default value is `80`.
* `ribbon`(`pos_integer()`):
- Specifies the preferred maximum number of characters on any line, not counting indentation.
- The default value is `56`.
+ `default_formatter`: Our own default formatter, defining our personal criteria for how to stylize Erlang code. It admits all the options listed below.
- The default value is `default_formatter`.
* `options` (`#{atom() => term()}`):
- A map with a list of options that should be interpreted by the chosen `formatter`. The available keys are:
+ `encoding`(`none | epp:source_encoding()`):
* Encoding to use when writing files.
* The default value is `none`.
+ `paper`(`pos_integer()`):
* Specifies the preferred maximum number of characters on any line, including indentation.
* The default value is `100`.
+ `ribbon`(`pos_integer()`):
* Specifies the preferred maximum number of characters on any line, not counting indentation.
* The default value is `90`.
+ `break_indent`(`pos_integer()`):
* Specifies the preferred number of characters to use to indent a line that "breaks" from the previous one (for instance, a clause body after a clause head).
* The default value is `4`.
+ `sub_indent`(`pos_integer()`):
* Specifies the preferred number of characters to use to indent a line that "follows" the current one (for instance, a long clause head or a long function application).
* The default value is `2`.
+ `inline_items` (`all | none | {when_over, pos_integer()}`):
* Specifies the desired behavior when using multiple lines for a multi-item structure (i.e. tuple, list, map, etc.).
* When this option is `all`, the formatter will try to fit as many items in each line as permitted by `paper` and `ribbon`.
* When the flag is `none`, the formatter will place each item in its own line.
* When the flag is `{when_over, N}` the formatter will work as `none` for lists with up to `N` elements, and it will inline longer lists.
* The default value is `{when_over, 25}` to properly accommodate large binaries or lists.
+ `inline_clause_bodies` (`boolean()`):
* Specifies if clause bodies (for `case`, `function`, etc. statements) should be placed in the same line as the clause heads if `paper` and `ribbon` allows it or if all bodies should be placed in the next line after their clause heads.
* The default value is `false`.
+ `inline_expressions` (`boolean()`):
* Specifies if sequential expressions in a clause should be placed in the same line if `paper` and `ribbon` allows it or if each expression should be placed in its own line.
* The default value is `false`.
+ `preserve_empty_lines` (`boolean()`):
* Specifies if blank lines should be preserved when formatting.
* This option is only used when `inline_expressions` is `false`.
* If this option is `true`, one empty line will preserved for each group of empty lines that are placed between expressions in a clause.
* The default value is `true`.
* `files` (`[file:filename_all()]`):
- List of wildcard patterns representing the files that will be formatted by default (i.e. when not using `--files` on command line).
- The default value is `["src/**/*.?rl"]`
### Per-File Configuration
You can tweak any of the formatter options for a particular file, using the `format` attribute in it, like this:
```erlang
-format(#{paper => 80}).
```
## Test
To test the plugin just run `rebar3 test`.
It will essentially run `rebar3 format` inside `test_app`.
Add modules with any "tricky" formatting you want to `test_app/src`, and push them to github _including_ the `after` results.
The `after` results can be tought as the **expected output** behaviour.
## Contribute
To contribute to rebar3_format, please refer to [CONTRIBUTING](CONTRIBUTING.md).