diff --git a/crates/improvise-command/src/command/cmd/cell.rs b/crates/improvise-command/src/command/cmd/cell.rs index 3281a894..01a2d5b9 100644 --- a/crates/improvise-command/src/command/cmd/cell.rs +++ b/crates/improvise-command/src/command/cmd/cell.rs @@ -626,7 +626,7 @@ impl Cmd for PasteCell { fn paste_into(ctx: &CmdContext, key: &CellKey, value: CellValue) -> Box { 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 { 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), } } diff --git a/crates/improvise-command/src/command/cmd/mode.rs b/crates/improvise-command/src/command/cmd/mode.rs index f3f264cd..a177c1e8 100644 --- a/crates/improvise-command/src/command/cmd/mode.rs +++ b/crates/improvise-command/src/command/cmd/mode.rs @@ -359,7 +359,7 @@ impl Cmd for EditOrDrill { fn execute(&self, ctx: &CmdContext) -> Vec> { // 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", )]; } diff --git a/crates/improvise-command/src/ui/app.rs b/crates/improvise-command/src/ui/app.rs index dd72b5a7..eda6ee1b 100644 --- a/crates/improvise-command/src/ui/app.rs +++ b/crates/improvise-command/src/ui/app.rs @@ -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();