rustfmt: Add option to specify line ranges for formatting
This commit adds the `--experimental-file-lines` option to rustfmt. This allows specifying line ranges to format from the command line. Refs #434
This commit is contained in:
parent
9fa5a91fc5
commit
bef5d095a4
19
README.md
19
README.md
|
@ -73,6 +73,25 @@ the command line. For example `rustfmt --write-mode=display src/filename.rs`
|
||||||
|
|
||||||
`cargo fmt` uses `--write-mode=replace` by default.
|
`cargo fmt` uses `--write-mode=replace` by default.
|
||||||
|
|
||||||
|
If you want to restrict reformatting to specific sets of lines, you can
|
||||||
|
use the `--file-lines` option. Its argument is a JSON array of objects
|
||||||
|
with `file` and `range` properties, where `file` is a file name, and
|
||||||
|
`range` is an array representing a range of lines like `[7,13]`. Ranges
|
||||||
|
are inclusive of both end points. Specifying an empty array will result in
|
||||||
|
no files being formatted. For example,
|
||||||
|
|
||||||
|
```
|
||||||
|
rustfmt --file-lines '[
|
||||||
|
{"file":"src/lib.rs","range":[7,13]},
|
||||||
|
{"file":"src/lib.rs","range":[21,29]},
|
||||||
|
{"file":"src/foo.rs","range":[10,11]},
|
||||||
|
{"file":"src/foo.rs","range":[15,15]}]'
|
||||||
|
```
|
||||||
|
|
||||||
|
would format lines `7-13` and `21-29` of `src/lib.rs`, and lines `10-11`,
|
||||||
|
and `15` of `src/foo.rs`. No other files would be formatted, even if they
|
||||||
|
are included as out of line modules from `src/lib.rs`.
|
||||||
|
|
||||||
If `rustfmt` successfully reformatted the code it will exit with `0` exit
|
If `rustfmt` successfully reformatted the code it will exit with `0` exit
|
||||||
status. Exit status `1` signals some unexpected error, like an unknown option or
|
status. Exit status `1` signals some unexpected error, like an unknown option or
|
||||||
a failure to read a file. Exit status `2` is returned if there are syntax errors
|
a failure to read a file. Exit status `2` is returned if there are syntax errors
|
||||||
|
|
|
@ -18,6 +18,7 @@ extern crate env_logger;
|
||||||
extern crate getopts;
|
extern crate getopts;
|
||||||
|
|
||||||
use rustfmt::{run, Input, Summary};
|
use rustfmt::{run, Input, Summary};
|
||||||
|
use rustfmt::file_lines::FileLines;
|
||||||
use rustfmt::config::{Config, WriteMode};
|
use rustfmt::config::{Config, WriteMode};
|
||||||
|
|
||||||
use std::{env, error};
|
use std::{env, error};
|
||||||
|
@ -57,6 +58,7 @@ struct CliOptions {
|
||||||
skip_children: bool,
|
skip_children: bool,
|
||||||
verbose: bool,
|
verbose: bool,
|
||||||
write_mode: Option<WriteMode>,
|
write_mode: Option<WriteMode>,
|
||||||
|
file_lines: FileLines, // Default is all lines in all files.
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CliOptions {
|
impl CliOptions {
|
||||||
|
@ -73,12 +75,17 @@ impl CliOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if let Some(ref file_lines) = matches.opt_str("file-lines") {
|
||||||
|
options.file_lines = try!(file_lines.parse());
|
||||||
|
}
|
||||||
|
|
||||||
Ok(options)
|
Ok(options)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_to(&self, config: &mut Config) {
|
fn apply_to(self, config: &mut Config) {
|
||||||
config.skip_children = self.skip_children;
|
config.skip_children = self.skip_children;
|
||||||
config.verbose = self.verbose;
|
config.verbose = self.verbose;
|
||||||
|
config.file_lines = self.file_lines;
|
||||||
if let Some(write_mode) = self.write_mode {
|
if let Some(write_mode) = self.write_mode {
|
||||||
config.write_mode = write_mode;
|
config.write_mode = write_mode;
|
||||||
}
|
}
|
||||||
|
@ -168,6 +175,10 @@ fn make_opts() -> Options {
|
||||||
"Recursively searches the given path for the rustfmt.toml config file. If not \
|
"Recursively searches the given path for the rustfmt.toml config file. If not \
|
||||||
found reverts to the input file path",
|
found reverts to the input file path",
|
||||||
"[Path for the configuration file]");
|
"[Path for the configuration file]");
|
||||||
|
opts.optopt("",
|
||||||
|
"file-lines",
|
||||||
|
"Format specified line ranges. See README for more detail on the JSON format.",
|
||||||
|
"JSON");
|
||||||
|
|
||||||
opts
|
opts
|
||||||
}
|
}
|
||||||
|
@ -198,8 +209,12 @@ fn execute(opts: &Options) -> FmtResult<Summary> {
|
||||||
|
|
||||||
Ok(run(Input::Text(input), &config))
|
Ok(run(Input::Text(input), &config))
|
||||||
}
|
}
|
||||||
Operation::Format { files, config_path } => {
|
Operation::Format { mut files, config_path } => {
|
||||||
let options = try!(CliOptions::from_matches(&matches));
|
let options = try!(CliOptions::from_matches(&matches));
|
||||||
|
|
||||||
|
// Add any additional files that were specified via `--file-lines`.
|
||||||
|
files.extend(options.file_lines.files().cloned().map(PathBuf::from));
|
||||||
|
|
||||||
let mut config = Config::default();
|
let mut config = Config::default();
|
||||||
let mut path = None;
|
let mut path = None;
|
||||||
// Load the config path file if provided
|
// Load the config path file if provided
|
||||||
|
@ -227,7 +242,7 @@ fn execute(opts: &Options) -> FmtResult<Summary> {
|
||||||
config = config_tmp;
|
config = config_tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
options.apply_to(&mut config);
|
options.clone().apply_to(&mut config);
|
||||||
error_summary.add(run(Input::File(file), &config));
|
error_summary.add(run(Input::File(file), &config));
|
||||||
}
|
}
|
||||||
Ok(error_summary)
|
Ok(error_summary)
|
||||||
|
@ -306,8 +321,8 @@ fn determine_operation(matches: &Matches) -> FmtResult<Operation> {
|
||||||
Some(dir)
|
Some(dir)
|
||||||
});
|
});
|
||||||
|
|
||||||
// if no file argument is supplied, read from stdin
|
// if no file argument is supplied and `--file-lines` is not specified, read from stdin
|
||||||
if matches.free.is_empty() {
|
if matches.free.is_empty() && !matches.opt_present("file-lines") {
|
||||||
|
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
try!(io::stdin().read_to_string(&mut buffer));
|
try!(io::stdin().read_to_string(&mut buffer));
|
||||||
|
@ -318,6 +333,7 @@ fn determine_operation(matches: &Matches) -> FmtResult<Operation> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We append files from `--file-lines` later in `execute()`.
|
||||||
let files: Vec<_> = matches.free.iter().map(PathBuf::from).collect();
|
let files: Vec<_> = matches.free.iter().map(PathBuf::from).collect();
|
||||||
|
|
||||||
Ok(Operation::Format {
|
Ok(Operation::Format {
|
||||||
|
|
Loading…
Reference in a new issue