Repository: gleam-lang/gleam (Rust)

Issue:
Format lists the same in constants as in expressions
### Discussed in https://github.com/gleam-lang/gleam/discussions/3976

<div type='discussions-op-text'>

<sup>Originally posted by **FrostyX** December 11, 2024</sup>
I have this `let` variable:

```gleam
let map = [
  #("A", [Dot, Comma]),
  #("B", [Comma, Dot, Dot, Dot]),
  #("C", [Comma, Dot, Comma, Dot]),
  #("D", [Comma, Dot, Dot]),
  #("E", [Dot]),
  #("F", [Dot, Dot, Comma, Dot]),
  #("S", [Dot, Dot, Dot]),
]
```

The formatting is very readable. However, when I turn it into a constant, `gleam format` does this:

```gleam
const map = [
  #("A", [Dot, Comma]), #("B", [Comma, Dot, Dot, Dot]),
  #("C", [Comma, Dot, Comma, Dot]), #("D", [Comma, Dot, Dot]), #("E", [Dot]),
  #("F", [Dot, Dot, Comma, Dot]), #("S", [Dot, Dot, Dot]),
]
```

Can we change `gleam format` to do the same exact formatting for `const` as it does for `let`?</div>


Discussion:

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 707a557dd78..67e4dc43875 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -194,6 +194,9 @@
   to latest page for search engines.
   ([Dave Lage](https://github.com/rockerBOO))
 
+- The formatter now format lists the same in constants as in expressions
+  ([Jiangda Wang](https://github.com/Frank-III))
+
 ### Bug fixed
 
 - The compiler now throws an error when a float literal ends with an `e` and
@@ -244,7 +247,7 @@
 - Fixed a bug where the inferred variant of values was not properly cached,
   leading to incorrect errors on incremental builds and in the Language Server.
   ([Surya Rose](https://github.com/GearsDatapacks))
-  
+
  - Fixed a bug where Gleam would be unable to compile to BEAM bytecode if the
    project path contains a non-ascii character.
    ([yoshi](https://github.com/joshi-monster))
diff --git a/compiler-core/src/format.rs b/compiler-core/src/format.rs
index be9cda9fb06..9b2798b3c90 100644
--- a/compiler-core/src/format.rs
+++ b/compiler-core/src/format.rs
@@ -546,7 +546,7 @@ impl<'comments> Formatter<'comments> {
         }
 
         let comma = match elements.first() {
-            // If the list is made of records and it gets too long we want to
+            // If the list is made of non-simple constants and it gets too long we want to
             // have each record on its own line instead of trying to fit as much
             // as possible in each line. For example:
             //
@@ -556,8 +556,8 @@ impl<'comments> Formatter<'comments> {
             //       Some("wobble wibble"),
             //    ]
             //
-            Some(Constant::Record { .. }) => break_(",", ", "),
-            // For all other items, if we have to break the list we still try to
+            Some(el) if !el.is_simple() => break_(",", ", "),
+            // For simple constants(String, Int, Float), if we have to break the list we still try to
             // fit as much as possible into a single line instead of putting
             // each item on its own separate line. For example:
             //
@@ -568,6 +568,7 @@ impl<'comments> Formatter<'comments> {
             //
             Some(_) | None => flex_break(",", ", "),
         };
+
         let elements = join(elements.iter().map(|e| self.const_expr(e)), comma);
 
         let doc = break_("[", "[").append(elements).nest(INDENT);


Test patch:
diff --git a/compiler-core/src/format/tests/tuple.rs b/compiler-core/src/format/tests/tuple.rs
index 44ffe09a8e8..6f0b59acd14 100644
--- a/compiler-core/src/format/tests/tuple.rs
+++ b/compiler-core/src/format/tests/tuple.rs
@@ -57,8 +57,18 @@ fn tuple_with_last_splittable_arg() {
 fn constant_long_list_of_tuples() {
     assert_format!(
         r#"const wibble = [
-  #(1, 2), #(3, 4), #(5, 6), #(7, 8), #(9, 10), #(11, 12), #(1, 2), #(3, 4),
-  #(5, 6), #(7, 8), #(9, 10), #(11, 12),
+  #(1, 2),
+  #(3, 4),
+  #(5, 6),
+  #(7, 8),
+  #(9, 10),
+  #(11, 12),
+  #(1, 2),
+  #(3, 4),
+  #(5, 6),
+  #(7, 8),
+  #(9, 10),
+  #(11, 12),
 ]
 
 pub fn main() {