Formatters are the cosmetic counterpart to validators. After every mutating op — edit, replace, replace_lines, paste, vim — supertool runs the matching formatters against the result file, normalizing whitespace, quotes, and import order before validators check correctness.
Run order:
edit → formatter(s) → validator(s) → rollback if validate fails
Formatters mutate the file in place (e.g. prettier --write, gofmt -w). Validators then see the canonical, formatted result — so the diff the model gets reflects real structural changes, not noise from trailing spaces or quote style.
Each formatter entry declares a hooks_into array listing the mutating ops it should run after — same as validators:
"hooks_into": ["edit", "replace", "replace_lines", "paste", "vim"]Formatters are declared per-file-type in .supertool.json under formatters, keyed by formatter name. Each entry matches files via a match glob:
{
"formatters": {
"prettier": {
"cmd": "prettier --write {file}",
"match": "*.{xml,scss,css,js,json,yml,yaml,md}",
"hooks_into": ["edit", "replace", "replace_lines", "paste", "vim"],
"rollback_on_fail": false,
"timeout": 30
}
}
}Enable any of these by copying the relevant entry from .supertool.example.json into your project's .supertool.json.
| Language / format | Formatter name | Requires | Notes |
|---|---|---|---|
| XML, SCSS, CSS, JS, JSON, YAML, Markdown | prettier |
prettier npm package |
npm install -g prettier |
| Python | black |
black pip package |
pip install black |
| Go | gofmt |
Go toolchain | Ships with Go — no extra install |
| Rust | rustfmt |
Rust toolchain | Ships with rustup — rustup component add rustfmt |
| PHP (PSR-12) | phpcbf |
PHP_CodeSniffer via Composer | composer global require squizlabs/php_codesniffer |
| Bash / shell | shfmt |
shfmt binary |
brew install shfmt / go install mvdan.cc/sh/v3/cmd/shfmt@latest |
| Terraform / HCL | terraform-fmt |
Terraform CLI | Ships with Terraform — brew install terraform |
| Ruby | rubocop |
RuboCop gem | gem install rubocop; -a = auto-fix only |
Any tool that rewrites the file in place works. Three lines of JSON and a new language is supported.
Examples:
"gofmt": {
"cmd": "gofmt -w {file}",
"match": "*.go",
"hooks_into": ["edit", "replace", "replace_lines", "paste", "vim"],
"rollback_on_fail": false,
"timeout": 10
}"black": {
"cmd": "black {file}",
"match": "*.py",
"hooks_into": ["edit", "replace", "replace_lines", "paste", "vim"],
"rollback_on_fail": false,
"timeout": 10
}"rustfmt": {
"cmd": "rustfmt {file}",
"match": "*.rs",
"hooks_into": ["edit", "replace", "replace_lines", "paste", "vim"],
"rollback_on_fail": false,
"timeout": 15
}"phpcbf": {
"cmd": "phpcbf {file}",
"match": "*.php",
"hooks_into": ["edit", "replace", "replace_lines", "paste", "vim"],
"rollback_on_fail": false,
"timeout": 15
}The {file} placeholder is replaced with the absolute path to the file being formatted. {supertool_dir} is also available for pointing at local wrapper scripts.
| Aspect | Formatters | Validators |
|---|---|---|
| Purpose | Normalize style (cosmetic) | Check correctness (safety) |
| Mutates file | Yes — rewrites in place | No — read-only |
rollback_on_fail |
Default false |
Default true (recommended) |
| Run order | First (after edit) | Second (after formatters) |
| Output | Warns on failure, continues | Diff block + optional rollback |
rollback_on_fail: false is the right default for formatters. If prettier chokes on a file that's structurally valid, the edit should still land — the validator is the safety net. Set rollback_on_fail: true only if you want a formatter failure to revert the file entirely.
When the underlying tool is missing (e.g. prettier not installed), the formatter warns and continues. No formatter failure blocks an unrelated edit. The project stays fully usable without pre-installed dependencies.
Full list of .supertool.json formatter config fields:
| Field | Notes |
|---|---|
cmd |
Shell command. {file} → target path. {supertool_dir} → supertool install dir. |
match |
Glob filter on the target path (default *). |
hooks_into |
Op names to wrap (subset of edit, replace, replace_lines, paste, vim). |
rollback_on_fail |
Restore pre-edit file content if the formatter fails. Default false. |
timeout |
Seconds. Default 30. |
After an edit on a .json file with prettier configured:
edited: src/config.json
[formatters]
[formatter] prettier: some warning message
When the formatter succeeds silently (the normal case), no formatter block appears — the output is clean.