WIP: the collapsed-group and three paste declines refuse (improvise-i3o5)

This commit is contained in:
Edward Langley
2026-09-23 08:33:54 -07:00
parent e406edc8e8
commit 2f7d9c8c5a
3 changed files with 73 additions and 4 deletions
@@ -626,7 +626,7 @@ impl Cmd for PasteCell {
fn paste_into(ctx: &CmdContext, key: &CellKey, value: CellValue) -> Box<dyn Effect> {
match synthetic_record_info(key) {
Some((row, col)) => paste_into_record(ctx, row, col, value),
None if aggregates(ctx, key) => effect::set_status(AGGREGATE_REFUSAL),
None if aggregates(ctx, key) => effect::refuse(AGGREGATE_REFUSAL),
None => Box::new(effect::SetCell(key.clone(), value)),
}
}
@@ -638,9 +638,9 @@ fn paste_into_record(
value: CellValue,
) -> Box<dyn Effect> {
match (ctx.layout.record_cell_key(row, col), ctx.has_drill_state) {
(Some(_), true) => effect::set_status(INSIDE_A_DRILL_REFUSAL),
(Some(_), true) => effect::refuse(INSIDE_A_DRILL_REFUSAL),
(Some(real), false) => Box::new(effect::SetCell(real, value)),
(None, _) => effect::set_status(NO_VALUE_REFUSAL),
(None, _) => effect::refuse(NO_VALUE_REFUSAL),
}
}
@@ -359,7 +359,7 @@ impl Cmd for EditOrDrill {
fn execute(&self, ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
// Neither edit nor drill: no record carries a group's name (core.md §14).
if ctx.layout.folds_a_group(ctx.selected.0, ctx.selected.1) {
return vec![effect::set_status(
return vec![effect::refuse(
"Collapsed group — press z to expand it, then edit an item",
)];
}
+69
View File
@@ -3245,6 +3245,36 @@ mod tests {
app
}
/// Months grouped into quarters with Q2 collapsed: row 2 is the fold.
fn folded_quarter() -> App {
let mut wb = Workbook::new("T");
wb.add_category("Month").unwrap();
wb.add_category("Type").unwrap();
for (month, quarter) in [("Jan", "Q1"), ("Feb", "Q1"), ("Apr", "Q2"), ("May", "Q2")] {
wb.add_item_in_group("Month", month, quarter).unwrap();
}
wb.add_item("Type", "Food").unwrap();
wb.active_view_mut().toggle_group_collapse("Month", "Q2");
let mut app = App::new(wb, None);
app.rebuild_layout();
app
}
fn yanked(mut app: App) -> App {
app.view_state.yanked = Some(CellValue::Number(5.5));
app
}
/// A drill frozen over the records the grid already shows.
fn in_a_drill(mut app: App) -> App {
let records = app.layout.records.clone().expect("records mode");
app.drill_state = Some(DrillState {
records,
pending_edits: HashMap::new(),
});
app
}
fn with_a_second_view(mut app: App) -> App {
app.model_state.workbook.create_view("Second");
app
@@ -3446,6 +3476,45 @@ mod tests {
two_col_model,
|app| commit_in(app, AppMode::command_mode(), "command", "add-category Z"),
),
// improvise-i3o5: these four wrote their decline with `set_status`.
(
"edit-or-drill on a collapsed group's row",
folded_quarter,
|app| {
app.cursor_mut().selected = (2, 0);
run_line(app, "edit-or-drill editing")
},
"Collapsed group",
folded_quarter,
|app| {
app.cursor_mut().selected = (1, 0);
run_line(app, "edit-or-drill editing")
},
),
(
"a spelled paste onto an aggregate",
|| yanked(aggregated_grid(true)),
|app| run_line(app, "paste Row/A Col/A"),
crate::command::cmd::core::AGGREGATE_REFUSAL,
|| yanked(aggregated_grid(true)),
|app| run_line(app, "paste Row/A Col/A Hidden/A"),
),
(
"a spelled paste onto a records coordinate column",
|| yanked(records_model_with_two_rows()),
|app| run_line(app, "paste _Index/1 _Dim/0"),
crate::command::cmd::core::NO_VALUE_REFUSAL,
|| yanked(records_model_with_two_rows()),
|app| run_line(app, "paste _Index/1 _Dim/2"),
),
(
"a spelled paste inside a drill",
|| yanked(in_a_drill(records_model_with_two_rows())),
|app| run_line(app, "paste _Index/1 _Dim/2"),
crate::command::cmd::core::INSIDE_A_DRILL_REFUSAL,
|| yanked(records_model_with_two_rows()),
|app| run_line(app, "paste _Index/1 _Dim/2"),
),
];
for (what, fail_setup, fails, says, ok_setup, succeeds) in cases {
let mut app = fail_setup();