Skip to content

Commit 79c5ee8

Browse files
committed
Add config options for formatting macro matchers and bodies
Closes #2753
1 parent b27d544 commit 79c5ee8

File tree

3 files changed

+108
-15
lines changed

3 files changed

+108
-15
lines changed

Configurations.md

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1006,6 +1006,76 @@ fn main() {
10061006

10071007
See also [`max_width`](#max_width).
10081008

1009+
## `format_macro_matchers`
1010+
1011+
Format the metavariable matching patterns in macros.
1012+
1013+
- **Default value**: `false`
1014+
- **Possible values**: `true`, `false`
1015+
- **Stable**: No
1016+
1017+
#### `false` (default):
1018+
1019+
```rust
1020+
macro_rules! foo {
1021+
($a: ident : $b: ty) => {
1022+
$a(42): $b;
1023+
};
1024+
($a: ident $b: ident $c: ident) => {
1025+
$a = $b + $c;
1026+
};
1027+
}
1028+
```
1029+
1030+
#### `true`:
1031+
1032+
```rust
1033+
macro_rules! foo {
1034+
($a:ident : $b:ty) => {
1035+
$a(42): $b;
1036+
};
1037+
($a:ident $b:ident $c:ident) => {
1038+
$a = $b + $c;
1039+
};
1040+
}
1041+
```
1042+
1043+
See also [`format_macro_bodies`](#format_macro_bodies).
1044+
1045+
1046+
## `format_macro_bodies`
1047+
1048+
Format the bodies of macros.
1049+
1050+
- **Default value**: `true`
1051+
- **Possible values**: `true`, `false`
1052+
- **Stable**: No
1053+
1054+
#### `true` (default):
1055+
1056+
```rust
1057+
macro_rules! foo {
1058+
($a:ident : $b:ty) => {
1059+
$a(42): $b;
1060+
};
1061+
($a:ident $b:ident $c:ident) => {
1062+
$a = $b + $c;
1063+
};
1064+
}
1065+
```
1066+
1067+
#### `false`:
1068+
1069+
```rust
1070+
macro_rules! foo {
1071+
($a:ident : $b:ty) => { $a(42): $b; };
1072+
($a:ident $b:ident $c:ident) => { $a=$b+$c; };
1073+
}
1074+
```
1075+
1076+
See also [`format_macro_matchers`](#format_macro_matchers).
1077+
1078+
10091079
## `hard_tabs`
10101080

10111081
Use tab characters for indentation, spaces for alignment

src/config/mod.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,20 @@ create_config! {
4242
tab_spaces: usize, 4, true, "Number of spaces per tab";
4343
newline_style: NewlineStyle, NewlineStyle::Native, true, "Unix or Windows line endings";
4444
use_small_heuristics: Heuristics, Heuristics::Default, true, "Whether to use different \
45-
formatting for items and expressions if they satisfy a heuristic notion of 'small'.";
46-
indent_style: IndentStyle, IndentStyle::Block, false, "How do we indent expressions or items.";
45+
formatting for items and expressions if they satisfy a heuristic notion of 'small'";
46+
indent_style: IndentStyle, IndentStyle::Block, false, "How do we indent expressions or items";
4747

48-
// Comments and strings
48+
// Comments. macros, and strings
4949
wrap_comments: bool, false, false, "Break comments to fit on the line";
5050
comment_width: usize, 80, false,
5151
"Maximum length of comments. No effect unless wrap_comments = true";
5252
normalize_comments: bool, false, false, "Convert /* */ comments to // comments where possible";
5353
license_template_path: String, String::default(), false,
5454
"Beginning of file must match license template";
5555
format_strings: bool, false, false, "Format string literals where necessary";
56+
format_macro_matchers: bool, true, false,
57+
"Format the metavariable matching patterns in macros";
58+
format_macro_bodies: bool, true, false, "Format the bodies of macros";
5659

5760
// Single line expressions and items
5861
empty_item_single_line: bool, true, false,
@@ -79,13 +82,13 @@ create_config! {
7982
space_after_colon: bool, true, false, "Leave a space after the colon";
8083
spaces_around_ranges: bool, false, false, "Put spaces around the .. and ..= range operators";
8184
binop_separator: SeparatorPlace, SeparatorPlace::Front, false,
82-
"Where to put a binary operator when a binary expression goes multiline.";
85+
"Where to put a binary operator when a binary expression goes multiline";
8386

8487
// Misc.
85-
remove_nested_parens: bool, true, true, "Remove nested parens.";
86-
combine_control_expr: bool, true, false, "Combine control expressions with function calls.";
88+
remove_nested_parens: bool, true, true, "Remove nested parens";
89+
combine_control_expr: bool, true, false, "Combine control expressions with function calls";
8790
struct_field_align_threshold: usize, 0, false, "Align struct fields if their diffs fits within \
88-
threshold.";
91+
threshold";
8992
match_arm_blocks: bool, true, false, "Wrap the body of arms in blocks when it does not fit on \
9093
the same line with the pattern of arms";
9194
force_multiline_blocks: bool, false, false,
@@ -101,10 +104,10 @@ create_config! {
101104
match_block_trailing_comma: bool, false, false,
102105
"Put a trailing comma after a block based match arm (non-block arms are not affected)";
103106
blank_lines_upper_bound: usize, 1, false,
104-
"Maximum number of blank lines which can be put between items.";
107+
"Maximum number of blank lines which can be put between items";
105108
blank_lines_lower_bound: usize, 0, false,
106-
"Minimum number of blank lines which must be put between items.";
107-
edition: Edition, Edition::Edition2015, false, "The edition of the parser. (RFC 2052)";
109+
"Minimum number of blank lines which must be put between items";
110+
edition: Edition, Edition::Edition2015, false, "The edition of the parser (RFC 2052)";
108111

109112
// Options that can change the source code beyond whitespace/blocks (somewhat linty things)
110113
merge_derives: bool, true, true, "Merge multiple `#[derive(...)]` into a single one";
@@ -118,7 +121,7 @@ create_config! {
118121
color: Color, Color::Auto, false,
119122
"What Color option to use when none is supplied: Always, Never, Auto";
120123
required_version: String, env!("CARGO_PKG_VERSION").to_owned(), false,
121-
"Require a specific version of rustfmt.";
124+
"Require a specific version of rustfmt";
122125
unstable_features: bool, false, false,
123126
"Enables unstable features. Only available on nightly channel";
124127
disable_all_formatting: bool, false, false, "Don't reformat anything";
@@ -133,7 +136,7 @@ create_config! {
133136
report_fixme: ReportTactic, ReportTactic::Never, false,
134137
"Report all, none or unnumbered occurrences of FIXME in source file comments";
135138
ignore: IgnoreList, IgnoreList::default(), false,
136-
"Skip formatting the specified files and directories.";
139+
"Skip formatting the specified files and directories";
137140

138141
// Not user-facing
139142
verbose: Verbosity, Verbosity::Normal, false, "How much to information to emit to the user";

src/macros.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -938,10 +938,22 @@ fn format_macro_args(
938938
toks: ThinTokenStream,
939939
shape: Shape,
940940
) -> Option<String> {
941+
if !context.config.format_macro_matchers() {
942+
let token_stream: TokenStream = toks.into();
943+
let span = span_for_token_stream(token_stream);
944+
return Some(match span {
945+
Some(span) => context.snippet(span).to_owned(),
946+
None => String::new(),
947+
});
948+
}
941949
let parsed_args = MacroArgParser::new().parse(toks)?;
942950
wrap_macro_args(context, &parsed_args, shape)
943951
}
944952

953+
fn span_for_token_stream(token_stream: TokenStream) -> Option<Span> {
954+
token_stream.trees().next().map(|tt| tt.span())
955+
}
956+
945957
// We should insert a space if the next token is a:
946958
#[derive(Copy, Clone, PartialEq)]
947959
enum SpaceState {
@@ -1172,13 +1184,14 @@ impl MacroParser {
11721184
TokenTree::Token(_, Token::FatArrow) => {}
11731185
_ => return None,
11741186
}
1175-
let (mut hi, body) = match self.toks.next()? {
1187+
let (mut hi, body, whole_body) = match self.toks.next()? {
11761188
TokenTree::Token(..) => return None,
11771189
TokenTree::Delimited(sp, _) => {
11781190
let data = sp.data();
11791191
(
11801192
data.hi,
11811193
Span::new(data.lo + BytePos(1), data.hi - BytePos(1), data.ctxt),
1194+
sp,
11821195
)
11831196
}
11841197
};
@@ -1191,6 +1204,7 @@ impl MacroParser {
11911204
args_paren_kind,
11921205
args,
11931206
body,
1207+
whole_body,
11941208
})
11951209
}
11961210
}
@@ -1207,6 +1221,7 @@ struct MacroBranch {
12071221
args_paren_kind: DelimToken,
12081222
args: ThinTokenStream,
12091223
body: Span,
1224+
whole_body: Span,
12101225
}
12111226

12121227
impl MacroBranch {
@@ -1229,6 +1244,12 @@ impl MacroBranch {
12291244
result += " =>";
12301245
}
12311246

1247+
if !context.config.format_macro_bodies() {
1248+
result += " ";
1249+
result += context.snippet(self.whole_body);
1250+
return Some(result);
1251+
}
1252+
12321253
// The macro body is the most interesting part. It might end up as various
12331254
// AST nodes, but also has special variables (e.g, `$foo`) which can't be
12341255
// parsed as regular Rust code (and note that these can be escaped using
@@ -1237,14 +1258,13 @@ impl MacroBranch {
12371258

12381259
let old_body = context.snippet(self.body).trim();
12391260
let (body_str, substs) = replace_names(old_body)?;
1261+
let has_block_body = old_body.starts_with('{');
12401262

12411263
let mut config = context.config.clone();
12421264
config.set().hide_parse_errors(true);
12431265

12441266
result += " {";
12451267

1246-
let has_block_body = old_body.starts_with('{');
1247-
12481268
let body_indent = if has_block_body {
12491269
shape.indent
12501270
} else {

0 commit comments

Comments
 (0)