From a83d4876e735a795b5f1eaec4687d55c079be6df Mon Sep 17 00:00:00 2001 From: topecongiro Date: Tue, 23 May 2017 22:12:37 +0900 Subject: [PATCH] Allow first child to stay on the same line with block parent --- src/chains.rs | 49 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/src/chains.rs b/src/chains.rs index fbc42a5d84e8..92f4aa212a27 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, } }