git.lucas.co / cce-designer
graphic design tool
git clone https://git.lucas.co/cce-designer.git

commit3b3e55e0c8bde054c279ac80a7fa2a2d8f13e5c2
parentd1abafc747
authorLucas Galante <lsgalante12@gmail.com>
date2026-10-07 10:35
feat(spreadsheet): a group's column header is g:<name>

With cce-ui's spreadsheet columns as wide as their content, a group's
header was the widest thing in its column of 0s and 1s. `group:<name>`
becomes `g:<name>`, matching the detail columns' `d:`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

 CLAUDE.md   | 8 ++++++--
 src/app.rs  | 9 ++++++---
 src/main.rs | 2 +-
 3 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/CLAUDE.md b/CLAUDE.md
index 66205b2..9c1e53b 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -2325,12 +2325,16 @@ wears and at Group Marker Size.
 
 **The point groups are the spreadsheet's first columns** after the
 point's number (`geometry_to_spreadsheet_columns`, since 2026-09-29):
-`group:<name>`, 1 for a member and 0 for the rest. They were `g:` columns
+`g:<name>`, 1 for a member and 0 for the rest. They were `g:` columns
 after every attribute, the thirteenth column of a sphere's table and off
 the right of any pane, and blank for a point outside the group — so a
 group of one point among five hundred was a column that looked empty.
 Sorting the column descending brings the members to the top. Only POINT
-groups: a row is a point, and the table has no primitive rows.
+groups: a row is a point, and the table has no primitive rows. The header
+read `group:<name>` until 2026-10-07: since the columns are as wide as
+their content (cce-ui's CLAUDE.md, "A spreadsheet's columns are as wide as
+their content"), the header is what sizes a column of 0s and 1s, and `g:`
+matches the detail columns' `d:`.
 
 **What reads a selected node for display reads it as the scene shows it**
 (`geometry::node_geometry_as_shown`, the same day): the spreadsheet's
diff --git a/src/app.rs b/src/app.rs
index cc21426..b117ba5 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -7284,15 +7284,18 @@ pub(crate) fn geometry_to_spreadsheet_columns(geom: &Detail) -> (Vec<String>, Ve
     // It is now the point index, which is also what the Point Numbers overlay
     // draws.
     // The groups stand FIRST after the point's number, a column each,
-    // `group:<name>`, 1 for a member and 0 for the rest. Until 2026-09-29
+    // `g:<name>`, 1 for a member and 0 for the rest. Until 2026-09-29
     // they were `g:` columns after every attribute — the thirteenth column
     // of a sphere's table, off the right of any pane — and blank for a
     // point not in the group, so a group of one point among five hundred
     // was a column that looked empty. Sorting the column, descending,
-    // brings the members to the top.
+    // brings the members to the top. The header was `group:<name>` from
+    // then until 2026-10-07, when the columns came to fit their content and
+    // the header was the widest thing in a column of 0s and 1s; `g:` is the
+    // detail columns' `d:` again.
     let groups = geom.points().group_names();
     let mut headers = vec!["Point".to_string()];
-    headers.extend(groups.iter().map(|g| format!("group:{}", g)));
+    headers.extend(groups.iter().map(|g| format!("g:{}", g)));
     headers.extend([
         "Pos.x".to_string(),
         "Pos.y".to_string(),
diff --git a/src/main.rs b/src/main.rs
index 83a4461..191e263 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -6415,7 +6415,7 @@ mod tests {
         assert_eq!(
             headers,
             vec![
-                "Point", "group:pinned", "Pos.x", "Pos.y", "Pos.z", "Col.r", "Col.g", "Col.b",
+                "Point", "g:pinned", "Pos.x", "Pos.y", "Pos.z", "Col.r", "Col.g", "Col.b",
                 "ID", "UV.x", "UV.y", "d:mass_max~",
             ]
         );