Merge pull request #1895 from topecongiro/configs-match_pattern_separator_break_point
Add mach_pattern_separator_break_point config option
This commit is contained in:
commit
88cb142173
@ -1163,6 +1163,39 @@ match lorem {
|
||||
|
||||
See also: [`indent_match_arms`](#indent_match_arms), [`trailing_comma`](#trailing_comma), [`wrap_match_arms`](#wrap_match_arms).
|
||||
|
||||
## `match_pattern_separator_break_point`
|
||||
|
||||
Put a match sub-patterns' separator (`|`) in front or back.
|
||||
|
||||
- **Default value**: `"Back"`
|
||||
- **Possible values**: `"Back"`, `"Front"`
|
||||
|
||||
#### `"Back"`
|
||||
|
||||
```rust
|
||||
match m {
|
||||
Variant::Tag |
|
||||
Variant::Tag2 |
|
||||
Variant::Tag3 |
|
||||
Variant::Tag4 |
|
||||
Variant::Tag5 |
|
||||
Variant::Tag6 => {}
|
||||
}
|
||||
```
|
||||
|
||||
#### `Front`
|
||||
|
||||
```rust
|
||||
match m {
|
||||
Variant::Tag
|
||||
| Variant::Tag2
|
||||
| Variant::Tag3
|
||||
| Variant::Tag4
|
||||
| Variant::Tag5
|
||||
| Variant::Tag6 => {}
|
||||
}
|
||||
```
|
||||
|
||||
## `max_width`
|
||||
|
||||
Maximum width of each line
|
||||
|
@ -17,7 +17,7 @@ use std::io::{Error, ErrorKind, Read};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use file_lines::FileLines;
|
||||
use lists::{ListTactic, SeparatorTactic};
|
||||
use lists::{ListTactic, SeparatorPlace, SeparatorTactic};
|
||||
|
||||
macro_rules! configuration_option_enum{
|
||||
($e:ident: $( $x:ident ),+ $(,)*) => {
|
||||
@ -581,6 +581,8 @@ create_config! {
|
||||
"Put a trailing comma after a block based match arm (non-block arms are not affected)";
|
||||
indent_match_arms: bool, true, "Indent match arms instead of keeping them at the same \
|
||||
indentation level as the match keyword";
|
||||
match_pattern_separator_break_point: SeparatorPlace, SeparatorPlace::Back,
|
||||
"Put a match sub-patterns' separator in front or back.";
|
||||
closure_block_indent_threshold: isize, 7, "How many lines a closure must have before it is \
|
||||
block indented. -1 means never use block indent.";
|
||||
space_before_type_annotation: bool, false,
|
||||
|
238
src/expr.rs
238
src/expr.rs
@ -10,7 +10,7 @@
|
||||
|
||||
use std::cmp::{min, Ordering};
|
||||
use std::fmt::Write;
|
||||
use std::iter::ExactSizeIterator;
|
||||
use std::iter::{repeat, ExactSizeIterator};
|
||||
|
||||
use syntax::{ast, ptr};
|
||||
use syntax::codemap::{BytePos, CodeMap, Span};
|
||||
@ -25,7 +25,7 @@ use config::{Config, ControlBraceStyle, IndentStyle, MultilineStyle, Style};
|
||||
use items::{span_hi_for_arg, span_lo_for_arg};
|
||||
use lists::{definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting,
|
||||
struct_lit_shape, struct_lit_tactic, write_list, DefinitiveListTactic, ListFormatting,
|
||||
ListItem, ListTactic, Separator, SeparatorTactic};
|
||||
ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
|
||||
use macros::{rewrite_macro, MacroPosition};
|
||||
use patterns::{can_be_overflowed_pat, TuplePatField};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
@ -473,6 +473,7 @@ where
|
||||
} else {
|
||||
SeparatorTactic::Vertical
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: nested_shape,
|
||||
ends_with_newline: ends_with_newline,
|
||||
preserve_newline: false,
|
||||
@ -555,6 +556,7 @@ fn rewrite_closure_fn_decl(
|
||||
tactic: tactic,
|
||||
separator: ",",
|
||||
trailing_separator: SeparatorTactic::Never,
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: arg_shape,
|
||||
ends_with_newline: false,
|
||||
preserve_newline: true,
|
||||
@ -1425,44 +1427,24 @@ fn is_unsafe_block(block: &ast::Block) -> bool {
|
||||
}
|
||||
}
|
||||
|
||||
// inter-match-arm-comment-rules:
|
||||
// - all comments following a match arm before the start of the next arm
|
||||
// are about the second arm
|
||||
fn rewrite_match_arm_comment(
|
||||
context: &RewriteContext,
|
||||
missed_str: &str,
|
||||
shape: Shape,
|
||||
arm_indent_str: &str,
|
||||
) -> Option<String> {
|
||||
// The leading "," is not part of the arm-comment
|
||||
let missed_str = match missed_str.find_uncommented(",") {
|
||||
Some(n) => &missed_str[n + 1..],
|
||||
None => &missed_str[..],
|
||||
};
|
||||
// A simple wrapper type against ast::Arm. Used inside write_list().
|
||||
struct ArmWrapper<'a> {
|
||||
pub arm: &'a ast::Arm,
|
||||
// True if the arm is the last one in match expression. Used to decide on whether we should add
|
||||
// trailing comma to the match arm when `config.trailing_comma() == Never`.
|
||||
pub is_last: bool,
|
||||
}
|
||||
|
||||
let mut result = String::new();
|
||||
// any text not preceeded by a newline is pushed unmodified to the block
|
||||
let first_brk = missed_str.find(|c: char| c == '\n').unwrap_or(0);
|
||||
result.push_str(&missed_str[..first_brk]);
|
||||
let missed_str = &missed_str[first_brk..]; // If missed_str had one newline, it starts with it
|
||||
|
||||
let first = missed_str
|
||||
.find(|c: char| !c.is_whitespace())
|
||||
.unwrap_or(missed_str.len());
|
||||
if missed_str[..first].chars().filter(|c| c == &'\n').count() >= 2 {
|
||||
// Excessive vertical whitespace before comment should be preserved
|
||||
// FIXME handle vertical whitespace better
|
||||
result.push('\n');
|
||||
}
|
||||
let missed_str = missed_str[first..].trim();
|
||||
if !missed_str.is_empty() {
|
||||
let comment = try_opt!(rewrite_comment(&missed_str, false, shape, context.config));
|
||||
result.push('\n');
|
||||
result.push_str(arm_indent_str);
|
||||
result.push_str(&comment);
|
||||
impl<'a> ArmWrapper<'a> {
|
||||
pub fn new(arm: &'a ast::Arm, is_last: bool) -> ArmWrapper<'a> {
|
||||
ArmWrapper { arm, is_last }
|
||||
}
|
||||
}
|
||||
|
||||
Some(result)
|
||||
impl<'a> Rewrite for ArmWrapper<'a> {
|
||||
fn rewrite(&self, context: &RewriteContext, shape: Shape) -> Option<String> {
|
||||
rewrite_match_arm(context, self.arm, shape, self.is_last)
|
||||
}
|
||||
}
|
||||
|
||||
fn rewrite_match(
|
||||
@ -1511,7 +1493,7 @@ fn rewrite_match(
|
||||
try_opt!(
|
||||
inner_attrs
|
||||
.rewrite(context, shape)
|
||||
.map(|s| format!("\n{}{}", nested_indent_str, s))
|
||||
.map(|s| format!("{}{}\n", nested_indent_str, s))
|
||||
)
|
||||
};
|
||||
|
||||
@ -1523,11 +1505,18 @@ fn rewrite_match(
|
||||
inner_attrs[inner_attrs.len() - 1].span().hi
|
||||
};
|
||||
|
||||
let arm_indent_str = if context.config.indent_match_arms() {
|
||||
nested_indent_str
|
||||
} else {
|
||||
shape.indent.to_string(context.config)
|
||||
};
|
||||
|
||||
Some(format!(
|
||||
"match {}{}{{{}{}\n{}}}",
|
||||
"match {}{}{{\n{}{}{}\n{}}}",
|
||||
cond_str,
|
||||
block_sep,
|
||||
inner_attrs_str,
|
||||
arm_indent_str,
|
||||
try_opt!(rewrite_match_arms(
|
||||
context,
|
||||
arms,
|
||||
@ -1539,8 +1528,10 @@ fn rewrite_match(
|
||||
))
|
||||
}
|
||||
|
||||
fn arm_comma(config: &Config, body: &ast::Expr) -> &'static str {
|
||||
if config.match_block_trailing_comma() {
|
||||
fn arm_comma(config: &Config, body: &ast::Expr, is_last: bool) -> &'static str {
|
||||
if is_last && config.trailing_comma() == SeparatorTactic::Never {
|
||||
""
|
||||
} else if config.match_block_trailing_comma() {
|
||||
","
|
||||
} else if let ast::ExprKind::Block(ref block) = body.node {
|
||||
if let ast::BlockCheckMode::Default = block.rules {
|
||||
@ -1560,84 +1551,88 @@ fn rewrite_match_arms(
|
||||
span: Span,
|
||||
open_brace_pos: BytePos,
|
||||
) -> Option<String> {
|
||||
let mut result = String::new();
|
||||
|
||||
let arm_shape = if context.config.indent_match_arms() {
|
||||
shape.block_indent(context.config.tab_spaces())
|
||||
} else {
|
||||
shape.block_indent(0)
|
||||
}.with_max_width(context.config);
|
||||
let arm_indent_str = arm_shape.indent.to_string(context.config);
|
||||
|
||||
let arm_num = arms.len();
|
||||
for (i, arm) in arms.iter().enumerate() {
|
||||
// Make sure we get the stuff between arms.
|
||||
let missed_str = if i == 0 {
|
||||
context.snippet(mk_sp(open_brace_pos, arm.span().lo))
|
||||
} else {
|
||||
context.snippet(mk_sp(arms[i - 1].span().hi, arm.span().lo))
|
||||
};
|
||||
let comment = try_opt!(rewrite_match_arm_comment(
|
||||
context,
|
||||
&missed_str,
|
||||
arm_shape,
|
||||
&arm_indent_str,
|
||||
));
|
||||
if !comment.chars().all(|c| c == ' ') {
|
||||
result.push_str(&comment);
|
||||
}
|
||||
result.push('\n');
|
||||
result.push_str(&arm_indent_str);
|
||||
let arm_len = arms.len();
|
||||
let is_last_iter = repeat(false)
|
||||
.take(arm_len.checked_sub(1).unwrap_or(0))
|
||||
.chain(repeat(true));
|
||||
let items = itemize_list(
|
||||
context.codemap,
|
||||
arms.iter()
|
||||
.zip(is_last_iter)
|
||||
.map(|(arm, is_last)| ArmWrapper::new(arm, is_last)),
|
||||
"}",
|
||||
|arm| arm.arm.span().lo,
|
||||
|arm| arm.arm.span().hi,
|
||||
|arm| arm.rewrite(context, arm_shape),
|
||||
open_brace_pos,
|
||||
span.hi,
|
||||
false,
|
||||
);
|
||||
let arms_vec: Vec<_> = items.collect();
|
||||
let fmt = ListFormatting {
|
||||
tactic: DefinitiveListTactic::Vertical,
|
||||
// We will add/remove commas inside `arm.rewrite()`, and hence no separator here.
|
||||
separator: "",
|
||||
trailing_separator: SeparatorTactic::Never,
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: arm_shape,
|
||||
ends_with_newline: true,
|
||||
preserve_newline: true,
|
||||
config: context.config,
|
||||
};
|
||||
|
||||
let arm_str = rewrite_match_arm(context, arm, arm_shape);
|
||||
if let Some(ref arm_str) = arm_str {
|
||||
// Trim the trailing comma if necessary.
|
||||
if i == arm_num - 1 && context.config.trailing_comma() == SeparatorTactic::Never &&
|
||||
arm_str.ends_with(',')
|
||||
{
|
||||
result.push_str(&arm_str[0..arm_str.len() - 1])
|
||||
} else {
|
||||
result.push_str(arm_str)
|
||||
}
|
||||
} else {
|
||||
// We couldn't format the arm, just reproduce the source.
|
||||
let snippet = context.snippet(arm.span());
|
||||
result.push_str(&snippet);
|
||||
if context.config.trailing_comma() != SeparatorTactic::Never {
|
||||
result.push_str(arm_comma(context.config, &arm.body))
|
||||
}
|
||||
}
|
||||
}
|
||||
// BytePos(1) = closing match brace.
|
||||
let last_span = mk_sp(arms[arms.len() - 1].span().hi, span.hi - BytePos(1));
|
||||
let last_comment = context.snippet(last_span);
|
||||
let comment = try_opt!(rewrite_match_arm_comment(
|
||||
context,
|
||||
&last_comment,
|
||||
arm_shape,
|
||||
&arm_indent_str,
|
||||
));
|
||||
result.push_str(&comment);
|
||||
|
||||
Some(result)
|
||||
write_list(&arms_vec, &fmt)
|
||||
}
|
||||
|
||||
fn rewrite_match_arm(context: &RewriteContext, arm: &ast::Arm, shape: Shape) -> Option<String> {
|
||||
let attr_str = if !arm.attrs.is_empty() {
|
||||
fn rewrite_match_arm(
|
||||
context: &RewriteContext,
|
||||
arm: &ast::Arm,
|
||||
shape: Shape,
|
||||
is_last: bool,
|
||||
) -> Option<String> {
|
||||
let (missing_span, attrs_str) = if !arm.attrs.is_empty() {
|
||||
if contains_skip(&arm.attrs) {
|
||||
return None;
|
||||
let (_, body) = flatten_arm_body(context, &arm.body);
|
||||
// `arm.span()` does not include trailing comma, add it manually.
|
||||
return Some(format!(
|
||||
"{}{}",
|
||||
context.snippet(arm.span()),
|
||||
arm_comma(context.config, body, is_last),
|
||||
));
|
||||
}
|
||||
format!(
|
||||
"{}\n{}",
|
||||
(
|
||||
mk_sp(arm.attrs[arm.attrs.len() - 1].span.hi, arm.pats[0].span.lo),
|
||||
try_opt!(arm.attrs.rewrite(context, shape)),
|
||||
shape.indent.to_string(context.config)
|
||||
)
|
||||
} else {
|
||||
String::new()
|
||||
(mk_sp(arm.span().lo, arm.span().lo), String::new())
|
||||
};
|
||||
let pats_str = try_opt!(rewrite_match_pattern(context, &arm.pats, &arm.guard, shape));
|
||||
let pats_str = attr_str + &pats_str;
|
||||
rewrite_match_body(context, &arm.body, &pats_str, shape, arm.guard.is_some())
|
||||
let pats_str = try_opt!(
|
||||
rewrite_match_pattern(context, &arm.pats, &arm.guard, shape).and_then(|pats_str| {
|
||||
combine_strs_with_missing_comments(
|
||||
context,
|
||||
&attrs_str,
|
||||
&pats_str,
|
||||
missing_span,
|
||||
shape,
|
||||
false,
|
||||
)
|
||||
})
|
||||
);
|
||||
rewrite_match_body(
|
||||
context,
|
||||
&arm.body,
|
||||
&pats_str,
|
||||
shape,
|
||||
arm.guard.is_some(),
|
||||
is_last,
|
||||
)
|
||||
}
|
||||
|
||||
fn rewrite_match_pattern(
|
||||
@ -1667,6 +1662,7 @@ fn rewrite_match_pattern(
|
||||
tactic: tactic,
|
||||
separator: " |",
|
||||
trailing_separator: SeparatorTactic::Never,
|
||||
separator_place: context.config.match_pattern_separator_break_point(),
|
||||
shape: pat_shape,
|
||||
ends_with_newline: false,
|
||||
preserve_newline: false,
|
||||
@ -1685,27 +1681,35 @@ fn rewrite_match_pattern(
|
||||
Some(format!("{}{}", pats_str, guard_str))
|
||||
}
|
||||
|
||||
fn rewrite_match_body(
|
||||
context: &RewriteContext,
|
||||
body: &ptr::P<ast::Expr>,
|
||||
pats_str: &str,
|
||||
shape: Shape,
|
||||
has_guard: bool,
|
||||
) -> Option<String> {
|
||||
let (extend, body) = match body.node {
|
||||
// (extend, body)
|
||||
// @extend: true if the arm body can be put next to `=>`
|
||||
// @body: flattened body, if the body is block with a single expression
|
||||
fn flatten_arm_body<'a>(context: &'a RewriteContext, body: &'a ast::Expr) -> (bool, &'a ast::Expr) {
|
||||
match body.node {
|
||||
ast::ExprKind::Block(ref block)
|
||||
if !is_unsafe_block(block) && is_simple_block(block, context.codemap) =>
|
||||
{
|
||||
if let ast::StmtKind::Expr(ref expr) = block.stmts[0].node {
|
||||
(expr.can_be_overflowed(context, 1), &**expr)
|
||||
} else {
|
||||
(false, &**body)
|
||||
(false, &*body)
|
||||
}
|
||||
}
|
||||
_ => (body.can_be_overflowed(context, 1), &**body),
|
||||
};
|
||||
_ => (body.can_be_overflowed(context, 1), &*body),
|
||||
}
|
||||
}
|
||||
|
||||
let comma = arm_comma(&context.config, body);
|
||||
fn rewrite_match_body(
|
||||
context: &RewriteContext,
|
||||
body: &ptr::P<ast::Expr>,
|
||||
pats_str: &str,
|
||||
shape: Shape,
|
||||
has_guard: bool,
|
||||
is_last: bool,
|
||||
) -> Option<String> {
|
||||
let (extend, body) = flatten_arm_body(context, &body);
|
||||
|
||||
let comma = arm_comma(&context.config, body, is_last);
|
||||
let alt_block_sep = String::from("\n") + &shape.indent.block_only().to_string(context.config);
|
||||
let alt_block_sep = alt_block_sep.as_str();
|
||||
let (is_block, is_empty_block) = if let ast::ExprKind::Block(ref block) = body.node {
|
||||
@ -2161,6 +2165,7 @@ where
|
||||
} else {
|
||||
context.config.trailing_comma()
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: shape,
|
||||
ends_with_newline: context.use_block_indent() && tactic == DefinitiveListTactic::Vertical,
|
||||
preserve_newline: false,
|
||||
@ -2761,6 +2766,7 @@ where
|
||||
tactic: tactic,
|
||||
separator: ",",
|
||||
trailing_separator: SeparatorTactic::Never,
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: shape,
|
||||
ends_with_newline: false,
|
||||
preserve_newline: false,
|
||||
|
@ -17,7 +17,7 @@ use Shape;
|
||||
use codemap::SpanUtils;
|
||||
use config::IndentStyle;
|
||||
use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
|
||||
ListItem, Separator, SeparatorTactic};
|
||||
ListItem, Separator, SeparatorPlace, SeparatorTactic};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use types::{rewrite_path, PathContext};
|
||||
use utils;
|
||||
@ -496,6 +496,7 @@ fn rewrite_use_list(
|
||||
} else {
|
||||
SeparatorTactic::Never
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: nested_shape,
|
||||
ends_with_newline: ends_with_newline,
|
||||
preserve_newline: true,
|
||||
|
@ -24,7 +24,7 @@ use config::{BraceStyle, Config, Density, IndentStyle, ReturnIndent, Style};
|
||||
use expr::{format_expr, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
|
||||
rewrite_call_inner, ExprType};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, DefinitiveListTactic, ListFormatting,
|
||||
ListItem, ListTactic, Separator, SeparatorTactic};
|
||||
ListItem, ListTactic, Separator, SeparatorPlace, SeparatorTactic};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use types::join_bounds;
|
||||
use utils::{colon_spaces, contains_skip, end_typaram, first_line_width, format_abi,
|
||||
@ -481,6 +481,7 @@ impl<'a> FmtVisitor<'a> {
|
||||
tactic: DefinitiveListTactic::Vertical,
|
||||
separator: ",",
|
||||
trailing_separator: self.config.trailing_comma(),
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: shape,
|
||||
ends_with_newline: true,
|
||||
preserve_newline: true,
|
||||
@ -2268,6 +2269,7 @@ fn rewrite_args(
|
||||
} else {
|
||||
trailing_comma
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: Shape::legacy(budget, indent),
|
||||
ends_with_newline: tactic.ends_with_newline(context.config.fn_args_layout()),
|
||||
preserve_newline: true,
|
||||
@ -2463,6 +2465,7 @@ where
|
||||
} else {
|
||||
context.config.trailing_comma()
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: shape,
|
||||
ends_with_newline: tactic.ends_with_newline(context.config.generics_indent()),
|
||||
preserve_newline: true,
|
||||
@ -2575,6 +2578,7 @@ fn rewrite_where_clause_rfc_style(
|
||||
tactic: DefinitiveListTactic::Vertical,
|
||||
separator: ",",
|
||||
trailing_separator: comma_tactic,
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: clause_shape,
|
||||
ends_with_newline: true,
|
||||
preserve_newline: true,
|
||||
@ -2686,6 +2690,7 @@ fn rewrite_where_clause(
|
||||
tactic: tactic,
|
||||
separator: ",",
|
||||
trailing_separator: comma_tactic,
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: Shape::legacy(budget, offset),
|
||||
ends_with_newline: tactic.ends_with_newline(context.config.where_pred_indent()),
|
||||
preserve_newline: true,
|
||||
|
114
src/lists.rs
114
src/lists.rs
@ -61,6 +61,7 @@ pub struct ListFormatting<'a> {
|
||||
pub tactic: DefinitiveListTactic,
|
||||
pub separator: &'a str,
|
||||
pub trailing_separator: SeparatorTactic,
|
||||
pub separator_place: SeparatorPlace,
|
||||
pub shape: Shape,
|
||||
// Non-expressions, e.g. items, will have a new line at the end of the list.
|
||||
// Important for comment styles.
|
||||
@ -70,6 +71,19 @@ pub struct ListFormatting<'a> {
|
||||
pub config: &'a Config,
|
||||
}
|
||||
|
||||
impl<'a> ListFormatting<'a> {
|
||||
pub fn needs_trailing_separator(&self) -> bool {
|
||||
match self.trailing_separator {
|
||||
// We always put separator in front.
|
||||
SeparatorTactic::Always => true,
|
||||
SeparatorTactic::Vertical => self.tactic == DefinitiveListTactic::Vertical,
|
||||
SeparatorTactic::Never => {
|
||||
self.tactic == DefinitiveListTactic::Vertical && self.separator_place.is_front()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<ListItem> for ListItem {
|
||||
fn as_ref(&self) -> &ListItem {
|
||||
self
|
||||
@ -165,6 +179,32 @@ impl Separator {
|
||||
}
|
||||
}
|
||||
|
||||
/// Where to put separator.
|
||||
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
|
||||
pub enum SeparatorPlace {
|
||||
Front,
|
||||
Back,
|
||||
}
|
||||
|
||||
impl_enum_serialize_and_deserialize!(SeparatorPlace, Front, Back);
|
||||
|
||||
impl SeparatorPlace {
|
||||
pub fn is_front(&self) -> bool {
|
||||
*self == SeparatorPlace::Front
|
||||
}
|
||||
|
||||
pub fn is_back(&self) -> bool {
|
||||
*self == SeparatorPlace::Back
|
||||
}
|
||||
|
||||
pub fn from_tactic(default: SeparatorPlace, tactic: DefinitiveListTactic) -> SeparatorPlace {
|
||||
match tactic {
|
||||
DefinitiveListTactic::Vertical => default,
|
||||
_ => SeparatorPlace::Back,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn definitive_tactic<I, T>(
|
||||
items: I,
|
||||
tactic: ListTactic,
|
||||
@ -214,11 +254,12 @@ where
|
||||
|
||||
// Now that we know how we will layout, we can decide for sure if there
|
||||
// will be a trailing separator.
|
||||
let mut trailing_separator = needs_trailing_separator(formatting.trailing_separator, tactic);
|
||||
let mut trailing_separator = formatting.needs_trailing_separator();
|
||||
let mut result = String::new();
|
||||
let cloned_items = items.clone();
|
||||
let mut iter = items.into_iter().enumerate().peekable();
|
||||
let mut item_max_width: Option<usize> = None;
|
||||
let mut sep_place = SeparatorPlace::from_tactic(formatting.separator_place, tactic);
|
||||
|
||||
let mut line_len = 0;
|
||||
let indent_str = &formatting.shape.indent.to_string(formatting.config);
|
||||
@ -258,13 +299,16 @@ where
|
||||
result.push('\n');
|
||||
result.push_str(indent_str);
|
||||
line_len = 0;
|
||||
if tactic == DefinitiveListTactic::Mixed && formatting.ends_with_newline {
|
||||
if formatting.ends_with_newline {
|
||||
if last {
|
||||
separate = true;
|
||||
} else {
|
||||
trailing_separator = true;
|
||||
}
|
||||
}
|
||||
sep_place = formatting.separator_place;
|
||||
} else {
|
||||
sep_place = SeparatorPlace::Back;
|
||||
}
|
||||
|
||||
if line_len > 0 {
|
||||
@ -314,6 +358,10 @@ where
|
||||
item_max_width = None;
|
||||
}
|
||||
|
||||
if separate && sep_place.is_front() && !first {
|
||||
result.push_str(formatting.separator.trim());
|
||||
result.push(' ');
|
||||
}
|
||||
result.push_str(&inner_item[..]);
|
||||
|
||||
// Post-comments
|
||||
@ -330,7 +378,7 @@ where
|
||||
result.push_str(&formatted_comment);
|
||||
}
|
||||
|
||||
if separate {
|
||||
if separate && sep_place.is_back() {
|
||||
result.push_str(formatting.separator);
|
||||
}
|
||||
|
||||
@ -380,8 +428,9 @@ where
|
||||
for _ in 0..(comment_alignment + 1) {
|
||||
result.push(' ');
|
||||
}
|
||||
// An additional space for the missing trailing comma
|
||||
if last && item_max_width.is_some() && !separate {
|
||||
// An additional space for the missing trailing separator.
|
||||
if last && item_max_width.is_some() && !separate && !formatting.separator.is_empty()
|
||||
{
|
||||
result.push(' ');
|
||||
}
|
||||
}
|
||||
@ -525,25 +574,30 @@ where
|
||||
}
|
||||
}
|
||||
let newline_index = post_snippet.find('\n');
|
||||
let separator_index = post_snippet.find_uncommented(",").unwrap();
|
||||
|
||||
match (block_open_index, newline_index) {
|
||||
// Separator before comment, with the next item on same line.
|
||||
// Comment belongs to next item.
|
||||
(Some(i), None) if i > separator_index => separator_index + 1,
|
||||
// Block-style post-comment before the separator.
|
||||
(Some(i), None) => cmp::max(
|
||||
find_comment_end(&post_snippet[i..]).unwrap() + i,
|
||||
separator_index + 1,
|
||||
),
|
||||
// Block-style post-comment. Either before or after the separator.
|
||||
(Some(i), Some(j)) if i < j => cmp::max(
|
||||
find_comment_end(&post_snippet[i..]).unwrap() + i,
|
||||
separator_index + 1,
|
||||
),
|
||||
// Potential *single* line comment.
|
||||
(_, Some(j)) if j > separator_index => j + 1,
|
||||
_ => post_snippet.len(),
|
||||
if let Some(separator_index) = post_snippet.find_uncommented(",") {
|
||||
match (block_open_index, newline_index) {
|
||||
// Separator before comment, with the next item on same line.
|
||||
// Comment belongs to next item.
|
||||
(Some(i), None) if i > separator_index => separator_index + 1,
|
||||
// Block-style post-comment before the separator.
|
||||
(Some(i), None) => cmp::max(
|
||||
find_comment_end(&post_snippet[i..]).unwrap() + i,
|
||||
separator_index + 1,
|
||||
),
|
||||
// Block-style post-comment. Either before or after the separator.
|
||||
(Some(i), Some(j)) if i < j => cmp::max(
|
||||
find_comment_end(&post_snippet[i..]).unwrap() + i,
|
||||
separator_index + 1,
|
||||
),
|
||||
// Potential *single* line comment.
|
||||
(_, Some(j)) if j > separator_index => j + 1,
|
||||
_ => post_snippet.len(),
|
||||
}
|
||||
} else {
|
||||
// Match arms may not have trailing comma. In any case, for match arms,
|
||||
// we will assume that the post comment belongs to the next arm if they
|
||||
// do not end with trailing comma.
|
||||
1
|
||||
}
|
||||
}
|
||||
None => post_snippet
|
||||
@ -636,17 +690,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn needs_trailing_separator(
|
||||
separator_tactic: SeparatorTactic,
|
||||
list_tactic: DefinitiveListTactic,
|
||||
) -> bool {
|
||||
match separator_tactic {
|
||||
SeparatorTactic::Always => true,
|
||||
SeparatorTactic::Vertical => list_tactic == DefinitiveListTactic::Vertical,
|
||||
SeparatorTactic::Never => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the count and total width of the list items.
|
||||
fn calculate_width<I, T>(items: I) -> (usize, usize)
|
||||
where
|
||||
@ -756,6 +799,7 @@ pub fn struct_lit_formatting<'a>(
|
||||
} else {
|
||||
context.config.trailing_comma()
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: shape,
|
||||
ends_with_newline: ends_with_newline,
|
||||
preserve_newline: true,
|
||||
|
@ -23,7 +23,7 @@ use config::{IndentStyle, Style, TypeDensity};
|
||||
use expr::{rewrite_pair, rewrite_tuple, rewrite_unary_prefix, wrap_args_with_parens};
|
||||
use items::{format_generics_item_list, generics_shape_from_config};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator,
|
||||
SeparatorTactic};
|
||||
SeparatorPlace, SeparatorTactic};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use utils::{colon_spaces, extra_offset, format_mutability, last_line_width, mk_sp, wrap_str};
|
||||
|
||||
@ -365,6 +365,7 @@ where
|
||||
} else {
|
||||
context.config.trailing_comma()
|
||||
},
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: list_shape,
|
||||
ends_with_newline: tactic.ends_with_newline(context.config.fn_call_style()),
|
||||
preserve_newline: true,
|
||||
|
@ -20,7 +20,8 @@ use codemap::SpanUtils;
|
||||
use comment::{combine_strs_with_missing_comments, contains_comment};
|
||||
use expr::rewrite_field;
|
||||
use items::{rewrite_struct_field, rewrite_struct_field_prefix};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator};
|
||||
use lists::{definitive_tactic, itemize_list, write_list, ListFormatting, ListTactic, Separator,
|
||||
SeparatorPlace};
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
use utils::{contains_skip, is_attributes_extendable, mk_sp};
|
||||
|
||||
@ -257,6 +258,7 @@ fn rewrite_aligned_items_inner<T: AlignedItem>(
|
||||
tactic: tactic,
|
||||
separator: ",",
|
||||
trailing_separator: context.config.trailing_comma(),
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: item_shape,
|
||||
ends_with_newline: true,
|
||||
preserve_newline: true,
|
||||
|
@ -24,7 +24,8 @@ use config::{BraceStyle, Config};
|
||||
use expr::{format_expr, ExprType};
|
||||
use items::{format_impl, format_trait, rewrite_associated_impl_type, rewrite_associated_type,
|
||||
rewrite_static, rewrite_type_alias};
|
||||
use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorTactic};
|
||||
use lists::{itemize_list, write_list, DefinitiveListTactic, ListFormatting, SeparatorPlace,
|
||||
SeparatorTactic};
|
||||
use macros::{rewrite_macro, MacroPosition};
|
||||
use regex::Regex;
|
||||
use rewrite::{Rewrite, RewriteContext};
|
||||
@ -917,6 +918,7 @@ impl Rewrite for ast::MetaItem {
|
||||
tactic: DefinitiveListTactic::Mixed,
|
||||
separator: ",",
|
||||
trailing_separator: SeparatorTactic::Never,
|
||||
separator_place: SeparatorPlace::Back,
|
||||
shape: item_shape,
|
||||
ends_with_newline: false,
|
||||
preserve_newline: false,
|
||||
|
@ -0,0 +1,9 @@
|
||||
// rustfmt-match_pattern_separator_break_point: Front
|
||||
// Whether `|` goes to front or to back.
|
||||
|
||||
fn main() {
|
||||
match lorem {
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa | bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb | cccccccccccccccccccccccccccccccccccccccc | dddddddddddddddddddddddddddddddddddddddd => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
@ -159,10 +159,9 @@ fn issue339() {
|
||||
// t comment
|
||||
t => 1,
|
||||
u => 2,
|
||||
// TODO uncomment when block-support exists
|
||||
// v => {
|
||||
// } /* funky block
|
||||
// * comment */
|
||||
v => {
|
||||
} /* funky block
|
||||
* comment */
|
||||
// final comment
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
// rustfmt-match_pattern_separator_break_point: Front
|
||||
// Whether `|` goes to front or to back.
|
||||
|
||||
fn main() {
|
||||
match lorem {
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
|
||||
| bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||
| cccccccccccccccccccccccccccccccccccccccc
|
||||
| dddddddddddddddddddddddddddddddddddddddd => (),
|
||||
_ => (),
|
||||
}
|
||||
}
|
@ -41,7 +41,8 @@ fn main() {
|
||||
}
|
||||
|
||||
match some_var
|
||||
{ // match comment
|
||||
{
|
||||
// match comment
|
||||
pattern0 => val0,
|
||||
pattern1 => val1,
|
||||
pattern2 | pattern3 =>
|
||||
|
@ -34,7 +34,8 @@ fn main() {
|
||||
}
|
||||
}
|
||||
|
||||
match some_var { // match comment
|
||||
match some_var {
|
||||
// match comment
|
||||
pattern0 => val0,
|
||||
pattern1 => val1,
|
||||
pattern2 | pattern3 => {
|
||||
|
@ -128,13 +128,15 @@ fn issue339() {
|
||||
h => {
|
||||
// comment above block
|
||||
}
|
||||
i => {} // comment below block
|
||||
i => {}
|
||||
// comment below block
|
||||
j => {
|
||||
// comment inside block
|
||||
}
|
||||
j2 => {
|
||||
// comments inside...
|
||||
} // ... and after
|
||||
}
|
||||
// ... and after
|
||||
// TODO uncomment when vertical whitespace is handled better
|
||||
// k => {
|
||||
//
|
||||
@ -156,11 +158,9 @@ fn issue339() {
|
||||
// t comment
|
||||
t => 1,
|
||||
u => 2,
|
||||
// TODO uncomment when block-support exists
|
||||
// v => {
|
||||
// } /* funky block
|
||||
// * comment */
|
||||
// final comment
|
||||
v => {} /* funky block
|
||||
* comment */
|
||||
/* final comment */
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,8 +173,8 @@ fn issue355() {
|
||||
e => vec![1, 2],
|
||||
f => vec![3; 4],
|
||||
h => println!("a", b), // h comment
|
||||
i => vec![1, 2], // i comment
|
||||
j => vec![3; 4], // j comment
|
||||
i => vec![1, 2], // i comment
|
||||
j => vec![3; 4], // j comment
|
||||
// k comment
|
||||
k => println!("a", b),
|
||||
// l comment
|
||||
@ -213,11 +213,11 @@ fn issue355() {
|
||||
y => vec![3; 4],
|
||||
// Brackets with comments
|
||||
tc => println!{"a", b}, // comment
|
||||
uc => vec![1, 2], // comment
|
||||
vc => vec![3; 4], // comment
|
||||
uc => vec![1, 2], // comment
|
||||
vc => vec![3; 4], // comment
|
||||
wc => println!["a", b], // comment
|
||||
xc => vec![1, 2], // comment
|
||||
yc => vec![3; 4], // comment
|
||||
xc => vec![1, 2], // comment
|
||||
yc => vec![3; 4], // comment
|
||||
yd => looooooooooooooooooooooooooooooooooooooooooooooooooooooooong_func(
|
||||
aaaaaaaaaa,
|
||||
bbbbbbbbbb,
|
||||
|
Loading…
x
Reference in New Issue
Block a user