Skip to content

Commit 69c35a2

Browse files
feat(config): expose all width heurstic options
1 parent cbacfff commit 69c35a2

File tree

3 files changed

+147
-35
lines changed

3 files changed

+147
-35
lines changed

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

Lines changed: 101 additions & 13 deletions
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,88 @@ 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+
panic!("`{}` cannot have a value that exceeds `max_width`", config_key);
312+
}
313+
override_value
314+
};
315+
316+
let fn_call_width = get_width_value(
317+
self.was_set().fn_call_width(),
318+
self.fn_call_width.2,
319+
heuristics.fn_call_width,
320+
"fn_call_width",
321+
);
322+
self.fn_call_width.2 = fn_call_width;
323+
324+
let attr_fn_like_width = get_width_value(
325+
self.was_set().attr_fn_like_width(),
326+
self.attr_fn_like_width.2,
327+
heuristics.attr_fn_like_width,
328+
"attr_fn_like_width",
329+
);
330+
self.attr_fn_like_width.2 = attr_fn_like_width;
331+
332+
let struct_lit_width = get_width_value(
333+
self.was_set().struct_lit_width(),
334+
self.struct_lit_width.2,
335+
heuristics.struct_lit_width,
336+
"struct_lit_width",
337+
);
338+
self.struct_lit_width.2 = struct_lit_width;
339+
340+
let struct_variant_width = get_width_value(
341+
self.was_set().struct_variant_width(),
342+
self.struct_variant_width.2,
343+
heuristics.struct_variant_width,
344+
"struct_variant_width",
345+
);
346+
self.struct_variant_width.2 = struct_variant_width;
347+
348+
let array_width = get_width_value(
349+
self.was_set().array_width(),
350+
self.array_width.2,
351+
heuristics.array_width,
352+
"array_width",
353+
);
354+
self.array_width.2 = array_width;
355+
356+
let chain_width = get_width_value(
357+
self.was_set().chain_width(),
358+
self.chain_width.2,
359+
heuristics.chain_width,
360+
"chain_width",
361+
);
362+
self.chain_width.2 = chain_width;
363+
364+
let single_line_if_else_max_width = get_width_value(
365+
self.was_set().single_line_if_else_max_width(),
366+
self.single_line_if_else_max_width.2,
367+
heuristics.single_line_if_else_max_width,
368+
"single_line_if_else_max_width",
369+
);
370+
self.single_line_if_else_max_width.2 = single_line_if_else_max_width;
371+
}
372+
283373
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-
}
374+
let max_width = self.max_width.2;
375+
match self.width_heuristics.2 {
376+
Heuristics::Scaled =>
377+
self.set_width_heuristics(WidthHeuristics::scaled(max_width)),
378+
Heuristics::Max => self.set_width_heuristics(WidthHeuristics::set(max_width)),
379+
Heuristics::Off => self.set_width_heuristics(WidthHeuristics::null()),
380+
};
293381
}
294382

