about summary refs log tree commit diff
diff options
context:
space:
mode:
authorCaleb Cartwright <caleb.cartwright@outlook.com>2020-02-22 22:05:07 -0600
committerCaleb Cartwright <calebcartwright@users.noreply.github.com>2021-04-21 21:27:50 -0500
commitea1611c06eabb6c77d002a6ddc06697604e5077f (patch)
treea1d13505e2fd2ac4499e1a91386f552a0e7e11f2
parent0269eb1c5f4550e23cf18939b566c1b1f2f2c6a1 (diff)
downloadrust-ea1611c06eabb6c77d002a6ddc06697604e5077f.tar.gz
rust-ea1611c06eabb6c77d002a6ddc06697604e5077f.zip
feat(config): expose all width heurstic options
-rw-r--r--src/config/config_type.rs110
-rw-r--r--src/config/mod.rs57
-rw-r--r--src/config/options.rs6
3 files changed, 151 insertions, 22 deletions
diff --git a/src/config/config_type.rs b/src/config/config_type.rs
index bd4a847e0f1..7407ac0c03c 100644
--- a/src/config/config_type.rs
+++ b/src/config/config_type.rs
@@ -95,7 +95,15 @@ macro_rules! create_config {
             pub fn $i(&mut self, value: $ty) {
                 (self.0).$i.2 = value;
                 match stringify!($i) {
-                    "max_width" | "use_small_heuristics" => self.0.set_heuristics(),
+                    "max_width"
+                    | "use_small_heuristics"
+                    | "fn_call_width"
+                    | "single_line_if_else_max_width"
+                    | "attr_fn_like_width"
+                    | "struct_lit_width"
+                    | "struct_variant_width"
+                    | "array_width"
+                    | "chain_width" => self.0.set_heuristics(),
                     "license_template_path" => self.0.set_license_template(),
                     "merge_imports" => self.0.set_merge_imports(),
                     &_ => (),
@@ -230,7 +238,15 @@ macro_rules! create_config {
                 }
 
                 match key {
-                    "max_width" | "use_small_heuristics" => self.set_heuristics(),
+                    "max_width"
+                    | "use_small_heuristics"
+                    | "fn_call_width"
+                    | "single_line_if_else_max_width"
+                    | "attr_fn_like_width"
+                    | "struct_lit_width"
+                    | "struct_variant_width"
+                    | "array_width"
+                    | "chain_width" => self.set_heuristics(),
                     "license_template_path" => self.set_license_template(),
                     "merge_imports" => self.set_merge_imports(),
                     &_ => (),
@@ -281,16 +297,88 @@ macro_rules! create_config {
                 )+
             }
 
+            fn set_width_heuristics(&mut self, heuristics: WidthHeuristics) {
+                let max_width = self.max_width.2;
+                let get_width_value = |
+                    was_set: bool,
+                    override_value: usize,
+                    heuristic_value: usize,
+                    config_key: &str,
+                | -> usize {
+                    if !was_set {
+                        return heuristic_value;
+                    }
+                    if override_value > max_width {
+                        panic!("`{}` cannot have a value that exceeds `max_width`", config_key);
+                    }
+                    override_value
+                };
+
+                let fn_call_width = get_width_value(
+                    self.was_set().fn_call_width(),
+                    self.fn_call_width.2,
+                    heuristics.fn_call_width,
+                    "fn_call_width",
+                );
+                self.fn_call_width.2 = fn_call_width;
+
+                let attr_fn_like_width = get_width_value(
+                    self.was_set().attr_fn_like_width(),
+                    self.attr_fn_like_width.2,
+                    heuristics.attr_fn_like_width,
+                    "attr_fn_like_width",
+                );
+                self.attr_fn_like_width.2 = attr_fn_like_width;
+
+                let struct_lit_width = get_width_value(
+                    self.was_set().struct_lit_width(),
+                    self.struct_lit_width.2,
+                    heuristics.struct_lit_width,
+                    "struct_lit_width",
+                );
+                self.struct_lit_width.2 = struct_lit_width;
+
+                let struct_variant_width = get_width_value(
+                    self.was_set().struct_variant_width(),
+                    self.struct_variant_width.2,
+                    heuristics.struct_variant_width,
+                    "struct_variant_width",
+                );
+                self.struct_variant_width.2 = struct_variant_width;
+
+                let array_width = get_width_value(
+                    self.was_set().array_width(),
+                    self.array_width.2,
+                    heuristics.array_width,
+                    "array_width",
+                );
+                self.array_width.2 = array_width;
+
+                let chain_width = get_width_value(
+                    self.was_set().chain_width(),
+                    self.chain_width.2,
+                    heuristics.chain_width,
+                    "chain_width",
+                );
+                self.chain_width.2 = chain_width;
+
+                let single_line_if_else_max_width = get_width_value(
+                    self.was_set().single_line_if_else_max_width(),
+                    self.single_line_if_else_max_width.2,
+                    heuristics.single_line_if_else_max_width,
+                    "single_line_if_else_max_width",
+                );
+                self.single_line_if_else_max_width.2 = single_line_if_else_max_width;
+            }
+
             fn set_heuristics(&mut self) {
-                if self.use_small_heuristics.2 == Heuristics::Default {
-                    let max_width = self.max_width.2;
-                    self.set().width_heuristics(WidthHeuristics::scaled(max_width));
-                } else if self.use_small_heuristics.2 == Heuristics::Max {
-                    let max_width = self.max_width.2;
-                    self.set().width_heuristics(WidthHeuristics::set(max_width));
-                } else {
-                    self.set().width_heuristics(WidthHeuristics::null());
-                }
+                let max_width = self.max_width.2;
+                match self.use_small_heuristics.2 {
+                    Heuristics::Default =>
+                        self.set_width_heuristics(WidthHeuristics::scaled(max_width)),
+                    Heuristics::Max => self.set_width_heuristics(WidthHeuristics::set(max_width)),
+                    Heuristics::Off => self.set_width_heuristics(WidthHeuristics::null()),
+                };
             }
 
             fn set_license_template(&mut self) {
diff --git a/src/config/mod.rs b/src/config/mod.rs
index dfce7977bfe..f16273423ff 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -35,9 +35,26 @@ create_config! {
     hard_tabs: bool, false, true, "Use tab characters for indentation, spaces for alignment";
     tab_spaces: usize, 4, true, "Number of spaces per tab";
     newline_style: NewlineStyle, NewlineStyle::Auto, true, "Unix or Windows line endings";
+    indent_style: IndentStyle, IndentStyle::Block, false, "How do we indent expressions or items";
+
+    // Width Heuristics
     use_small_heuristics: Heuristics, Heuristics::Default, true, "Whether to use different \
         formatting for items and expressions if they satisfy a heuristic notion of 'small'";
-    indent_style: IndentStyle, IndentStyle::Block, false, "How do we indent expressions or items";
+    width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
+        "'small' heuristic values";
+    fn_call_width: usize, 60, true, "Maximum width of the args of a function call before \
+        falling back to vertical formatting.";
+    attr_fn_like_width: usize, 70, true, "Maximum width of the args of a function-like \
+        attributes before falling back to vertical formatting.";
+    struct_lit_width: usize, 18, true, "Maximum width in the body of a struct lit before \
+        falling back to vertical formatting.";
+    struct_variant_width: usize, 35, true, "Maximum width in the body of a struct variant before \
+        falling back to vertical formatting.";
+    array_width: usize, 60, true,  "Maximum width of an array literal before falling \
+        back to vertical formatting.";
+    chain_width: usize, 60, true, "Maximum length of a chain to fit on a single line.";
+    single_line_if_else_max_width: usize, 50, true, "Maximum line length for single line if-else \
+        expressions. A value of zero means always break if-else expressions.";
 
     // Comments. macros, and strings
     wrap_comments: bool, false, false, "Break comments to fit on the line";
@@ -154,8 +171,6 @@ create_config! {
     file_lines: FileLines, FileLines::all(), false,
         "Lines to format; this is not supported in rustfmt.toml, and can only be specified \
          via the --file-lines option";
-    width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
-        "'small' heuristic values";
     emit_mode: EmitMode, EmitMode::Files, false,
         "What emit Mode to use when none is supplied";
     make_backup: bool, false, false, "Backup changed files";
@@ -394,9 +409,6 @@ mod test {
         create_config! {
             // Options that are used by the generated functions
             max_width: usize, 100, true, "Maximum width of each line";
-            use_small_heuristics: Heuristics, Heuristics::Default, true,
-                "Whether to use different formatting for items and \
-                 expressions if they satisfy a heuristic notion of 'small'.";
             license_template_path: String, String::default(), false,
                 "Beginning of file must match license template";
             required_version: String, env!("CARGO_PKG_VERSION").to_owned(), false,
@@ -408,13 +420,33 @@ mod test {
             file_lines: FileLines, FileLines::all(), false,
                 "Lines to format; this is not supported in rustfmt.toml, and can only be specified \
                     via the --file-lines option";
-            width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
-                "'small' heuristic values";
+
             // merge_imports deprecation
             imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
                 "Merge imports";
             merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
 
+            // Width Heuristics
+            use_small_heuristics: Heuristics, Heuristics::Default, true,
+                "Whether to use different formatting for items and \
+                 expressions if they satisfy a heuristic notion of 'small'.";
+            width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
+                "'small' heuristic values";
+
+            fn_call_width: usize, 60, true, "Maximum width of the args of a function call before \
+                falling back to vertical formatting.";
+            attr_fn_like_width: usize, 70, true, "Maximum width of the args of a function-like \
+                attributes before falling back to vertical formatting.";
+            struct_lit_width: usize, 18, true, "Maximum width in the body of a struct lit before \
+                falling back to vertical formatting.";
+            struct_variant_width: usize, 35, true, "Maximum width in the body of a struct \
+                variant before falling back to vertical formatting.";
+            array_width: usize, 60, true,  "Maximum width of an array literal before falling \
+                back to vertical formatting.";
+            chain_width: usize, 60, true, "Maximum length of a chain to fit on a single line.";
+            single_line_if_else_max_width: usize, 50, true, "Maximum line length for single \
+                line if-else expressions. A value of zero means always break if-else expressions.";
+
             // Options that are used by the tests
             stable_option: bool, false, true, "A stable option";
             unstable_option: bool, false, false, "An unstable option";
@@ -519,8 +551,15 @@ mod test {
 hard_tabs = false
 tab_spaces = 4
 newline_style = "Auto"
-use_small_heuristics = "Default"
 indent_style = "Block"
+use_small_heuristics = "Default"
+fn_call_width = 60
+attr_fn_like_width = 70
+struct_lit_width = 18
+struct_variant_width = 35
+array_width = 60
+chain_width = 60
+single_line_if_else_max_width = 50
 wrap_comments = false
 format_code_in_doc_comments = false
 comment_width = 80
diff --git a/src/config/options.rs b/src/config/options.rs
index c0491630c00..3b91021813c 100644
--- a/src/config/options.rs
+++ b/src/config/options.rs
@@ -79,13 +79,15 @@ pub enum TypeDensity {
 }
 
 #[config_type]
-/// To what extent does rustfmt pursue its heuristics?
+/// Heuristic settings that can be used to simply
+/// the configuration of the granular width configurations
+/// like `struct_lit_width`, `array_width`, etc.
 pub enum Heuristics {
     /// Turn off any heuristics
     Off,
     /// Turn on max heuristics
     Max,
-    /// Use Rustfmt's defaults
+    /// Use scaled values based on the value of `max_width`
     Default,
 }