Make a trailing comma always force tall

At first I thought, “but a single-element collection should always fit,
right?” And sure it fits, but then I reformatted a larger experimental
config I have, including some GitHub Actions, and it turns out that
sometimes I prefer even single-element litst to be tall. Black is right
about this. I should be less opinionated, leave it to the user.
This commit is contained in:
Ruud van Asseldonk 2024-06-18 19:20:02 +02:00
parent 830fa48598
commit a070021547
5 changed files with 33 additions and 39 deletions

View file

@ -59,10 +59,10 @@ possible to stay within the limit.
The formatter is not sensitive to initial formatting, with the exception of
trailing commas, to give some control over how collections are formatted.[^1]
Collections with at least two elements that have a trailing comma will be
formatted tall, even when they fit on a line. To format the collection wide,
remove the trailing comma. This applies to any place where trailing commas are
allowed, not just collection literals.
Collections that have a trailing comma will be formatted tall, even when they
fit on a line. To format the collection wide, remove the trailing comma. This
applies to any place where trailing commas are allowed, not just collection
literals.
```rcl
// This collection is formatted wide.

View file

@ -2,7 +2,9 @@
name = "Build",
on = {
push = { branches = ["master"] },
push = {
branches = ["master"],
},
workflow_dispatch = {},
},

View file

@ -23,7 +23,7 @@ let double_comprehension = [
h.frobnicated(),
];
let b = [
1,
1
]; a +
b

View file

@ -1,12 +1,12 @@
// RCL implements Black's "magic trailing comma" behavior for lists of length >= 2.
// RCL implements Black's "magic trailing comma" behavior.
// https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#the-magic-trailing-comma
// If there is a trailing comma originally, and there are at least two elements,
// then the output is tall regardless of whether it would fit wide. If there is
// no trailing comma, the output is whatever fits.
// If there is a trailing comma originally, then the output is tall regardless
// regardless of whether it would fit wide. If there is no trailing comma, the
// output is whatever fits.
// Length 1, trailing comma is not relevant.
let a = [1,];
let b = [1];
// Length 1.
let a = [1];
let b = [1,];
let c = [
1
];
@ -14,7 +14,7 @@ let d = [
1,
];
// Length 2, trailing comma forces tall.
// Length 2.
let a = [1, 2];
let b = [
1, 2
@ -25,7 +25,6 @@ let d = [
];
// Sets.
let z = {1,};
let a = {1, 2};
let b = {
1, 2
@ -36,7 +35,6 @@ let d = {
};
// Dicts.
let z = {a=1,};
let a = {a=1, b=2};
let b = {
a=1, b=2
@ -47,7 +45,6 @@ let d = {
};
// Function calls.
let z = f(1,);
let a = f(1, 2);
let b = f(
1, 2
@ -57,7 +54,7 @@ let d = f(
1, 2,
);
// Function definitions.
// Function definitions. Here a single argument is a special case.
let z = (x,) => 1;
let a = (x, y) => 1;
let b = (
@ -69,7 +66,6 @@ let d = (
) => 1;
// Generic types.
let z: List[Int,] = [];
let a: List[Int, Int] = [];
let b: List[
Int, Int
@ -80,7 +76,6 @@ let d: List[
] = [];
// Function types.
let z: (Int,) -> Int = null;
let a: (Int, Int) -> Int = null;
let b: (
Int, Int
@ -93,19 +88,23 @@ let d: (
null
# output:
// RCL implements Black's "magic trailing comma" behavior for lists of length >= 2.
// RCL implements Black's "magic trailing comma" behavior.
// https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#the-magic-trailing-comma
// If there is a trailing comma originally, and there are at least two elements,
// then the output is tall regardless of whether it would fit wide. If there is
// no trailing comma, the output is whatever fits.
// If there is a trailing comma originally, then the output is tall regardless
// regardless of whether it would fit wide. If there is no trailing comma, the
// output is whatever fits.
// Length 1, trailing comma is not relevant.
// Length 1.
let a = [1];
let b = [1];
let b = [
1,
];
let c = [1];
let d = [1];
let d = [
1,
];
// Length 2, trailing comma forces tall.
// Length 2.
let a = [1, 2];
let b = [1, 2];
let c = [
@ -118,7 +117,6 @@ let d = [
];
// Sets.
let z = {1};
let a = {1, 2};
let b = {1, 2};
let c = {
@ -131,7 +129,6 @@ let d = {
};
// Dicts.
let z = { a = 1 };
let a = { a = 1, b = 2 };
let b = { a = 1, b = 2 };
let c = {
@ -144,7 +141,6 @@ let d = {
};
// Function calls.
let z = f(1);
let a = f(1, 2);
let b = f(1, 2);
let c = f(
@ -156,7 +152,7 @@ let d = f(
2,
);
// Function definitions.
// Function definitions. Here a single argument is a special case.
let z = x => 1;
let a = (x, y) => 1;
let b = (x, y) => 1;
@ -170,7 +166,6 @@ let d = (
) => 1;
// Generic types.
let z: List[Int] = [];
let a: List[Int, Int] = [];
let b: List[Int, Int] = [];
let c: List[
@ -183,7 +178,6 @@ let d: List[
] = [];
// Function types.
let z: (Int) -> Int = null;
let a: (Int, Int) -> Int = null;
let b: (Int, Int) -> Int = null;
let c: (

View file

@ -67,14 +67,12 @@ impl<'a> Formatter<'a> {
/// between the content and closing delimiter. But if we have no content
/// (but possibly a suffix) then we need only one soft break.
pub fn collection_opening_sep<T>(&self, list: &List<T>) -> Option<Doc<'a>> {
// When there is a list of at least two elements, and there is a trailing
// comma, then regardless of whether the list would fit in wide mode, we
// force it to be tall, to give the user some control over wide/tall.
// This is inspired by Black's "magic trailing comma":
// When there is a trailing comma, then regardless of whether the list
// would fit in wide mode, we force it to be tall, to give the user some
// control over wide/tall. This is inspired by Black's "magic trailing comma":
// https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#the-magic-trailing-comma
match list.elements.len() {
0 => None,
1 => Some(Doc::SoftBreak),
_ if list.trailing_comma => Some(Doc::HardBreak),
_ => Some(Doc::SoftBreak),
}