mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-26 13:29:12 +00:00
feat(formatter): implement outdent formatting for multiline lists and records
This commit is contained in:
parent
3d9daed836
commit
b147890b08
9 changed files with 647 additions and 87 deletions
|
@ -186,14 +186,75 @@ impl<'a> Formattable for Expr<'a> {
|
|||
loc_expr.format_with_options(buf, Parens::InApply, Newlines::Yes, indent);
|
||||
|
||||
let multiline_args = loc_args.iter().any(|loc_arg| loc_arg.is_multiline());
|
||||
let last_arg_index = loc_args.len() - 1;
|
||||
|
||||
if multiline_args {
|
||||
let should_outdent_last_arg =
|
||||
loc_args
|
||||
.iter()
|
||||
.enumerate()
|
||||
.fold(false, |found_multiline_expr, val| {
|
||||
let (index, loc_arg) = val;
|
||||
if index == last_arg_index {
|
||||
match loc_arg.value {
|
||||
SpaceBefore(sub_expr, spaces) => match sub_expr {
|
||||
Record { .. } | List { .. } => {
|
||||
let is_only_newlines =
|
||||
spaces.iter().all(|s| s.is_newline());
|
||||
is_only_newlines
|
||||
&& !found_multiline_expr
|
||||
&& sub_expr.is_multiline()
|
||||
}
|
||||
_ => false,
|
||||
},
|
||||
Record { .. } | List { .. } => {
|
||||
!found_multiline_expr && loc_arg.is_multiline()
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
} else {
|
||||
loc_arg.is_multiline()
|
||||
}
|
||||
});
|
||||
|
||||
if multiline_args && !should_outdent_last_arg {
|
||||
let arg_indent = indent + INDENT;
|
||||
|
||||
for loc_arg in loc_args.iter() {
|
||||
buf.newline();
|
||||
loc_arg.format_with_options(buf, Parens::InApply, Newlines::No, arg_indent);
|
||||
}
|
||||
} else if multiline_args && should_outdent_last_arg {
|
||||
for (index, loc_arg) in loc_args.iter().enumerate() {
|
||||
buf.spaces(1);
|
||||
|
||||
if index == last_arg_index {
|
||||
match loc_arg.value {
|
||||
SpaceBefore(sub_expr, _) => {
|
||||
sub_expr.format_with_options(
|
||||
buf,
|
||||
Parens::InApply,
|
||||
Newlines::Yes,
|
||||
indent,
|
||||
);
|
||||
}
|
||||
_ => {
|
||||
loc_arg.format_with_options(
|
||||
buf,
|
||||
Parens::InApply,
|
||||
Newlines::Yes,
|
||||
indent,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
loc_arg.format_with_options(
|
||||
buf,
|
||||
Parens::InApply,
|
||||
Newlines::Yes,
|
||||
indent,
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for loc_arg in loc_args.iter() {
|
||||
buf.spaces(1);
|
||||
|
@ -846,7 +907,34 @@ fn fmt_closure<'a, 'buf>(
|
|||
}
|
||||
};
|
||||
|
||||
loc_ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, body_indent);
|
||||
if is_multiline {
|
||||
match &loc_ret.value {
|
||||
SpaceBefore(sub_expr, spaces) => {
|
||||
let should_outdent = match sub_expr {
|
||||
Record { .. } | List { .. } => {
|
||||
let is_only_newlines = spaces.iter().all(|s| s.is_newline());
|
||||
is_only_newlines && sub_expr.is_multiline()
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if should_outdent {
|
||||
buf.spaces(1);
|
||||
sub_expr.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||
} else {
|
||||
loc_ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, body_indent);
|
||||
}
|
||||
}
|
||||
Record { .. } | List { .. } => {
|
||||
loc_ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, indent);
|
||||
}
|
||||
_ => {
|
||||
loc_ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, body_indent);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
loc_ret.format_with_options(buf, Parens::NotNeeded, Newlines::Yes, body_indent);
|
||||
}
|
||||
}
|
||||
|
||||
fn fmt_backpassing<'a, 'buf>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue