refactor(command): improve formula commitment and buffer management
Refactor command execution and buffer management. - `CommitFormula` now defaults to targeting `_Measure` . - `CommitFormula` no longer automatically clears the buffer; buffer clearing is now handled by keymap sequences. - Added `ClearBufferCmd` to the command registry. - Updated `AddFormulaCmd` to support optional target category. - Added `SetBuffer` effect to allow clearing buffers. Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/gemma-4-26B-A4B-it-GGUF:UD-Q5_K_XL)
This commit is contained in:
@ -34,8 +34,10 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Formulas always target _Measure by default, even when no regular
|
||||||
|
/// categories exist. _Measure is a virtual category that always exists.
|
||||||
#[test]
|
#[test]
|
||||||
fn commit_formula_without_regular_categories_shows_status() {
|
fn commit_formula_without_regular_categories_targets_measure() {
|
||||||
let m = Model::new("Empty");
|
let m = Model::new("Empty");
|
||||||
let layout = make_layout(&m);
|
let layout = make_layout(&m);
|
||||||
let reg = make_registry();
|
let reg = make_registry();
|
||||||
@ -46,12 +48,12 @@ mod tests {
|
|||||||
let effects = CommitFormula.execute(&ctx);
|
let effects = CommitFormula.execute(&ctx);
|
||||||
let dbg = effects_debug(&effects);
|
let dbg = effects_debug(&effects);
|
||||||
assert!(
|
assert!(
|
||||||
!dbg.contains("AddFormula"),
|
dbg.contains("AddFormula"),
|
||||||
"Should not add formula when only virtual categories exist, got: {dbg}"
|
"Should add formula targeting _Measure, got: {dbg}"
|
||||||
);
|
);
|
||||||
assert!(
|
assert!(
|
||||||
dbg.contains("Add at least one category first"),
|
dbg.contains("_Measure"),
|
||||||
"Expected status message, got: {dbg}"
|
"target_category should be _Measure, got: {dbg}"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,30 +222,23 @@ impl Cmd for CommitFormula {
|
|||||||
}
|
}
|
||||||
fn execute(&self, ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
|
fn execute(&self, ctx: &CmdContext) -> Vec<Box<dyn Effect>> {
|
||||||
let buf = ctx.buffers.get("formula").cloned().unwrap_or_default();
|
let buf = ctx.buffers.get("formula").cloned().unwrap_or_default();
|
||||||
let first_cat = ctx
|
|
||||||
.model
|
|
||||||
.regular_category_names()
|
|
||||||
.into_iter()
|
|
||||||
.next()
|
|
||||||
.map(String::from);
|
|
||||||
let mut effects: Vec<Box<dyn Effect>> = Vec::new();
|
let mut effects: Vec<Box<dyn Effect>> = Vec::new();
|
||||||
if let Some(cat) = first_cat {
|
// Default formula target to _Measure (the virtual measure category).
|
||||||
|
// _Measure dynamically includes all formula targets.
|
||||||
effects.push(Box::new(effect::AddFormula {
|
effects.push(Box::new(effect::AddFormula {
|
||||||
raw: buf,
|
raw: buf,
|
||||||
target_category: cat,
|
target_category: "_Measure".to_string(),
|
||||||
}));
|
}));
|
||||||
effects.push(effect::mark_dirty());
|
effects.push(effect::mark_dirty());
|
||||||
effects.push(effect::set_status("Formula added"));
|
effects.push(effect::set_status("Formula added"));
|
||||||
} else {
|
|
||||||
effects.push(effect::set_status("Add at least one category first."));
|
|
||||||
}
|
|
||||||
effects.push(effect::change_mode(AppMode::FormulaPanel));
|
effects.push(effect::change_mode(AppMode::FormulaPanel));
|
||||||
effects
|
effects
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Shared helper: read a buffer, trim it, and if non-empty, produce add + dirty
|
/// Shared helper: read a buffer, trim it, and if non-empty, produce add + dirty
|
||||||
/// + status + clear-buffer effects. If empty, return to CategoryPanel.
|
/// + status effects. If empty, return to CategoryPanel.
|
||||||
|
/// Buffer clearing is handled by the keymap (Enter → [commit, clear-buffer]).
|
||||||
fn commit_add_from_buffer(
|
fn commit_add_from_buffer(
|
||||||
ctx: &CmdContext,
|
ctx: &CmdContext,
|
||||||
buffer_name: &str,
|
buffer_name: &str,
|
||||||
@ -262,10 +257,6 @@ fn commit_add_from_buffer(
|
|||||||
add,
|
add,
|
||||||
effect::mark_dirty(),
|
effect::mark_dirty(),
|
||||||
effect::set_status(status_msg(&trimmed)),
|
effect::set_status(status_msg(&trimmed)),
|
||||||
Box::new(effect::SetBuffer {
|
|
||||||
name: buffer_name.to_string(),
|
|
||||||
value: String::new(),
|
|
||||||
}),
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -200,11 +200,35 @@ effect_cmd!(
|
|||||||
effect_cmd!(
|
effect_cmd!(
|
||||||
AddFormulaCmd,
|
AddFormulaCmd,
|
||||||
"add-formula",
|
"add-formula",
|
||||||
|args: &[String]| require_args("add-formula", args, 2),
|
|args: &[String]| {
|
||||||
|
if args.is_empty() || args.len() > 2 {
|
||||||
|
return Err(format!("add-formula requires 1-2 argument(s), got {}", args.len()));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
},
|
||||||
|args: &Vec<String>, _ctx: &CmdContext| -> Vec<Box<dyn Effect>> {
|
|args: &Vec<String>, _ctx: &CmdContext| -> Vec<Box<dyn Effect>> {
|
||||||
|
// 1 arg: formula text (target_category defaults to _Measure)
|
||||||
|
// 2 args: target_category, formula text
|
||||||
|
let (cat, raw) = if args.len() == 2 {
|
||||||
|
(args[0].clone(), args[1].clone())
|
||||||
|
} else {
|
||||||
|
("_Measure".to_string(), args[0].clone())
|
||||||
|
};
|
||||||
vec![Box::new(effect::AddFormula {
|
vec![Box::new(effect::AddFormula {
|
||||||
target_category: args[0].clone(),
|
target_category: cat,
|
||||||
raw: args[1].clone(),
|
raw,
|
||||||
|
})]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
effect_cmd!(
|
||||||
|
ClearBufferCmd,
|
||||||
|
"clear-buffer",
|
||||||
|
|args: &[String]| require_args("clear-buffer", args, 1),
|
||||||
|
|args: &Vec<String>, _ctx: &CmdContext| -> Vec<Box<dyn Effect>> {
|
||||||
|
vec![Box::new(effect::SetBuffer {
|
||||||
|
name: args[0].clone(),
|
||||||
|
value: String::new(),
|
||||||
})]
|
})]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|||||||
@ -25,6 +25,7 @@ pub fn default_registry() -> CmdRegistry {
|
|||||||
r.register_pure(&AddItemsCmd(vec![]), AddItemsCmd::parse);
|
r.register_pure(&AddItemsCmd(vec![]), AddItemsCmd::parse);
|
||||||
r.register_pure(&AddItemInGroupCmd(vec![]), AddItemInGroupCmd::parse);
|
r.register_pure(&AddItemInGroupCmd(vec![]), AddItemInGroupCmd::parse);
|
||||||
r.register_pure(&SetCellCmd(vec![]), SetCellCmd::parse);
|
r.register_pure(&SetCellCmd(vec![]), SetCellCmd::parse);
|
||||||
|
r.register_pure(&ClearBufferCmd(vec![]), ClearBufferCmd::parse);
|
||||||
r.register(
|
r.register(
|
||||||
&ClearCellCommand {
|
&ClearCellCommand {
|
||||||
key: CellKey::new(vec![]),
|
key: CellKey::new(vec![]),
|
||||||
|
|||||||
@ -1252,6 +1252,23 @@ mod tests {
|
|||||||
assert_eq!(app.mode, AppMode::Help);
|
assert_eq!(app.mode, AppMode::Help);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// SetBuffer with empty value clears the buffer (used by clear-buffer command
|
||||||
|
/// in keymap sequences after commit).
|
||||||
|
#[test]
|
||||||
|
fn set_buffer_empty_clears() {
|
||||||
|
let mut app = test_app();
|
||||||
|
app.buffers.insert("formula".to_string(), "old text".to_string());
|
||||||
|
SetBuffer {
|
||||||
|
name: "formula".to_string(),
|
||||||
|
value: String::new(),
|
||||||
|
}
|
||||||
|
.apply(&mut app);
|
||||||
|
assert_eq!(
|
||||||
|
app.buffers.get("formula").map(|s| s.as_str()),
|
||||||
|
Some(""),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn set_status_effect() {
|
fn set_status_effect() {
|
||||||
let mut app = test_app();
|
let mut app = test_app();
|
||||||
|
|||||||
Reference in New Issue
Block a user