From 89cda8d43a92f16060319515343b69f5cbf3e1da Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 1 Sep 2015 17:06:41 +1200 Subject: [PATCH 1/7] Option to pack fn args on fewer lines --- src/config.rs | 23 ++++++++++++++++++++++- src/items.rs | 2 +- tests/config/small_tabs.toml | 1 + tests/source/fn-custom.rs | 13 +++++++++++++ tests/target/fn-custom.rs | 15 +++++++++++++++ 5 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 tests/source/fn-custom.rs create mode 100644 tests/target/fn-custom.rs diff --git a/src/config.rs b/src/config.rs index 02ee8e63789..1abdc9e80b7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -11,7 +11,7 @@ extern crate toml; use {NewlineStyle, BraceStyle, ReturnIndent, StructLitStyle}; -use lists::SeparatorTactic; +use lists::{SeparatorTactic, ListTactic}; use issues::ReportTactic; #[derive(Copy, Clone, Eq, PartialEq, Debug)] @@ -26,6 +26,25 @@ pub enum BlockIndentStyle { impl_enum_decodable!(BlockIndentStyle, Inherit, Tabbed, Visual); +#[derive(Copy, Clone, Eq, PartialEq, Debug)] +pub enum Density { + // Fit as much on one line as possible. + Compressed, + // Use more lines. + Tall, +} + +impl_enum_decodable!(Density, Compressed, Tall); + +impl Density { + pub fn to_list_tactic(self) -> ListTactic { + match self { + Density::Compressed => ListTactic::Mixed, + Density::Tall => ListTactic::HorizontalVertical, + } + } +} + macro_rules! create_config { ($($i:ident: $ty:ty),+ $(,)*) => ( #[derive(RustcDecodable, Clone)] @@ -70,6 +89,7 @@ create_config! { fn_brace_style: BraceStyle, fn_return_indent: ReturnIndent, fn_args_paren_newline: bool, + fn_args_layout: Density, struct_trailing_comma: SeparatorTactic, struct_lit_trailing_comma: SeparatorTactic, struct_lit_style: StructLitStyle, @@ -94,6 +114,7 @@ impl Default for Config { fn_brace_style: BraceStyle::SameLineWhere, fn_return_indent: ReturnIndent::WithArgs, fn_args_paren_newline: true, + fn_args_layout: Density::Tall, struct_trailing_comma: SeparatorTactic::Vertical, struct_lit_trailing_comma: SeparatorTactic::Vertical, struct_lit_style: StructLitStyle::BlockIndent, diff --git a/src/items.rs b/src/items.rs index bcc851a5b35..18cf58b667b 100644 --- a/src/items.rs +++ b/src/items.rs @@ -342,7 +342,7 @@ impl<'a> FmtVisitor<'a> { } let fmt = ListFormatting { - tactic: ListTactic::HorizontalVertical, + tactic: self.config.fn_args_layout.to_list_tactic(), separator: ",", trailing_separator: SeparatorTactic::Never, indent: arg_indent, diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index 1b4ab5cb7e9..c05f173177b 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -6,6 +6,7 @@ newline_style = "Unix" fn_brace_style = "SameLineWhere" fn_return_indent = "WithArgs" fn_args_paren_newline = true +fn_args_layout = "Tall" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" struct_lit_style = "BlockIndent" diff --git a/tests/source/fn-custom.rs b/tests/source/fn-custom.rs new file mode 100644 index 00000000000..77ced4c5e0e --- /dev/null +++ b/tests/source/fn-custom.rs @@ -0,0 +1,13 @@ +// rustfmt-fn_args_layout: Compressed +// Test some of the ways function signatures can be customised. + +// Test compressed layout of args. +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } +} diff --git a/tests/target/fn-custom.rs b/tests/target/fn-custom.rs new file mode 100644 index 00000000000..01abeaebb9e --- /dev/null +++ b/tests/target/fn-custom.rs @@ -0,0 +1,15 @@ +// rustfmt-fn_args_layout: Compressed +// Test some of the ways function signatures can be customised. + +// Test compressed layout of args. +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } +} From 0413c47a09d24ecd4494b2dc73442b88087f1020 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 1 Sep 2015 17:22:00 +1200 Subject: [PATCH 2/7] Support different tabbing of function args (Although, frankly anything other than visual is deeply wrong). --- src/config.rs | 2 ++ src/items.rs | 12 ++++++++++-- tests/config/small_tabs.toml | 1 + 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index 1abdc9e80b7..8ba88725d01 100644 --- a/src/config.rs +++ b/src/config.rs @@ -90,6 +90,7 @@ create_config! { fn_return_indent: ReturnIndent, fn_args_paren_newline: bool, fn_args_layout: Density, + fn_arg_indent: BlockIndentStyle, struct_trailing_comma: SeparatorTactic, struct_lit_trailing_comma: SeparatorTactic, struct_lit_style: StructLitStyle, @@ -115,6 +116,7 @@ impl Default for Config { fn_return_indent: ReturnIndent::WithArgs, fn_args_paren_newline: true, fn_args_layout: Density::Tall, + fn_arg_indent: BlockIndentStyle::Visual, struct_trailing_comma: SeparatorTactic::Vertical, struct_lit_trailing_comma: SeparatorTactic::Vertical, struct_lit_style: StructLitStyle::BlockIndent, diff --git a/src/items.rs b/src/items.rs index 18cf58b667b..694662b4eed 100644 --- a/src/items.rs +++ b/src/items.rs @@ -18,7 +18,7 @@ use expr::rewrite_assign_rhs; use comment::FindUncommented; use visitor::FmtVisitor; use rewrite::Rewrite; -use config::Config; +use config::{Config, BlockIndentStyle}; use syntax::{ast, abi}; use syntax::codemap::{self, Span, BytePos}; @@ -237,6 +237,7 @@ impl<'a> FmtVisitor<'a> { explicit_self, one_line_budget, multi_line_budget, + indent, arg_indent, args_span)); result.push(')'); @@ -293,6 +294,7 @@ impl<'a> FmtVisitor<'a> { explicit_self: Option<&ast::ExplicitSelf>, one_line_budget: usize, multi_line_budget: usize, + indent: usize, arg_indent: usize, span: Span) -> String { @@ -341,11 +343,17 @@ impl<'a> FmtVisitor<'a> { item.item = arg; } + let indent = match self.config.fn_arg_indent { + BlockIndentStyle::Inherit => indent, + BlockIndentStyle::Tabbed => indent + self.config.tab_spaces, + BlockIndentStyle::Visual => arg_indent, + }; + let fmt = ListFormatting { tactic: self.config.fn_args_layout.to_list_tactic(), separator: ",", trailing_separator: SeparatorTactic::Never, - indent: arg_indent, + indent: indent, h_width: one_line_budget, v_width: multi_line_budget, ends_with_newline: false, diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index c05f173177b..d489f960917 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -7,6 +7,7 @@ fn_brace_style = "SameLineWhere" fn_return_indent = "WithArgs" fn_args_paren_newline = true fn_args_layout = "Tall" +fn_arg_indent = "Visual" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" struct_lit_style = "BlockIndent" From fc2fb8be43debb483d9bb94e334d298e39ead24f Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 1 Sep 2015 18:20:17 +1200 Subject: [PATCH 3/7] Support different indent styles for generics --- src/config.rs | 2 ++ src/items.rs | 29 ++++++++++++++++++------ tests/config/small_tabs.toml | 1 + tests/source/fn-custom-2.rs | 25 ++++++++++++++++++++ tests/source/fn-custom-3.rs | 25 ++++++++++++++++++++ tests/target/fn-custom-2.rs | 44 ++++++++++++++++++++++++++++++++++++ tests/target/fn-custom-3.rs | 44 ++++++++++++++++++++++++++++++++++++ 7 files changed, 163 insertions(+), 7 deletions(-) create mode 100644 tests/source/fn-custom-2.rs create mode 100644 tests/source/fn-custom-3.rs create mode 100644 tests/target/fn-custom-2.rs create mode 100644 tests/target/fn-custom-3.rs diff --git a/src/config.rs b/src/config.rs index 8ba88725d01..fdfca063172 100644 --- a/src/config.rs +++ b/src/config.rs @@ -91,6 +91,7 @@ create_config! { fn_args_paren_newline: bool, fn_args_layout: Density, fn_arg_indent: BlockIndentStyle, + generics_indent: BlockIndentStyle, struct_trailing_comma: SeparatorTactic, struct_lit_trailing_comma: SeparatorTactic, struct_lit_style: StructLitStyle, @@ -117,6 +118,7 @@ impl Default for Config { fn_args_paren_newline: true, fn_args_layout: Density::Tall, fn_arg_indent: BlockIndentStyle::Visual, + generics_indent: BlockIndentStyle::Visual, struct_trailing_comma: SeparatorTactic::Vertical, struct_lit_trailing_comma: SeparatorTactic::Vertical, struct_lit_style: StructLitStyle::BlockIndent, diff --git a/src/items.rs b/src/items.rs index 694662b4eed..ae440826bdf 100644 --- a/src/items.rs +++ b/src/items.rs @@ -196,6 +196,7 @@ impl<'a> FmtVisitor<'a> { // Generics. let generics_indent = indent + result.len(); result.push_str(&self.rewrite_generics(generics, + indent, generics_indent, codemap::mk_sp(span.lo, span_for_return(&fd.output).lo))); @@ -432,6 +433,7 @@ impl<'a> FmtVisitor<'a> { let body_start = span.lo + BytePos(enum_snippet.find_uncommented("{").unwrap() as u32 + 1); let generics_str = self.format_generics(generics, " {", + self.block_indent, self.block_indent + self.config.tab_spaces, codemap::mk_sp(span.lo, body_start)); @@ -573,6 +575,7 @@ impl<'a> FmtVisitor<'a> { let generics_str = match generics { Some(g) => self.format_generics(g, opener, + offset, offset + header_str.len(), codemap::mk_sp(span.lo, struct_def.fields[0].span.lo)), @@ -670,9 +673,10 @@ impl<'a> FmtVisitor<'a> { generics: &ast::Generics, opener: &str, offset: usize, + generics_offset: usize, span: Span) -> String { - let mut result = self.rewrite_generics(generics, offset, span); + let mut result = self.rewrite_generics(generics, offset, generics_offset, span); if !generics.where_clause.predicates.is_empty() || result.contains('\n') { result.push_str(&self.rewrite_where_clause(&generics.where_clause, @@ -722,7 +726,12 @@ impl<'a> FmtVisitor<'a> { } } - fn rewrite_generics(&self, generics: &ast::Generics, offset: usize, span: Span) -> String { + fn rewrite_generics(&self, + generics: &ast::Generics, + offset: usize, + generics_offset: usize, + span: Span) + -> String { // FIXME convert bounds to where clauses where they get too big or if // there is a where clause at all. let lifetimes: &[_] = &generics.lifetimes; @@ -731,18 +740,24 @@ impl<'a> FmtVisitor<'a> { return String::new(); } - let budget = self.config.max_width - offset - 2; + let offset = match self.config.generics_indent { + BlockIndentStyle::Inherit => offset, + BlockIndentStyle::Tabbed => offset + self.config.tab_spaces, + // 1 = < + BlockIndentStyle::Visual => generics_offset + 1, + }; + + let h_budget = self.config.max_width - generics_offset - 2; // TODO might need to insert a newline if the generics are really long // Strings for the generics. - // 1 = < let context = self.get_context(); // FIXME: don't unwrap let lt_strs = lifetimes.iter().map(|lt| { - lt.rewrite(&context, budget, offset + 1).unwrap() + lt.rewrite(&context, h_budget, offset).unwrap() }); let ty_strs = tys.iter().map(|ty_param| { - ty_param.rewrite(&context, budget, offset + 1).unwrap() + ty_param.rewrite(&context, h_budget, offset).unwrap() }); // Extract comments between generics. @@ -770,7 +785,7 @@ impl<'a> FmtVisitor<'a> { item.item = ty; } - let fmt = ListFormatting::for_fn(budget, offset + 1); + let fmt = ListFormatting::for_fn(h_budget, offset); format!("<{}>", write_list(&items, &fmt)) } diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index d489f960917..e621547a010 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -8,6 +8,7 @@ fn_return_indent = "WithArgs" fn_args_paren_newline = true fn_args_layout = "Tall" fn_arg_indent = "Visual" +generics_indent = "Visual" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" struct_lit_style = "BlockIndent" diff --git a/tests/source/fn-custom-2.rs b/tests/source/fn-custom-2.rs new file mode 100644 index 00000000000..1b7e6ad78ad --- /dev/null +++ b/tests/source/fn-custom-2.rs @@ -0,0 +1,25 @@ +// rustfmt-fn_arg_indent: Inherit +// rustfmt-generics_indent: Tabbed +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo { + foo: Foo, +} diff --git a/tests/source/fn-custom-3.rs b/tests/source/fn-custom-3.rs new file mode 100644 index 00000000000..68939eee6b5 --- /dev/null +++ b/tests/source/fn-custom-3.rs @@ -0,0 +1,25 @@ +// rustfmt-fn_arg_indent: Tabbed +// rustfmt-generics_indent: Inherit +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); +} + +impl Foo { + fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo { + foo: Foo, +} diff --git a/tests/target/fn-custom-2.rs b/tests/target/fn-custom-2.rs new file mode 100644 index 00000000000..1bb7ef401ec --- /dev/null +++ b/tests/target/fn-custom-2.rs @@ -0,0 +1,44 @@ +// rustfmt-fn_arg_indent: Inherit +// rustfmt-generics_indent: Tabbed +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, +b: Bbbbbbbbbbbbbbbb, +c: Ccccccccccccccccc, +d: Ddddddddddddddddddddddddd, +e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> + (a: Aaaaaaaaaaaaaaa) { + bar(); +} + +impl Foo { + fn foo(self, + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> + (a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo +{ + foo: Foo, +} diff --git a/tests/target/fn-custom-3.rs b/tests/target/fn-custom-3.rs new file mode 100644 index 00000000000..61194dd04f3 --- /dev/null +++ b/tests/target/fn-custom-3.rs @@ -0,0 +1,44 @@ +// rustfmt-fn_arg_indent: Tabbed +// rustfmt-generics_indent: Inherit +// Test different indents. + +fn foo(a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee) { + foo(); +} + +fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, +TTTTTTTTTTTTT, +UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> + (a: Aaaaaaaaaaaaaaa) { + bar(); +} + +impl Foo { + fn foo(self, + a: Aaaaaaaaaaaaaaa, + b: Bbbbbbbbbbbbbbbb, + c: Ccccccccccccccccc, + d: Ddddddddddddddddddddddddd, + e: Eeeeeeeeeeeeeeeeeee) { + foo(); + } + + fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, + TTTTTTTTTTTTT, + UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> + (a: Aaaaaaaaaaaaaaa) { + bar(); + } +} + +struct Foo +{ + foo: Foo, +} From 6f3c329500fc0e1f67d454864f658e72a52183b3 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 1 Sep 2015 18:38:12 +1200 Subject: [PATCH 4/7] Support non-indented where clauses --- src/config.rs | 2 ++ src/items.rs | 9 +++++++-- tests/config/small_tabs.toml | 1 + tests/source/fn-custom-2.rs | 9 +++++++++ tests/target/fn-custom-2.rs | 13 +++++++++++++ 5 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/config.rs b/src/config.rs index fdfca063172..03b522be366 100644 --- a/src/config.rs +++ b/src/config.rs @@ -91,6 +91,7 @@ create_config! { fn_args_paren_newline: bool, fn_args_layout: Density, fn_arg_indent: BlockIndentStyle, + where_indent: BlockIndentStyle, // Visual will be treated like Tabbed generics_indent: BlockIndentStyle, struct_trailing_comma: SeparatorTactic, struct_lit_trailing_comma: SeparatorTactic, @@ -118,6 +119,7 @@ impl Default for Config { fn_args_paren_newline: true, fn_args_layout: Density::Tall, fn_arg_indent: BlockIndentStyle::Visual, + where_indent: BlockIndentStyle::Tabbed, generics_indent: BlockIndentStyle::Visual, struct_trailing_comma: SeparatorTactic::Vertical, struct_lit_trailing_comma: SeparatorTactic::Vertical, diff --git a/src/items.rs b/src/items.rs index ae440826bdf..94083e81c11 100644 --- a/src/items.rs +++ b/src/items.rs @@ -800,9 +800,14 @@ impl<'a> FmtVisitor<'a> { return String::new(); } + let extra_indent = match self.config.where_indent { + BlockIndentStyle::Inherit => 0, + BlockIndentStyle::Tabbed | BlockIndentStyle::Visual => config.tab_spaces, + }; + let context = self.get_context(); // 6 = "where ".len() - let offset = indent + config.tab_spaces + 6; + let offset = indent + extra_indent + 6; let budget = self.config.ideal_width + self.config.leeway - offset; let span_start = span_for_where_pred(&where_clause.predicates[0]).lo; let items = itemize_list(self.codemap, @@ -828,7 +833,7 @@ impl<'a> FmtVisitor<'a> { }; format!("\n{}where {}", - make_indent(indent + config.tab_spaces), + make_indent(indent + extra_indent), write_list(&items.collect::>(), &fmt)) } diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index e621547a010..3d6f01d7375 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -8,6 +8,7 @@ fn_return_indent = "WithArgs" fn_args_paren_newline = true fn_args_layout = "Tall" fn_arg_indent = "Visual" +where_indent = "Tabbed" generics_indent = "Visual" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" diff --git a/tests/source/fn-custom-2.rs b/tests/source/fn-custom-2.rs index 1b7e6ad78ad..6c9238e8087 100644 --- a/tests/source/fn-custom-2.rs +++ b/tests/source/fn-custom-2.rs @@ -1,5 +1,6 @@ // rustfmt-fn_arg_indent: Inherit // rustfmt-generics_indent: Tabbed +// rustfmt-where_indent: Inherit // Test different indents. fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { @@ -10,6 +11,10 @@ fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WW bar(); } +fn baz() where X: TTTTTTTT { + baz(); +} + impl Foo { fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { foo(); @@ -18,6 +23,10 @@ impl Foo { fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW>(a: Aaaaaaaaaaaaaaa) { bar(); } + + fn baz() where X: TTTTTTTT { + baz(); + } } struct Foo { diff --git a/tests/target/fn-custom-2.rs b/tests/target/fn-custom-2.rs index 1bb7ef401ec..e5c8af9a38b 100644 --- a/tests/target/fn-custom-2.rs +++ b/tests/target/fn-custom-2.rs @@ -1,5 +1,6 @@ // rustfmt-fn_arg_indent: Inherit // rustfmt-generics_indent: Tabbed +// rustfmt-where_indent: Inherit // Test different indents. fn foo(a: Aaaaaaaaaaaaaaa, @@ -17,6 +18,12 @@ fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, bar(); } +fn baz() +where X: TTTTTTTT +{ + baz(); +} + impl Foo { fn foo(self, a: Aaaaaaaaaaaaaaa, @@ -33,6 +40,12 @@ impl Foo { (a: Aaaaaaaaaaaaaaa) { bar(); } + + fn baz() + where X: TTTTTTTT + { + baz(); + } } struct Foo Date: Tue, 1 Sep 2015 18:53:16 +1200 Subject: [PATCH 5/7] Support where predicates on the same line --- src/config.rs | 2 ++ src/items.rs | 2 +- src/lists.rs | 2 ++ tests/config/small_tabs.toml | 1 + tests/source/fn-custom-2.rs | 5 +++++ tests/source/fn-custom-3.rs | 9 +++++++++ tests/target/fn-custom-2.rs | 8 ++++++++ tests/target/fn-custom-3.rs | 16 ++++++++++++++++ 8 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/config.rs b/src/config.rs index 03b522be366..b788052a047 100644 --- a/src/config.rs +++ b/src/config.rs @@ -92,6 +92,7 @@ create_config! { fn_args_layout: Density, fn_arg_indent: BlockIndentStyle, where_indent: BlockIndentStyle, // Visual will be treated like Tabbed + where_layout: ListTactic, generics_indent: BlockIndentStyle, struct_trailing_comma: SeparatorTactic, struct_lit_trailing_comma: SeparatorTactic, @@ -120,6 +121,7 @@ impl Default for Config { fn_args_layout: Density::Tall, fn_arg_indent: BlockIndentStyle::Visual, where_indent: BlockIndentStyle::Tabbed, + where_layout: ListTactic::Vertical, generics_indent: BlockIndentStyle::Visual, struct_trailing_comma: SeparatorTactic::Vertical, struct_lit_trailing_comma: SeparatorTactic::Vertical, diff --git a/src/items.rs b/src/items.rs index 94083e81c11..d2265fe9db1 100644 --- a/src/items.rs +++ b/src/items.rs @@ -823,7 +823,7 @@ impl<'a> FmtVisitor<'a> { span_end); let fmt = ListFormatting { - tactic: ListTactic::Vertical, + tactic: self.config.where_layout, separator: ",", trailing_separator: SeparatorTactic::Never, indent: offset, diff --git a/src/lists.rs b/src/lists.rs index 931baaa1073..3b9bb3f4af2 100644 --- a/src/lists.rs +++ b/src/lists.rs @@ -28,6 +28,8 @@ pub enum ListTactic { Mixed, } +impl_enum_decodable!(ListTactic, Vertical, Horizontal, HorizontalVertical, Mixed); + #[derive(Eq, PartialEq, Debug, Copy, Clone)] pub enum SeparatorTactic { Always, diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index 3d6f01d7375..21d12c7d4ea 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -9,6 +9,7 @@ fn_args_paren_newline = true fn_args_layout = "Tall" fn_arg_indent = "Visual" where_indent = "Tabbed" +where_layout = "Vertical" generics_indent = "Visual" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" diff --git a/tests/source/fn-custom-2.rs b/tests/source/fn-custom-2.rs index 6c9238e8087..a45f5501ea7 100644 --- a/tests/source/fn-custom-2.rs +++ b/tests/source/fn-custom-2.rs @@ -1,6 +1,7 @@ // rustfmt-fn_arg_indent: Inherit // rustfmt-generics_indent: Tabbed // rustfmt-where_indent: Inherit +// rustfmt-where_layout: Mixed // Test different indents. fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { @@ -15,6 +16,10 @@ fn baz() where X: TTTTTTTT { baz(); } +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + impl Foo { fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { foo(); diff --git a/tests/source/fn-custom-3.rs b/tests/source/fn-custom-3.rs index 68939eee6b5..e63b642d19c 100644 --- a/tests/source/fn-custom-3.rs +++ b/tests/source/fn-custom-3.rs @@ -1,5 +1,6 @@ // rustfmt-fn_arg_indent: Tabbed // rustfmt-generics_indent: Inherit +// rustfmt-where_layout: HorizontalVertical // Test different indents. fn foo(a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { @@ -10,6 +11,14 @@ fn bar<'a: 'bbbbbbbbbbbbbbbbbbbbbbbbbbb, TTTTTTTTTTTTT, UUUUUUUUUUUUUUUUUUUU: WW bar(); } +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + impl Foo { fn foo(self, a: Aaaaaaaaaaaaaaa, b: Bbbbbbbbbbbbbbbb, c: Ccccccccccccccccc, d: Ddddddddddddddddddddddddd, e: Eeeeeeeeeeeeeeeeeee) { foo(); diff --git a/tests/target/fn-custom-2.rs b/tests/target/fn-custom-2.rs index e5c8af9a38b..acac301fa53 100644 --- a/tests/target/fn-custom-2.rs +++ b/tests/target/fn-custom-2.rs @@ -1,6 +1,7 @@ // rustfmt-fn_arg_indent: Inherit // rustfmt-generics_indent: Tabbed // rustfmt-where_indent: Inherit +// rustfmt-where_layout: Mixed // Test different indents. fn foo(a: Aaaaaaaaaaaaaaa, @@ -24,6 +25,13 @@ where X: TTTTTTTT baz(); } +fn qux() +where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT +{ + baz(); +} + impl Foo { fn foo(self, a: Aaaaaaaaaaaaaaa, diff --git a/tests/target/fn-custom-3.rs b/tests/target/fn-custom-3.rs index 61194dd04f3..110fcf36714 100644 --- a/tests/target/fn-custom-3.rs +++ b/tests/target/fn-custom-3.rs @@ -1,5 +1,6 @@ // rustfmt-fn_arg_indent: Tabbed // rustfmt-generics_indent: Inherit +// rustfmt-where_layout: HorizontalVertical // Test different indents. fn foo(a: Aaaaaaaaaaaaaaa, @@ -17,6 +18,21 @@ UUUUUUUUUUUUUUUUUUUU: WWWWWWWWWWWWWWWWWWWWWWWW> bar(); } +fn qux() + where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT +{ + baz(); +} + +fn qux() + where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT +{ + baz(); +} + impl Foo { fn foo(self, a: Aaaaaaaaaaaaaaa, From 6216dce14e92007d8943b11f37879683fc31f2a2 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 1 Sep 2015 19:04:41 +1200 Subject: [PATCH 6/7] Support where clause predicates at different indentations --- src/config.rs | 2 ++ src/items.rs | 12 ++++++++++-- tests/config/small_tabs.toml | 1 + tests/source/fn-custom-4.rs | 6 ++++++ tests/source/fn-custom-5.rs | 6 ++++++ tests/target/fn-custom-4.rs | 11 +++++++++++ tests/target/fn-custom-5.rs | 11 +++++++++++ 7 files changed, 47 insertions(+), 2 deletions(-) create mode 100644 tests/source/fn-custom-4.rs create mode 100644 tests/source/fn-custom-5.rs create mode 100644 tests/target/fn-custom-4.rs create mode 100644 tests/target/fn-custom-5.rs diff --git a/src/config.rs b/src/config.rs index b788052a047..12dfce4de33 100644 --- a/src/config.rs +++ b/src/config.rs @@ -93,6 +93,7 @@ create_config! { fn_arg_indent: BlockIndentStyle, where_indent: BlockIndentStyle, // Visual will be treated like Tabbed where_layout: ListTactic, + where_pred_indent: BlockIndentStyle, generics_indent: BlockIndentStyle, struct_trailing_comma: SeparatorTactic, struct_lit_trailing_comma: SeparatorTactic, @@ -122,6 +123,7 @@ impl Default for Config { fn_arg_indent: BlockIndentStyle::Visual, where_indent: BlockIndentStyle::Tabbed, where_layout: ListTactic::Vertical, + where_pred_indent: BlockIndentStyle::Visual, generics_indent: BlockIndentStyle::Visual, struct_trailing_comma: SeparatorTactic::Vertical, struct_lit_trailing_comma: SeparatorTactic::Vertical, diff --git a/src/items.rs b/src/items.rs index d2265fe9db1..b93db659eba 100644 --- a/src/items.rs +++ b/src/items.rs @@ -806,8 +806,16 @@ impl<'a> FmtVisitor<'a> { }; let context = self.get_context(); - // 6 = "where ".len() - let offset = indent + extra_indent + 6; + + let offset = match self.config.where_pred_indent { + BlockIndentStyle::Inherit => indent + extra_indent, + BlockIndentStyle::Tabbed => indent + extra_indent + config.tab_spaces, + // 6 = "where ".len() + BlockIndentStyle::Visual => indent + extra_indent + 6, + }; + // FIXME: if where_pred_indent != Visual, then the budgets below might + // be out by a char or two. + let budget = self.config.ideal_width + self.config.leeway - offset; let span_start = span_for_where_pred(&where_clause.predicates[0]).lo; let items = itemize_list(self.codemap, diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index 21d12c7d4ea..912638c91f8 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -10,6 +10,7 @@ fn_args_layout = "Tall" fn_arg_indent = "Visual" where_indent = "Tabbed" where_layout = "Vertical" +where_pred_indent = "Visual" generics_indent = "Visual" struct_trailing_comma = "Vertical" struct_lit_trailing_comma = "Vertical" diff --git a/tests/source/fn-custom-4.rs b/tests/source/fn-custom-4.rs new file mode 100644 index 00000000000..0293f1b1959 --- /dev/null +++ b/tests/source/fn-custom-4.rs @@ -0,0 +1,6 @@ +// rustfmt-where_pred_indent: Tabbed +// Test different indents. + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} diff --git a/tests/source/fn-custom-5.rs b/tests/source/fn-custom-5.rs new file mode 100644 index 00000000000..98f11a72eab --- /dev/null +++ b/tests/source/fn-custom-5.rs @@ -0,0 +1,6 @@ +// rustfmt-where_pred_indent: Inherit +// Test different indents. + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} diff --git a/tests/target/fn-custom-4.rs b/tests/target/fn-custom-4.rs new file mode 100644 index 00000000000..e1da6524565 --- /dev/null +++ b/tests/target/fn-custom-4.rs @@ -0,0 +1,11 @@ +// rustfmt-where_pred_indent: Tabbed +// Test different indents. + +fn qux() + where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT +{ + baz(); +} diff --git a/tests/target/fn-custom-5.rs b/tests/target/fn-custom-5.rs new file mode 100644 index 00000000000..08c717538f2 --- /dev/null +++ b/tests/target/fn-custom-5.rs @@ -0,0 +1,11 @@ +// rustfmt-where_pred_indent: Inherit +// Test different indents. + +fn qux() + where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT +{ + baz(); +} From 8d81aa1991a92bc23c8629f1ef79b9c5dc13ff93 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 1 Sep 2015 19:36:00 +1200 Subject: [PATCH 7/7] Support where clauses on the same line as the function decl where it all fits on one line. --- src/config.rs | 3 +++ src/items.rs | 31 ++++++++++++++++++++++++++----- tests/config/small_tabs.toml | 1 + tests/source/fn-custom-4.rs | 9 +++++++++ tests/target/fn-custom-4.rs | 12 ++++++++++++ 5 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index 12dfce4de33..457c2eb2adf 100644 --- a/src/config.rs +++ b/src/config.rs @@ -91,6 +91,8 @@ create_config! { fn_args_paren_newline: bool, fn_args_layout: Density, fn_arg_indent: BlockIndentStyle, + where_density: Density, // Should we at least try to put the where clause on the same line as + // the rest of the function decl? where_indent: BlockIndentStyle, // Visual will be treated like Tabbed where_layout: ListTactic, where_pred_indent: BlockIndentStyle, @@ -121,6 +123,7 @@ impl Default for Config { fn_args_paren_newline: true, fn_args_layout: Density::Tall, fn_arg_indent: BlockIndentStyle::Visual, + where_density: Density::Tall, where_indent: BlockIndentStyle::Tabbed, where_layout: ListTactic::Vertical, where_pred_indent: BlockIndentStyle::Visual, diff --git a/src/items.rs b/src/items.rs index b93db659eba..cc431792c10 100644 --- a/src/items.rs +++ b/src/items.rs @@ -18,7 +18,7 @@ use expr::rewrite_assign_rhs; use comment::FindUncommented; use visitor::FmtVisitor; use rewrite::Rewrite; -use config::{Config, BlockIndentStyle}; +use config::{Config, BlockIndentStyle, Density}; use syntax::{ast, abi}; use syntax::codemap::{self, Span, BytePos}; @@ -99,7 +99,7 @@ impl<'a> FmtVisitor<'a> { vis: ast::Visibility, span: Span) -> String { - let newline_brace = self.newline_for_brace(&generics.where_clause); + let mut newline_brace = self.newline_for_brace(&generics.where_clause); let mut result = self.rewrite_fn_base(indent, ident, @@ -113,6 +113,10 @@ impl<'a> FmtVisitor<'a> { span, newline_brace); + if self.config.fn_brace_style != BraceStyle::AlwaysNextLine && !result.contains('\n') { + newline_brace = false; + } + // Prepare for the function body by possibly adding a newline and // indent. // FIXME we'll miss anything between the end of the signature and the @@ -281,10 +285,18 @@ impl<'a> FmtVisitor<'a> { } } + let where_density = if self.config.where_density == Density::Compressed && + !result.contains('\n') { + Density::Compressed + } else { + Density::Tall + }; + // Where clause. result.push_str(&self.rewrite_where_clause(where_clause, self.config, indent, + where_density, span.hi)); result @@ -682,6 +694,7 @@ impl<'a> FmtVisitor<'a> { result.push_str(&self.rewrite_where_clause(&generics.where_clause, self.config, self.block_indent, + Density::Tall, span.hi)); result.push_str(&make_indent(self.block_indent)); result.push('\n'); @@ -794,6 +807,7 @@ impl<'a> FmtVisitor<'a> { where_clause: &ast::WhereClause, config: &Config, indent: usize, + density: Density, span_end: BytePos) -> String { if where_clause.predicates.is_empty() { @@ -839,10 +853,17 @@ impl<'a> FmtVisitor<'a> { v_width: budget, ends_with_newline: true, }; + let preds_str = write_list(&items.collect::>(), &fmt); - format!("\n{}where {}", - make_indent(indent + extra_indent), - write_list(&items.collect::>(), &fmt)) + // 9 = " where ".len() + " {".len() + if density == Density::Tall || preds_str.contains('\n') || + indent + 9 + preds_str.len() > self.config.max_width { + format!("\n{}where {}", + make_indent(indent + extra_indent), + preds_str) + } else { + format!(" where {}", preds_str) + } } fn rewrite_return(&self, ret: &ast::FunctionRetTy) -> String { diff --git a/tests/config/small_tabs.toml b/tests/config/small_tabs.toml index 912638c91f8..146ceb2a62c 100644 --- a/tests/config/small_tabs.toml +++ b/tests/config/small_tabs.toml @@ -8,6 +8,7 @@ fn_return_indent = "WithArgs" fn_args_paren_newline = true fn_args_layout = "Tall" fn_arg_indent = "Visual" +where_density = "Tall" where_indent = "Tabbed" where_layout = "Vertical" where_pred_indent = "Visual" diff --git a/tests/source/fn-custom-4.rs b/tests/source/fn-custom-4.rs index 0293f1b1959..7b3e4c4a163 100644 --- a/tests/source/fn-custom-4.rs +++ b/tests/source/fn-custom-4.rs @@ -1,6 +1,15 @@ // rustfmt-where_pred_indent: Tabbed +// rustfmt-where_density: Compressed // Test different indents. fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { baz(); } + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + +fn qux(a: Aaaaaaaaaaaaaaaaa) where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} diff --git a/tests/target/fn-custom-4.rs b/tests/target/fn-custom-4.rs index e1da6524565..70ec49f34bc 100644 --- a/tests/target/fn-custom-4.rs +++ b/tests/target/fn-custom-4.rs @@ -1,4 +1,5 @@ // rustfmt-where_pred_indent: Tabbed +// rustfmt-where_density: Compressed // Test different indents. fn qux() @@ -9,3 +10,14 @@ fn qux() { baz(); } + +fn qux() where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT { + baz(); +} + +fn qux(a: Aaaaaaaaaaaaaaaaa) + where X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT, + X: TTTTTTTTTTTTTTTTTTTTTTTTTTTT +{ + baz(); +}