Merge branch 'main' into worktree-improvise-ewi-formula-crate
# Conflicts: # src/model/types.rs # src/view/layout.rs
This commit is contained in:
@ -137,27 +137,89 @@ mod tests {
|
||||
// ── Commit commands (mode-specific buffer consumers) ────────────────────────
|
||||
|
||||
/// Commit a cell value: for synthetic records keys, stage in drill pending edits
|
||||
/// or apply directly; for real keys, write to the model.
|
||||
fn commit_cell_value(key: &CellKey, value: &str, effects: &mut Vec<Box<dyn Effect>>) {
|
||||
if let Some((record_idx, col_name)) = crate::view::synthetic_record_info(key) {
|
||||
effects.push(Box::new(effect::SetDrillPendingEdit {
|
||||
record_idx,
|
||||
col_name,
|
||||
new_value: value.to_string(),
|
||||
}));
|
||||
} else if value.is_empty() {
|
||||
/// in drill mode, or apply directly in plain records mode; for real keys, write
|
||||
/// to the model.
|
||||
fn commit_regular_cell_value(key: &CellKey, value: &str, effects: &mut Vec<Box<dyn Effect>>) {
|
||||
if value.is_empty() {
|
||||
effects.push(Box::new(effect::ClearCell(key.clone())));
|
||||
effects.push(effect::mark_dirty());
|
||||
} else if let Ok(n) = value.parse::<f64>() {
|
||||
effects.push(Box::new(effect::SetCell(key.clone(), CellValue::Number(n))));
|
||||
effects.push(effect::mark_dirty());
|
||||
} else {
|
||||
effects.push(Box::new(effect::SetCell(
|
||||
key.clone(),
|
||||
CellValue::Text(value.to_string()),
|
||||
)));
|
||||
effects.push(effect::mark_dirty());
|
||||
}
|
||||
effects.push(effect::mark_dirty());
|
||||
}
|
||||
|
||||
/// Stage a synthetic edit in drill state so it can be applied atomically on exit.
|
||||
fn stage_drill_edit(record_idx: usize, col_name: String, value: &str) -> Box<dyn Effect> {
|
||||
Box::new(effect::SetDrillPendingEdit {
|
||||
record_idx,
|
||||
col_name,
|
||||
new_value: value.to_string(),
|
||||
})
|
||||
}
|
||||
|
||||
/// Apply a synthetic records-mode edit directly to the underlying model cell.
|
||||
fn commit_plain_records_edit(
|
||||
ctx: &CmdContext,
|
||||
record_idx: usize,
|
||||
col_name: &str,
|
||||
value: &str,
|
||||
effects: &mut Vec<Box<dyn Effect>>,
|
||||
) {
|
||||
let Some((orig_key, _)) = ctx
|
||||
.layout
|
||||
.records
|
||||
.as_ref()
|
||||
.and_then(|records| records.get(record_idx))
|
||||
else {
|
||||
return;
|
||||
};
|
||||
|
||||
if col_name == "Value" {
|
||||
commit_regular_cell_value(orig_key, value, effects);
|
||||
return;
|
||||
}
|
||||
|
||||
if value.is_empty() {
|
||||
effects.push(effect::set_status(effect::RECORD_COORDS_CANNOT_BE_EMPTY));
|
||||
return;
|
||||
}
|
||||
|
||||
let Some(existing_value) = ctx.model.get_cell(orig_key).cloned() else {
|
||||
return;
|
||||
};
|
||||
effects.push(Box::new(effect::ClearCell(orig_key.clone())));
|
||||
effects.push(Box::new(effect::AddItem {
|
||||
category: col_name.to_string(),
|
||||
item: value.to_string(),
|
||||
}));
|
||||
effects.push(Box::new(effect::SetCell(
|
||||
orig_key.clone().with(col_name, value),
|
||||
existing_value,
|
||||
)));
|
||||
effects.push(effect::mark_dirty());
|
||||
}
|
||||
|
||||
fn commit_cell_value(
|
||||
ctx: &CmdContext,
|
||||
key: &CellKey,
|
||||
value: &str,
|
||||
effects: &mut Vec<Box<dyn Effect>>,
|
||||
) {
|
||||
if let Some((record_idx, col_name)) = crate::view::synthetic_record_info(key) {
|
||||
if ctx.has_drill_state {
|
||||
effects.push(stage_drill_edit(record_idx, col_name, value));
|
||||
return;
|
||||
}
|
||||
commit_plain_records_edit(ctx, record_idx, &col_name, value, effects);
|
||||
return;
|
||||
}
|
||||
|
||||
commit_regular_cell_value(key, value, effects);
|
||||
}
|
||||
|
||||
/// Direction to advance after committing a cell edit.
|
||||
@ -187,7 +249,7 @@ impl Cmd for CommitAndAdvance {
|
||||
}
|
||||
fn execute(&self, ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
|
||||
let mut effects: Vec<Box<dyn Effect>> = Vec::new();
|
||||
commit_cell_value(&self.key, &self.value, &mut effects);
|
||||
commit_cell_value(ctx, &self.key, &self.value, &mut effects);
|
||||
match self.advance {
|
||||
AdvanceDir::Down => {
|
||||
let adv = EnterAdvance {
|
||||
|
||||
Reference in New Issue
Block a user