295383
fn set_license_template(&mut self) {

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

Lines changed: 41 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,24 @@ create_config! {
3232
hard_tabs: bool, false, true, "Use tab characters for indentation, spaces for alignment";
3333
tab_spaces: usize, 4, true, "Number of spaces per tab";
3434
newline_style: NewlineStyle, NewlineStyle::Auto, true, "Unix or Windows line endings";
35-
use_small_heuristics: Heuristics, Heuristics::Default, true, "Whether to use different \
36-
formatting for items and expressions if they satisfy a heuristic notion of 'small'";
3735
indent_style: IndentStyle, IndentStyle::Block, false, "How do we indent expressions or items";
36+
width_heuristics: Heuristics, Heuristics::Scaled, true, "Controls width heuristics \
37+
by setting the values for the individual width heuristic options";
38+
39+
// Width Heuristics
40+
fn_call_width: usize, 60, true, "Maximum width of the args of a function call before \
41+
falling back to vertical formatting.";
42+
attr_fn_like_width: usize, 70, true, "Maximum width of the args of a function-like \
43+
attributes before falling back to vertical formatting.";
44+
struct_lit_width: usize, 18, true, "Maximum width in the body of a struct lit before \
45+
falling back to vertical formatting.";
46+
struct_variant_width: usize, 35, true, "Maximum width in the body of a struct variant before \
47+
falling back to vertical formatting.";
48+
array_width: usize, 60, true, "Maximum width of an array literal before falling \
49+
back to vertical formatting.";
50+
chain_width: usize, 60, true, "Maximum length of a chain to fit on a single line.";
51+
single_line_if_else_max_width: usize, 50, true, "Maximum line length for single line if-else \
52+
expressions. A value of zero means always break if-else expressions.";
3853

3954
// Comments. macros, and strings
4055
wrap_comments: bool, false, false, "Break comments to fit on the line";
@@ -146,8 +161,6 @@ create_config! {
146161
file_lines: FileLines, FileLines::all(), false,
147162
"Lines to format; this is not supported in rustfmt.toml, and can only be specified \
148163
via the --file-lines option";
149-
width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
150-
"'small' heuristic values";
151164
emit_mode: EmitMode, EmitMode::Files, false,
152165
"What emit Mode to use when none is supplied";
153166
print_misformatted_file_names: bool, false, true,
@@ -167,7 +180,6 @@ impl PartialConfig {
167180
let mut cloned = self.clone();
168181
cloned.file_lines = None;
169182
cloned.verbose = None;
170-
cloned.width_heuristics = None;
171183
cloned.print_misformatted_file_names = None;
172184
cloned.recursive = None;
173185
cloned.emit_mode = None;
@@ -389,9 +401,6 @@ mod test {
389401
create_config! {
390402
// Options that are used by the generated functions
391403
max_width: usize, 100, true, "Maximum width of each line";
392-
use_small_heuristics: Heuristics, Heuristics::Default, true,
393-
"Whether to use different formatting for items and \
394-
expressions if they satisfy a heuristic notion of 'small'.";
395404
license_template_path: String, String::default(), false,
396405
"Beginning of file must match license template";
397406
required_version: String, env!("CARGO_PKG_VERSION").to_owned(), false,
@@ -403,8 +412,22 @@ mod test {
403412
file_lines: FileLines, FileLines::all(), false,
404413
"Lines to format; this is not supported in rustfmt.toml, and can only be specified \
405414
via the --file-lines option";
406-
width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
407-
"'small' heuristic values";
415+
width_heuristics: Heuristics, Heuristics::Scaled, true, "Controls width heuristics \
416+
by setting the values for the individual width heuristic options";
417+
// Width Heuristics
418+
fn_call_width: usize, 60, true, "Maximum width of the args of a function call before \
419+
falling back to vertical formatting.";
420+
attr_fn_like_width: usize, 70, true, "Maximum width of the args of a function-like \
421+
attributes before falling back to vertical formatting.";
422+
struct_lit_width: usize, 18, true, "Maximum width in the body of a struct lit before \
423+
falling back to vertical formatting.";
424+
struct_variant_width: usize, 35, true, "Maximum width in the body of a struct \
425+
variant before falling back to vertical formatting.";
426+
array_width: usize, 60, true, "Maximum width of an array literal before falling \
427+
back to vertical formatting.";
428+
chain_width: usize, 60, true, "Maximum length of a chain to fit on a single line.";
429+
single_line_if_else_max_width: usize, 50, true, "Maximum line length for single \
430+
line if-else expressions. A value of zero means always break if-else expressions.";
408431

409432
// Options that are used by the tests
410433
stable_option: bool, false, true, "A stable option";
@@ -492,8 +515,15 @@ mod test {
492515
hard_tabs = false
493516
tab_spaces = 4
494517
newline_style = "Auto"
495-
use_small_heuristics = "Default"
496518
indent_style = "Block"
519+
width_heuristics = "Scaled"
520+
fn_call_width = 60
521+
attr_fn_like_width = 70
522+
struct_lit_width = 18
523+
struct_variant_width = 35
524+
array_width = 60
525+
chain_width = 60
526+
single_line_if_else_max_width = 50
497527
wrap_comments = false
498528
format_code_in_doc_comments = false
499529
comment_width = 80

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

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,14 +77,16 @@ pub enum TypeDensity {
7777
}
7878

7979
#[config_type]
80-
/// To what extent does rustfmt pursue its heuristics?
80+
/// Heuristic settings that can be used to simply
81+
/// the configuration of the granular width configurations
82+
/// like `struct_lit_width`, `array_width`, etc.
8183
pub enum Heuristics {
8284
/// Turn off any heuristics
8385
Off,
8486
/// Turn on max heuristics
8587
Max,
86-
/// Use Rustfmt's defaults
87-
Default,
88+
/// Use scaled values based on the value of `max_width`
89+
Scaled,
8890
}
8991

9092
impl Density {
@@ -248,14 +250,6 @@ impl WidthHeuristics {
248250
}
249251
}
250252

251-
impl std::str::FromStr for WidthHeuristics {
252-
type Err = &'static str;
253-
254-
fn from_str(_: &str) -> Result<Self, Self::Err> {
255-
Err("WidthHeuristics is not parsable")
256-
}
257-
}
258-
259253
impl Default for EmitMode {
260254
fn default() -> EmitMode {
261255
EmitMode::Files

0 commit comments

Comments
 (0)