Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docs/site/reference/formatter-spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ The formatter's CLI must be of the form:
Where:

- `<command>` is the name of the formatter executable.
- `[options]` is any number of flags and options that the formatter accepts.
- `[...<files>]` is one or more files given to the formatter for processing.
- `[options]` are any number of flags and options that the formatter accepts.
- `[...<files>]` are one or more files given to the formatter for processing.

Example:

Expand Down
55 changes: 55 additions & 0 deletions docs/site/reference/stdin-spec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
outline: deep
---

# Stdin Specification

Formatters **MAY** also implement the Stdin Specification, which allows
formatting "virtual files" passed via stdin.
Comment on lines +7 to +8
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How is this support expressed in the treefmt.toml config?

Copy link
Collaborator Author

@jfly jfly Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking we'd add a new formatter.<mylanguage>.stdin (or stdin_supported) bool that defaults to false if unspecified. Feedback appreciated.

Do you think the stdin spec is the place to put this? I was thinking this would go in our config docs.


A formatter **MUST** implement the Stdin Specification if its formatting behavior
can depend on the name of the file being formatted.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a bit hard to read

Copy link
Collaborator Author

@jfly jfly Aug 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, but I don't know how to fix it. Does flipping the sentence around help? Suggestions appreciated.

If a formatter's behavior can depend on the name of the file being formatted, then it MUST implement the Stdin Specification.


## Rules

In order for the formatter to comply with this spec, it **MUST** implement the
vanilla [Formatter Specification](/reference/formatter-spec), and additionally
satisfy the following:

### 1. `--stdin-filepath` flag
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
### 1. `--stdin-filepath` flag
### 1. `--stdin` flag

KISS?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm lightly opposed to this, for 2 reasons:

  1. I think --stdin-filepath is clearer that the option takes a value.
  2. treefmt itself currently implements a --stdin flag with different semantics, and I would like for treefmt to implement the new stdin spec. Changing this might be awkward?

WDYT?


The formatter's CLI **MUST** be of the form:

```
<command> [options] [--stdin-filepath <path>]
```

Where:

- `<command>` is the name of the formatting tool.
- `[options]` are any number of flags and options that the formatter accepts.
- `--stdin-filepath <path>` is an optional flag that puts the formatter in
"stdin mode". In stdin mode, the formatter reads file contents from stdin
rather than the filesystem.
- The formatter _MAY_ alter its behavior based on the given `<path>`. For
example, if a there are different formatting rules in different
directories. If the formatter's behavior doesn't depend on the given
`<path>`, it's ok to ignore it.
- The formatter _MAY_ understand `--stdin-filepath=<path>` as well, but **MUST**
understand the space separated variant.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would make sense to outline the purpose of the <path> argument explicitly. Both you and I know why it's there, but maybe not the reader.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the path argument is not needed by the tool, it's also valid to ignore it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've taken a stab at this. Please take a look.


Example:

```
$ echo "{}" | nixfmt --stdin-filepath path/to/file.nix
```

### 2. Print to stdout, do not assume file is present on filesystem

When in stdin mode, the formatter:

1. **MUST** print the formatted file to stdout.
2. **MUST NOT** attempt to read the file on the filesystem. Instead, it
**MUST** read from stdin.
3. **MUST NOT** write to the given path on the filesytem. It _MAY_ write to
temporary files elsewhere on disk, but _SHOULD_ clean them up when done.