Skip to content

Commit f1a44c5

Browse files
Update width heuristic configuration (#4063)
1 parent 9ace1de commit f1a44c5

File tree

20 files changed

+645
-68
lines changed

20 files changed

+645
-68
lines changed

Configurations.md

+137-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,29 @@ To enable unstable options, set `unstable_features = true` in `rustfmt.toml` or
1717

1818
Below you find a detailed visual guide on all the supported configuration options of rustfmt:
1919

20+
## `array_width`
21+
22+
Maximum width of an array literal before falling back to vertical formatting.
23+
24+
- **Default value**: `60`
25+
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
26+
- **Stable**: Yes
27+
28+
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`width_heuristics`](#width_heuristics), but a value set directly for `array_width` will take precedence.
29+
30+
See also [`max_width`](#max_width) and [`width_heuristics`](#width_heuristics)
31+
32+
## `attr_fn_like_width`
33+
34+
Maximum width of the args of a function-like attributes before falling back to vertical formatting.
35+
36+
- **Default value**: `70`
37+
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
38+
- **Stable**: Yes
39+
40+
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`width_heuristics`](#width_heuristics), but a value set directly for `attr_fn_like_width` will take precedence.
41+
42+
See also [`max_width`](#max_width) and [`width_heuristics`](#width_heuristics)
2043

2144
## `binop_separator`
2245

@@ -272,6 +295,17 @@ where
272295
}
273296
```
274297

298+
## `chain_width`
299+
300+
Maximum width of a chain to fit on one line.
301+
302+
- **Default value**: `60`
303+
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
304+
- **Stable**: Yes
305+
306+
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`width_heuristics`](#width_heuristics), but a value set directly for `chain_width` will take precedence.
307+
308+
See also [`max_width`](#max_width) and [`width_heuristics`](#width_heuristics)
275309

276310
## `color`
277311

@@ -717,6 +751,17 @@ trait Lorem {
717751
}
718752
```
719753

754+
## `fn_call_width`
755+
756+
Maximum width of the args of a function call before falling back to vertical formatting.
757+
758+
- **Default value**: `60`
759+
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
760+
- **Stable**: Yes
761+
762+
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`width_heuristics`](#width_heuristics), but a value set directly for `fn_call_width` will take precedence.
763+
764+
See also [`max_width`](#max_width) and [`width_heuristics`](#width_heuristics)
720765

721766
## `fn_single_line`
722767

@@ -1881,6 +1926,18 @@ specific version of rustfmt is used in your CI, use this option.
18811926
- **Possible values**: any published version (e.g. `"0.3.8"`)
18821927
- **Stable**: No (tracking issue: [#3386](https://github.com/rust-lang/rustfmt/issues/3386))
18831928

1929+
## `single_line_if_else_max_width`
1930+
1931+
Maximum line length for single line if-else expressions. A value of `0` (zero) results in if-else expressions always being broken into multiple lines. Note this occurs when `width_heuristics` is set to `Off`.
1932+
1933+
- **Default value**: `50`
1934+
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
1935+
- **Stable**: Yes
1936+
1937+
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`width_heuristics`](#width_heuristics), but a value set directly for `single_line_if_else_max_width` will take precedence.
1938+
1939+
See also [`max_width`](#max_width) and [`width_heuristics`](#width_heuristics)
1940+
18841941
## `space_after_colon`
18851942

18861943
Leave a space after the colon.
@@ -2080,6 +2137,29 @@ fn main() {
20802137

20812138
See also: [`indent_style`](#indent_style).
20822139

2140+
## `struct_lit_width`
2141+
2142+
Maximum width in the body of a struct literal before falling back to vertical formatting. A value of `0` (zero) results in struct literals always being broken into multiple lines. Note this occurs when `width_heuristics` is set to `Off`.
2143+
2144+
- **Default value**: `18`
2145+
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
2146+
- **Stable**: Yes
2147+
2148+
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`width_heuristics`](#width_heuristics), but a value set directly for `struct_lit_width` will take precedence.
2149+
2150+
See also [`max_width`](#max_width), [`width_heuristics`](#width_heuristics), and [`struct_lit_single_line`](#struct_lit_single_line)
2151+
2152+
## `struct_variant_width`
2153+
2154+
Maximum width in the body of a struct variant before falling back to vertical formatting. A value of `0` (zero) results in struct literals always being broken into multiple lines. Note this occurs when `width_heuristics` is set to `Off`.
2155+
2156+
- **Default value**: `35`
2157+
- **Possible values**: any positive integer that is less than or equal to the value specified for [`max_width`](#max_width)
2158+
- **Stable**: Yes
2159+
2160+
By default this option is set as a percentage of [`max_width`](#max_width) provided by [`width_heuristics`](#width_heuristics), but a value set directly for `struct_variant_width` will take precedence.
2161+
2162+
See also [`max_width`](#max_width) and [`width_heuristics`](#width_heuristics)
20832163

20842164
## `tab_spaces`
20852165

@@ -2270,15 +2350,45 @@ fn main() {
22702350
}
22712351
```
22722352

2273-
## `use_small_heuristics`
2353+
## `width_heuristics`
2354+
2355+
This option can be used to simplify the management and bulk updates of the granular width configuration settings ([`fn_call_width`](#fn_call_width), [`attr_fn_like_width`](#attr_fn_like_width), [`struct_lit_width`](#struct_lit_width), [`struct_variant_width`](#struct_variant_width), [`array_width`](#array_width), [`chain_width`](#chain_width), [`single_line_if_else_max_width`](#single_line_if_else_max_width)), that respectively control when formatted constructs are multi-lined/vertical based on width.
22742356

2275-
Whether to use different formatting for items and expressions if they satisfy a heuristic notion of 'small'.
2357+
Note that explicitly provided values for the width configuration settings take precedence and override the calculated values determined by `width_heuristics`.
22762358

2277-
- **Default value**: `"Default"`
2278-
- **Possible values**: `"Default"`, `"Off"`, `"Max"`
2359+
- **Default value**: `"Scaled"`
2360+
- **Possible values**: `"Scaled"`, `"Off"`, `"Max"`
22792361
- **Stable**: Yes
22802362

2281-
#### `Default` (default):
2363+
#### `Scaled` (default):
2364+
When `width_heuristics` is set to `Scaled`, the values for the granular width settings are calculated as a ratio of the value for `max_width`.
2365+
2366+
The ratios are:
2367+
* [`fn_call_width`](#fn_call_width) - `60%`
2368+
* [`attr_fn_like_width`](#attr_fn_like_width) - `70%`
2369+
* [`struct_lit_width`](#struct_lit_width) - `18%`
2370+
* [`struct_variant_width`](#struct_variant_width) - `35%`
2371+
* [`array_width`](#array_width) - `60%`
2372+
* [`chain_width`](#chain_width) - `60%`
2373+
* [`single_line_if_else_max_width`](#single_line_if_else_max_width) - `50%`
2374+
2375+
For example when `max_width` is set to `100`, the width settings are:
2376+
* `fn_call_width=60`
2377+
* `attr_fn_like_width=70`
2378+
* `struct_lit_width=18`
2379+
* `struct_variant_width=35`
2380+
* `array_width=60`
2381+
* `chain_width=60`
2382+
* `single_line_if_else_max_width=50`
2383+
2384+
and when `max_width` is set to `200`:
2385+
* `fn_call_width=120`
2386+
* `attr_fn_like_width=140`
2387+
* `struct_lit_width=36`
2388+
* `struct_variant_width=70`
2389+
* `array_width=120`
2390+
* `chain_width=120`
2391+
* `single_line_if_else_max_width=100`
22822392

22832393
```rust
22842394
enum Lorem {
@@ -2309,6 +2419,7 @@ fn main() {
23092419
```
23102420

23112421
#### `Off`:
2422+
When `width_heuristics` is set to `Off`, the granular width settings are functionally disabled and ignored. See the documentation for the respective width config options for specifics.
23122423

23132424
```rust
23142425
enum Lorem {
@@ -2337,6 +2448,16 @@ fn main() {
23372448
```
23382449

23392450
#### `Max`:
2451+
When `width_heuristics` is set to `Max`, then each granular width setting is set to the same value as `max_width`.
2452+
2453+
So if `max_width` is set to `200`, then all the width settings are also set to `200`.
2454+
* `fn_call_width=200`
2455+
* `attr_fn_like_width=200`
2456+
* `struct_lit_width=200`
2457+
* `struct_variant_width=200`
2458+
* `array_width=200`
2459+
* `chain_width=200`
2460+
* `single_line_if_else_max_width=200`
23402461

23412462
```rust
23422463
enum Lorem {
@@ -2354,6 +2475,17 @@ fn main() {
23542475
}
23552476
```
23562477

2478+
2479+
See also:
2480+
* [`max_width`](#max_width)
2481+
* [`fn_call_width`](#fn_call_width)
2482+
* [`attr_fn_like_width`](#attr_fn_like_width)
2483+
* [`struct_lit_width`](#struct_lit_width)
2484+
* [`struct_variant_width`](#struct_variant_width)
2485+
* [`array_width`](#array_width)
2486+
* [`chain_width`](#chain_width)
2487+
* [`single_line_if_else_max_width`](#single_line_if_else_max_width)
2488+
23572489
## `use_try_shorthand`
23582490

23592491
Replace uses of the try! macro by the ? shorthand

rustfmt-core/rustfmt-config/src/config_type.rs

+106-13
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,15 @@ macro_rules! create_config {
9696
(self.0).$i.1 = true;
9797
(self.0).$i.2 = value;
9898
match stringify!($i) {
99-
"max_width" | "use_small_heuristics" => self.0.set_heuristics(),
99+
"max_width"
100+
| "width_heuristics"
101+
| "fn_call_width"
102+
| "single_line_if_else_max_width"
103+
| "attr_fn_like_width"
104+
| "struct_lit_width"
105+
| "struct_variant_width"
106+
| "array_width"
107+
| "chain_width" => self.0.set_heuristics(),
100108
"license_template_path" => self.0.set_license_template(),
101109
&_ => (),
102110
}
@@ -228,16 +236,24 @@ macro_rules! create_config {
228236
}
229237

230238
match key {
231-
"max_width" | "use_small_heuristics" => self.set_heuristics(),
239+
"max_width"
240+
| "width_heuristics"
241+
| "fn_call_width"
242+
| "single_line_if_else_max_width"
243+
| "attr_fn_like_width"
244+
| "struct_lit_width"
245+
| "struct_variant_width"
246+
| "array_width"
247+
| "chain_width" => self.set_heuristics(),
232248
"license_template_path" => self.set_license_template(),
233249
&_ => (),
234250
}
235251
}
236252

237253
#[allow(unreachable_pub)]
238254
pub fn is_hidden_option(name: &str) -> bool {
239-
const HIDE_OPTIONS: [&str; 6] = [
240-
"verbose", "verbose_diff", "file_lines", "width_heuristics",
255+
const HIDE_OPTIONS: [&str; 5] = [
256+
"verbose", "verbose_diff", "file_lines",
241257
"recursive", "print_misformatted_file_names",
242258
];
243259
HIDE_OPTIONS.contains(&name)
@@ -280,16 +296,93 @@ macro_rules! create_config {
280296
)+
281297
}
282298

299+
fn set_width_heuristics(&mut self, heuristics: WidthHeuristics) {
300+
let max_width = self.max_width.2;
301+
let get_width_value = |
302+
was_set: bool,
303+
override_value: usize,
304+
heuristic_value: usize,
305+
config_key: &str,
306+
| -> usize {
307+
if !was_set {
308+
return heuristic_value;
309+
}
310+
if override_value > max_width {
311+
eprintln!(
312+
"`{0}` cannot have a value that exceeds `max_width`. \
313+
`{0}` will be set to the same value as `max_width`",
314+
config_key,
315+
);
316+
return max_width;
317+
}
318+
override_value
319+
};
320+
321+
let fn_call_width = get_width_value(
322+
self.was_set().fn_call_width(),
323+
self.fn_call_width.2,
324+
heuristics.fn_call_width,
325+
"fn_call_width",
326+
);
327+
self.fn_call_width.2 = fn_call_width;
328+
329+
let attr_fn_like_width = get_width_value(
330+
self.was_set().attr_fn_like_width(),
331+
self.attr_fn_like_width.2,
332+
heuristics.attr_fn_like_width,
333+
"attr_fn_like_width",
334+
);
335+
self.attr_fn_like_width.2 = attr_fn_like_width;
336+
337+
let struct_lit_width = get_width_value(
338+
self.was_set().struct_lit_width(),
339+
self.struct_lit_width.2,
340+
heuristics.struct_lit_width,
341+
"struct_lit_width",
342+
);
343+
self.struct_lit_width.2 = struct_lit_width;
344+
345+
let struct_variant_width = get_width_value(
346+
self.was_set().struct_variant_width(),
347+
self.struct_variant_width.2,
348+
heuristics.struct_variant_width,
349+
"struct_variant_width",
350+
);
351+
self.struct_variant_width.2 = struct_variant_width;
352+
353+
let array_width = get_width_value(
354+
self.was_set().array_width(),
355+
self.array_width.2,
356+
heuristics.array_width,
357+
"array_width",
358+
);
359+
self.array_width.2 = array_width;
360+
361+
let chain_width = get_width_value(
362+
self.was_set().chain_width(),
363+
self.chain_width.2,
364+
heuristics.chain_width,
365+
"chain_width",
366+
);
367+
self.chain_width.2 = chain_width;
368+
369+
let single_line_if_else_max_width = get_width_value(
370+
self.was_set().single_line_if_else_max_width(),
371+
self.single_line_if_else_max_width.2,
372+
heuristics.single_line_if_else_max_width,
373+
"single_line_if_else_max_width",
374+
);
375+
self.single_line_if_else_max_width.2 = single_line_if_else_max_width;
376+
}
377+
283378
fn set_heuristics(&mut self) {
284-
if self.use_small_heuristics.2 == Heuristics::Default {
285-
let max_width = self.max_width.2;
286-
self.set().width_heuristics(WidthHeuristics::scaled(max_width));
287-
} else if self.use_small_heuristics.2 == Heuristics::Max {
288-
let max_width = self.max_width.2;
289-
self.set().width_heuristics(WidthHeuristics::set(max_width));
290-
} else {
291-
self.set().width_heuristics(WidthHeuristics::null());
292-
}
379+
let max_width = self.max_width.2;
380+
match self.width_heuristics.2 {
381+
Heuristics::Scaled =>
382+
self.set_width_heuristics(WidthHeuristics::scaled(max_width)),
383+
Heuristics::Max => self.set_width_heuristics(WidthHeuristics::set(max_width)),
384+
Heuristics::Off => self.set_width_heuristics(WidthHeuristics::null()),
385+
};
293386
}
294387

295388
fn set_license_template(&mut self) {

0 commit comments

Comments
 (0)