Skip to content

Update documentation #4345

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 28, 2020
Merged
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
142 changes: 76 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
# rustfmt [![Linux badge][linux-build-status]][linux-build] [![Mac badge][mac-build-status]][mac-build] [![Windows badge][windows-build-status]][windows-build] [![crates.io badge][cratesio-badge]][cratesio-package] [![Travis config badge][travis-config-badge]][travis-config-job]

<!-- To update: doctoc README.md --notitle -->
<!-- https://github.com/thlorenz/doctoc -->
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->


- [Quick start](#quick-start)
- [On the Stable toolchain](#on-the-stable-toolchain)
- [On the Nightly toolchain](#on-the-nightly-toolchain)
- [Installing from source](#installing-from-source)
- [Running](#running)
- [Configuring Rustfmt](#configuring-rustfmt)
- [Rust's Editions](#rusts-editions)
- [Limitations](#limitations)
- [Running Rustfmt from your editor](#running-rustfmt-from-your-editor)
- [Checking style on a CI server](#checking-style-on-a-ci-server)
- [How to build and test](#how-to-build-and-test)
- [Tips](#tips)
- [License](#license)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

A tool for formatting Rust code according to style guidelines.

If you'd like to help out (and you should, it's a fun project!), see
Expand Down Expand Up @@ -45,42 +67,7 @@ To run on a cargo project in the current working directory:
cargo +nightly fmt
```

## Limitations

Rustfmt tries to work on as much Rust code as possible. Sometimes, the code
doesn't even need to compile! As we approach a 1.0 release we are also looking
to limit areas of instability; in particular, post-1.0, the formatting of most
code should not change as Rustfmt improves. However, there are some things that
Rustfmt can't do or can't do well (and thus where formatting might change
significantly, even post-1.0). We would like to reduce the list of limitations
over time.

The following list enumerates areas where Rustfmt does not work or where the
stability guarantees do not apply (we don't make a distinction between the two
because in the future Rustfmt might work on code where it currently does not):

* a program where any part of the program does not parse (parsing is an early
stage of compilation and in Rust includes macro expansion).
* Macro declarations and uses (current status: some macro declarations and uses
are formatted).
* Comments, including any AST node with a comment 'inside' (Rustfmt does not
currently attempt to format comments, it does format code with comments inside, but that formatting may change in the future).
* Rust code in code blocks in comments.
* Any fragment of a program (i.e., stability guarantees only apply to whole
programs, even where fragments of a program can be formatted today).
* Code containing non-ascii unicode characters (we believe Rustfmt mostly works
here, but do not have the test coverage or experience to be 100% sure).
* Bugs in Rustfmt (like any software, Rustfmt has bugs, we do not consider bug
fixes to break our stability guarantees).


## Installation

```sh
rustup component add rustfmt
```

## Installing from source
### Installing from source

To install from source (nightly required), first checkout to the tag or branch for the version of rustfmt you want.

Expand All @@ -102,25 +89,75 @@ cargo install --path . --force --locked --features rustfmt,cargo-fmt
This will install `rustfmt` in your `~/.cargo/bin`. Make sure to add `~/.cargo/bin` directory to
your PATH variable.


## Running

You can run `rustfmt --help` for information about available arguments.

You can run Rustfmt by just typing `rustfmt filename` if you used `cargo
install`. This runs rustfmt on the given file, if the file includes out of line
modules, then we reformat those too. So to run on a whole module or crate, you
just need to run on the root file (usually mod.rs or lib.rs). Rustfmt can also
read data from stdin. Alternatively, you can use `cargo fmt` to format all
binary and library targets of your crate.
Comment on lines +94 to 101
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 the section that I'm most interested in updating to address #4336

There's items in the current text that are strictly not true, like the if the file includes out of line modules, then we reformat those too which is quite false with rustfmt 2.0 (so relevant for anyone building from source). Then there's other items like the if you used cargo install clause in the first sentence feels a bit dated/out of place (rustfmt filename is available regardless of whether you used rustup, installed from crates.io, or build from source).

Here's a high level framing and order of the items that IMO we should call out here, let me know what you think

  1. cargo fmt is the easiest way to run rustfmt against your entire project and is the general recommendation, worth calling out cargo fmt --help. this is true for single-crate projects, but also cargo workspaces (not sure we necessarily need to call that out here)
  2. Less commonly used, but rustfmt can also be used directly to format files (rustfmt foo.rs bar.rs) or via stdin, but want to highlight the stdin bit more than the current text does
    a. rustfmt 1.x will format out of line mods by default, so rustfmt rootfile will basically format the entire project
    b. rustfmt 2.x does not format out of line mods by default, requires --recursive flag

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That sounds great to me, are you okay with the addition of this in a followup PR where I will also add changes to the running section?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah that's fine, but will want to keep #4336 open til after that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

sgtm


You can run `rustfmt --help` for information about available arguments.

When running with `--check`, Rustfmt will exit with `0` if Rustfmt would not
make any formatting changes to the input, and `1` if Rustfmt would make changes.
In other modes, Rustfmt will exit with `1` if there was some error during
formatting (for example a parsing or internal error) and `0` if formatting
completed without error (whether or not changes were made).

## Configuring Rustfmt

Rustfmt is designed to be very configurable. You can create a TOML file called
`rustfmt.toml` or `.rustfmt.toml`, place it in the project or any other parent
directory and it will apply the options in that file. See `rustfmt
--help=config` for the options which are available, or if you prefer to see
visual style previews, [GitHub page](https://rust-lang.github.io/rustfmt/).

By default, Rustfmt uses a style which conforms to the [Rust style guide][style
guide] that has been formalized through the [style RFC
process][fmt rfcs].

Configuration options are either stable or unstable. Stable options can always
be used on any channel. Unstable options are always available on nightly, but can only be used on stable and beta with an explicit opt-in (starting in Rustfmt v2.0).

Unstable options are not available on stable/beta with Rustfmt v1.x.

See the configuration documentation on the Rustfmt [GitHub page](https://rust-lang.github.io/rustfmt/) for details (look for the `unstable_features` section).

### Rust's Editions

Rustfmt is able to pick up the edition used by reading the `Cargo.toml` file if
executed through the Cargo's formatting tool `cargo fmt`. Otherwise, the edition
needs to be specified in `rustfmt.toml`, e.g., with `edition = "2018"`.

## Limitations

Rustfmt tries to work on as much Rust code as possible. Sometimes, the code
doesn't even need to compile! As we approach a 1.0 release we are also looking
to limit areas of instability; in particular, post-1.0, the formatting of most
code should not change as Rustfmt improves. However, there are some things that
Rustfmt can't do or can't do well (and thus where formatting might change
significantly, even post-1.0). We would like to reduce the list of limitations
over time.

The following list enumerates areas where Rustfmt does not work or where the
stability guarantees do not apply (we don't make a distinction between the two
because in the future Rustfmt might work on code where it currently does not):

* a program where any part of the program does not parse (parsing is an early
stage of compilation and in Rust includes macro expansion).
* Macro declarations and uses (current status: some macro declarations and uses
are formatted).
* Comments, including any AST node with a comment 'inside' (Rustfmt does not
currently attempt to format comments, it does format code with comments inside, but that formatting may change in the future).
* Rust code in code blocks in comments.
* Any fragment of a program (i.e., stability guarantees only apply to whole
programs, even where fragments of a program can be formatted today).
* Code containing non-ascii unicode characters (we believe Rustfmt mostly works
here, but do not have the test coverage or experience to be 100% sure).
* Bugs in Rustfmt (like any software, Rustfmt has bugs, we do not consider bug
fixes to break our stability guarantees).

## Running Rustfmt from your editor

Expand All @@ -131,7 +168,6 @@ completed without error (whether or not changes were made).
* Visual Studio Code using [vscode-rust](https://github.com/editor-rs/vscode-rust), [vsc-rustfmt](https://github.com/Connorcpu/vsc-rustfmt) or [rls_vscode](https://github.com/jonathandturner/rls_vscode) through RLS.
* [IntelliJ or CLion](intellij.md)


## Checking style on a CI server

To keep your code base consistently formatted, it can be helpful to fail the CI build
Expand Down Expand Up @@ -197,32 +233,6 @@ CFG_RELEASE_CHANNEL=nightly CFG_RELEASE=1.45.0-nightly cargo test --all-features
To run rustfmt after this, use `cargo run --bin rustfmt -- filename`. See the
notes above on running rustfmt.


## Configuring Rustfmt

Rustfmt is designed to be very configurable. You can create a TOML file called
`rustfmt.toml` or `.rustfmt.toml`, place it in the project or any other parent
directory and it will apply the options in that file. See `rustfmt
--help=config` for the options which are available, or if you prefer to see
visual style previews, [GitHub page](https://rust-lang.github.io/rustfmt/).

By default, Rustfmt uses a style which conforms to the [Rust style guide][style
guide] that has been formalized through the [style RFC
process][fmt rfcs].

Configuration options are either stable or unstable. Stable options can always
be used on any channel. Unstable options are always available on nightly, but can only be used on stable and beta with an explicit opt-in (starting in Rustfmt v2.0).

Unstable options are not available on stable/beta with Rustfmt v1.x.

See the configuration documentation on the Rustfmt [GitHub page](https://rust-lang.github.io/rustfmt/) for details (look for the `unstable_features` section).

### Rust's Editions

Rustfmt is able to pick up the edition used by reading the `Cargo.toml` file if
executed through the Cargo's formatting tool `cargo fmt`. Otherwise, the edition
needs to be specified in `rustfmt.toml`, e.g., with `edition = "2018"`.

## Tips

* For things you do not want rustfmt to mangle, use `#[rustfmt::skip]`
Expand Down
3 changes: 3 additions & 0 deletions src/cargo-fmt/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ pub struct Opts {
message_format: Option<String>,

/// Options passed to rustfmt
///
/// To see all rustfmt options, run `rustfmt --help'.
/// To see all rustfmt configuration options, please visit https://rust-lang.github.io/rustfmt.
// 'raw = true' to make `--` explicit.
#[structopt(name = "rustfmt_options", raw(true))]
rustfmt_options: Vec<String>,
Expand Down
28 changes: 26 additions & 2 deletions src/rustfmt/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,30 @@ fn main() {

/// Format Rust code
#[derive(Debug, StructOpt, Clone)]
#[structopt(name = "rustfmt", version = include_str!(concat!(env!("OUT_DIR"),"/version-info.txt")))]
#[structopt(
name = "rustfmt",
version = include_str!(concat!(env!("OUT_DIR"),"/version-info.txt")),
about = r#"Format Rust code

Rustfmt runs on a set of files or stdin. When invoked without any file arguments, rustfmt will
read code from stdin.

Please visit https://rust-lang.github.io/rustfmt to see all rustfmt configuration options.

EXAMPLES

cat lib.rs | rustfmt
Feed the contents of "lib.rs" to rustfmt via stdin

rustfmt lib.rs main.rs
Run rustfmt over "lib.rs" and "main.rs", formatting in-place.

rustfmt --emit=stdout lib.rs main.rs
Run rustfmt over "lib.rs" and "main.rs", writing to stdout (rather than in-place)

rustfmt --config-path=rustfmt.toml --print-config=current
Print the resolved rustfmt configuration formed by rustfmt.toml
"#)]
struct Opt {
/// Run in 'check' mode.
///
Expand All @@ -60,7 +83,8 @@ struct Opt {
config_path: Option<PathBuf>,
/// Rust compiler edition
///
/// Specify which edition of the compiler to use when formatting code.
/// Specify which edition of the compiler to use when formatting code. This behaves identically
/// to the "edition" configuration option.
#[structopt(long, name = "2015|2018")]
edition: Option<Edition>,
/// Print configuration options.
Expand Down