about summary refs log tree commit diff
path: root/src/chains.rs
diff options
context:
space:
mode:
authortopecongiro <seuchida@gmail.com>2017-05-23 22:12:37 +0900
committertopecongiro <seuchida@gmail.com>2017-05-23 22:12:37 +0900
commita83d4876e735a795b5f1eaec4687d55c079be6df (patch)
tree364a133b6960497f3a1692025d9bbe62ee19ca98 /src/chains.rs
parent7c8432f05bf77ccd7aba238e9871ba50160e85df (diff)
Allow first child to stay on the same line with block parent
Diffstat (limited to 'src/chains.rs')
-rw-r--r--src/chains.rs49
1 files changed, 34 insertions, 15 deletions
diff --git a/src/chains.rs b/src/chains.rs
index fbc42a5d84e..92f4aa212a2 100644
--- a/src/chains.rs
+++ b/src/chains.rs
@@ -99,10 +99,14 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
     }
 
     // Parent is the first item in the chain, e.g., `foo` in `foo.bar.baz()`.
-    let mut parent_shape = shape;
-    if is_block_expr(&parent, "\n") {
-        parent_shape = chain_indent(context, shape);
-    }
+    let parent_shape = if is_block_expr(context, &parent, "\n") {
+        match context.config.chain_indent() {
+            IndentStyle::Visual => shape.visual_indent(0),
+            IndentStyle::Block => shape.block(),
+        }
+    } else {
+        shape
+    };
     let parent_rewrite = try_opt!(parent.rewrite(context, parent_shape));
     let parent_rewrite_contains_newline = parent_rewrite.contains('\n');
 
@@ -121,10 +125,14 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
         (nested_shape,
          context.config.chain_indent() == IndentStyle::Visual ||
          parent_rewrite.len() <= context.config.tab_spaces())
-    } else if is_block_expr(&parent, &parent_rewrite) {
-        // The parent is a block, so align the rest of the chain with the closing
-        // brace.
-        (parent_shape, false)
+    } else if is_block_expr(context, &parent, &parent_rewrite) {
+        match context.config.chain_indent() {
+            // Try to put the first child on the same line with parent's last line
+            IndentStyle::Block => (parent_shape.block_indent(context.config.tab_spaces()), true),
+            // The parent is a block, so align the rest of the chain with the closing
+            // brace.
+            IndentStyle::Visual => (parent_shape, false),
+        }
     } else if parent_rewrite_contains_newline {
         (chain_indent(context, parent_shape), false)
     } else {
@@ -140,11 +148,11 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
         ..nested_shape
     };
     let first_child_shape = if extend {
-        let first_child_shape = try_opt!(parent_shape
-                                             .offset_left(last_line_width(&parent_rewrite)));
+        let overhead = last_line_width(&parent_rewrite);
+        let offset = parent_rewrite.lines().rev().next().unwrap().trim().len();
         match context.config.chain_indent() {
-            IndentStyle::Visual => first_child_shape,
-            IndentStyle::Block => first_child_shape.block(),
+            IndentStyle::Visual => try_opt!(parent_shape.offset_left(overhead)),
+            IndentStyle::Block => try_opt!(parent_shape.block().offset_left(offset)),
         }
     } else {
         other_child_shape
@@ -224,8 +232,16 @@ pub fn rewrite_chain(expr: &ast::Expr, context: &RewriteContext, shape: Shape) -
         format!("\n{}", nested_shape.indent.to_string(context.config))
     };
 
-    let first_connector = if extend || subexpr_list.is_empty() || first_subexpr_is_try {
+    let first_connector = if subexpr_list.is_empty() {
         ""
+    } else if extend || first_subexpr_is_try {
+        // 1 = ";", being conservative here.
+        if last_line_width(&parent_rewrite) + first_line_width(&rewrites[0]) + 1 <=
+           context.config.max_width() {
+            ""
+        } else {
+            &*connector
+        }
     } else {
         &*connector
     };
@@ -277,8 +293,11 @@ fn join_rewrites(rewrites: &[String], subexps: &[ast::Expr], connector: &str) ->
 
 // States whether an expression's last line exclusively consists of closing
 // parens, braces, and brackets in its idiomatic formatting.
-fn is_block_expr(expr: &ast::Expr, repr: &str) -> bool {
+fn is_block_expr(context: &RewriteContext, expr: &ast::Expr, repr: &str) -> bool {
     match expr.node {
+        ast::ExprKind::Call(..) => {
+            context.config.fn_call_style() == IndentStyle::Block && repr.contains('\n')
+        }
         ast::ExprKind::Struct(..) |
         ast::ExprKind::While(..) |
         ast::ExprKind::WhileLet(..) |
@@ -291,7 +310,7 @@ fn is_block_expr(expr: &ast::Expr, repr: &str) -> bool {
         ast::ExprKind::Paren(ref expr) |
         ast::ExprKind::Binary(_, _, ref expr) |
         ast::ExprKind::Index(_, ref expr) |
-        ast::ExprKind::Unary(_, ref expr) => is_block_expr(expr, repr),
+        ast::ExprKind::Unary(_, ref expr) => is_block_expr(context, expr, repr),
         _ => false,
     }
 }