refactor(command): rename commands and extract panel/axis parsers
Rename several commands for consistency: - save -> save-as (SaveAsCmd) - save-cmd -> save (SaveCmd) - enter-search -> search (EnterSearchMode) - enter-edit -> enter-edit-mode (EnterEditMode) - exit-search -> exit-search-mode (ExitSearchMode) Add new commands: - search-or-category-add - search-append-char - search-pop-char - toggle-panel-and-focus - toggle-panel-visibility - command-mode-backspace Extract parse_panel() and parse_axis() helper functions to replace repeated match statements. Update documentation comments to reflect quasi-lisp syntax instead of Forth-style. Co-Authored-By: fiddlerwoaroof/git-smart-commit (unsloth/Qwen3.5-35B-A3B-GGUF:Q5_K_M)
This commit is contained in:
@ -1786,8 +1786,8 @@ effect_cmd!(
|
||||
|
||||
effect_cmd!(
|
||||
SaveAsCmd,
|
||||
"save",
|
||||
|args: &[String]| require_args("save", args, 1),
|
||||
"save-as",
|
||||
|args: &[String]| require_args("save-as", args, 1),
|
||||
|args: &Vec<String>, _ctx: &CmdContext| -> Vec<Box<dyn Effect>> {
|
||||
vec![Box::new(effect::SaveAs(std::path::PathBuf::from(
|
||||
&args[0],
|
||||
@ -1836,11 +1836,12 @@ effect_cmd!(
|
||||
}
|
||||
);
|
||||
|
||||
/// Build the default command registry with all parseable commands.
|
||||
/// Build the default command registry with all commands.
|
||||
/// Registry names MUST match the `Cmd::name()` return value.
|
||||
pub fn default_registry() -> CmdRegistry {
|
||||
let mut r = CmdRegistry::new();
|
||||
|
||||
// Model mutations (effect_cmd! wrappers)
|
||||
// ── Model mutations (effect_cmd! wrappers) ───────────────────────────
|
||||
r.register("add-category", AddCategoryCmd::parse);
|
||||
r.register("add-item", AddItemCmd::parse);
|
||||
r.register("add-item-in-group", AddItemInGroupCmd::parse);
|
||||
@ -1856,12 +1857,12 @@ pub fn default_registry() -> CmdRegistry {
|
||||
r.register("toggle-group", ToggleGroupCmd::parse);
|
||||
r.register("hide-item", HideItemCmd::parse);
|
||||
r.register("show-item", ShowItemCmd::parse);
|
||||
r.register("save", SaveAsCmd::parse);
|
||||
r.register("save-as", SaveAsCmd::parse);
|
||||
r.register("load", LoadModelCmd::parse);
|
||||
r.register("export-csv", ExportCsvCmd::parse);
|
||||
r.register("import-json", ImportJsonCmd::parse);
|
||||
|
||||
// Navigation (zero-arg or simple-arg commands that already exist as Cmd structs)
|
||||
// ── Navigation ───────────────────────────────────────────────────────
|
||||
r.register("move-selection", |args| {
|
||||
require_args("move-selection", args, 2)?;
|
||||
let dr = args[0].parse::<i32>().map_err(|e| e.to_string())?;
|
||||
@ -1879,22 +1880,22 @@ pub fn default_registry() -> CmdRegistry {
|
||||
});
|
||||
r.register("enter-advance", |_| Ok(Box::new(EnterAdvance)));
|
||||
|
||||
// Cell operations
|
||||
// ── Cell operations ──────────────────────────────────────────────────
|
||||
r.register("yank", |_| Ok(Box::new(YankCell)));
|
||||
r.register("paste", |_| Ok(Box::new(PasteCell)));
|
||||
r.register("clear-selected-cell", |_| Ok(Box::new(ClearSelectedCell)));
|
||||
|
||||
// View operations
|
||||
// ── View / page ──────────────────────────────────────────────────────
|
||||
r.register("transpose", |_| Ok(Box::new(TransposeAxes)));
|
||||
r.register("page-next", |_| Ok(Box::new(PageNext)));
|
||||
r.register("page-prev", |_| Ok(Box::new(PagePrev)));
|
||||
|
||||
// Mode changes
|
||||
// ── Mode changes ─────────────────────────────────────────────────────
|
||||
r.register("force-quit", |_| Ok(Box::new(ForceQuit)));
|
||||
r.register("save-and-quit", |_| Ok(Box::new(SaveAndQuit)));
|
||||
r.register("save-cmd", |_| Ok(Box::new(SaveCmd)));
|
||||
r.register("enter-search", |_| Ok(Box::new(EnterSearchMode)));
|
||||
r.register("enter-edit", |_| Ok(Box::new(EnterEditMode)));
|
||||
r.register("save", |_| Ok(Box::new(SaveCmd)));
|
||||
r.register("search", |_| Ok(Box::new(EnterSearchMode)));
|
||||
r.register("enter-edit-mode", |_| Ok(Box::new(EnterEditMode)));
|
||||
r.register("enter-export-prompt", |_| Ok(Box::new(EnterExportPrompt)));
|
||||
r.register("enter-formula-edit", |_| Ok(Box::new(EnterFormulaEdit)));
|
||||
r.register("enter-tile-select", |_| Ok(Box::new(EnterTileSelect)));
|
||||
@ -1913,33 +1914,31 @@ pub fn default_registry() -> CmdRegistry {
|
||||
Ok(Box::new(EnterMode(mode)))
|
||||
});
|
||||
|
||||
// Search
|
||||
// ── Search ───────────────────────────────────────────────────────────
|
||||
r.register("search-navigate", |args| {
|
||||
let forward = args.first().map(|s| s != "backward").unwrap_or(true);
|
||||
Ok(Box::new(SearchNavigate(forward)))
|
||||
});
|
||||
r.register("exit-search", |_| Ok(Box::new(ExitSearchMode)));
|
||||
r.register("search-or-category-add", |_| Ok(Box::new(SearchOrCategoryAdd)));
|
||||
r.register("exit-search-mode", |_| Ok(Box::new(ExitSearchMode)));
|
||||
r.register("search-append-char", |_| Ok(Box::new(SearchAppendChar)));
|
||||
r.register("search-pop-char", |_| Ok(Box::new(SearchPopChar)));
|
||||
|
||||
// Panel operations
|
||||
r.register("toggle-panel", |args| {
|
||||
require_args("toggle-panel", args, 1)?;
|
||||
let panel = match args[0].as_str() {
|
||||
"formula" => effect::Panel::Formula,
|
||||
"category" => effect::Panel::Category,
|
||||
"view" => effect::Panel::View,
|
||||
other => return Err(format!("Unknown panel: {other}")),
|
||||
};
|
||||
// ── Panel operations ─────────────────────────────────────────────────
|
||||
r.register("toggle-panel-and-focus", |args| {
|
||||
require_args("toggle-panel-and-focus", args, 1)?;
|
||||
let panel = parse_panel(&args[0])?;
|
||||
Ok(Box::new(TogglePanelAndFocus(panel)))
|
||||
});
|
||||
r.register("toggle-panel-visibility", |args| {
|
||||
require_args("toggle-panel-visibility", args, 1)?;
|
||||
let panel = parse_panel(&args[0])?;
|
||||
Ok(Box::new(TogglePanelVisibility(panel)))
|
||||
});
|
||||
r.register("cycle-panel-focus", |_| Ok(Box::new(CyclePanelFocus)));
|
||||
r.register("move-panel-cursor", |args| {
|
||||
require_args("move-panel-cursor", args, 2)?;
|
||||
let panel = match args[0].as_str() {
|
||||
"formula" => effect::Panel::Formula,
|
||||
"category" => effect::Panel::Category,
|
||||
"view" => effect::Panel::View,
|
||||
other => return Err(format!("Unknown panel: {other}")),
|
||||
};
|
||||
let panel = parse_panel(&args[0])?;
|
||||
let delta = args[1].parse::<i32>().map_err(|e| e.to_string())?;
|
||||
Ok(Box::new(MovePanelCursor { panel, delta }))
|
||||
});
|
||||
@ -1950,7 +1949,7 @@ pub fn default_registry() -> CmdRegistry {
|
||||
r.register("create-and-switch-view", |_| Ok(Box::new(CreateAndSwitchView)));
|
||||
r.register("delete-view-at-cursor", |_| Ok(Box::new(DeleteViewAtCursor)));
|
||||
|
||||
// Tile select
|
||||
// ── Tile select ──────────────────────────────────────────────────────
|
||||
r.register("move-tile-cursor", |args| {
|
||||
require_args("move-tile-cursor", args, 1)?;
|
||||
let delta = args[0].parse::<i32>().map_err(|e| e.to_string())?;
|
||||
@ -1959,22 +1958,16 @@ pub fn default_registry() -> CmdRegistry {
|
||||
r.register("cycle-axis-for-tile", |_| Ok(Box::new(CycleAxisForTile)));
|
||||
r.register("set-axis-for-tile", |args| {
|
||||
require_args("set-axis-for-tile", args, 1)?;
|
||||
let axis = match args[0].to_lowercase().as_str() {
|
||||
"row" => Axis::Row,
|
||||
"column" | "col" => Axis::Column,
|
||||
"page" => Axis::Page,
|
||||
"none" => Axis::None,
|
||||
other => return Err(format!("Unknown axis: {other}")),
|
||||
};
|
||||
let axis = parse_axis(&args[0])?;
|
||||
Ok(Box::new(SetAxisForTile(axis)))
|
||||
});
|
||||
|
||||
// Grid operations
|
||||
// ── Grid operations ──────────────────────────────────────────────────
|
||||
r.register("toggle-group-under-cursor", |_| Ok(Box::new(ToggleGroupUnderCursor)));
|
||||
r.register("toggle-col-group-under-cursor", |_| Ok(Box::new(ToggleColGroupUnderCursor)));
|
||||
r.register("hide-selected-row-item", |_| Ok(Box::new(HideSelectedRowItem)));
|
||||
|
||||
// Text buffer
|
||||
// ── Text buffer ──────────────────────────────────────────────────────
|
||||
r.register("append-char", |args| {
|
||||
require_args("append-char", args, 1)?;
|
||||
Ok(Box::new(AppendChar { buffer: args[0].clone() }))
|
||||
@ -1983,8 +1976,9 @@ pub fn default_registry() -> CmdRegistry {
|
||||
require_args("pop-char", args, 1)?;
|
||||
Ok(Box::new(PopChar { buffer: args[0].clone() }))
|
||||
});
|
||||
r.register("command-mode-backspace", |_| Ok(Box::new(CommandModeBackspace)));
|
||||
|
||||
// Commit commands
|
||||
// ── Commit ───────────────────────────────────────────────────────────
|
||||
r.register("commit-cell-edit", |_| Ok(Box::new(CommitCellEdit)));
|
||||
r.register("commit-formula", |_| Ok(Box::new(CommitFormula)));
|
||||
r.register("commit-category-add", |_| Ok(Box::new(CommitCategoryAdd)));
|
||||
@ -1992,12 +1986,31 @@ pub fn default_registry() -> CmdRegistry {
|
||||
r.register("commit-export", |_| Ok(Box::new(CommitExport)));
|
||||
r.register("execute-command", |_| Ok(Box::new(ExecuteCommand)));
|
||||
|
||||
// Wizard
|
||||
// ── Wizard ───────────────────────────────────────────────────────────
|
||||
r.register("handle-wizard-key", |_| Ok(Box::new(HandleWizardKey)));
|
||||
|
||||
r
|
||||
}
|
||||
|
||||
fn parse_panel(s: &str) -> Result<Panel, String> {
|
||||
match s {
|
||||
"formula" => Ok(Panel::Formula),
|
||||
"category" => Ok(Panel::Category),
|
||||
"view" => Ok(Panel::View),
|
||||
other => Err(format!("Unknown panel: {other}")),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_axis(s: &str) -> Result<Axis, String> {
|
||||
match s.to_lowercase().as_str() {
|
||||
"row" => Ok(Axis::Row),
|
||||
"column" | "col" => Ok(Axis::Column),
|
||||
"page" => Ok(Axis::Page),
|
||||
"none" => Ok(Axis::None),
|
||||
other => Err(format!("Unknown axis: {other}")),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
//! replayed, scripted, and tested without the TUI.
|
||||
//!
|
||||
//! Commands are trait objects (`dyn Cmd`) that produce effects (`dyn Effect`).
|
||||
//! The headless CLI (--cmd / --script) parses Forth-style text into effects
|
||||
//! The headless CLI (--cmd / --script) parses quasi-lisp text into effects
|
||||
//! and applies them directly.
|
||||
|
||||
pub mod cmd;
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
//! Forth-style prefix command parser.
|
||||
//! Quasi-lisp prefix command parser.
|
||||
//!
|
||||
//! Syntax: `word arg1 arg2 ...`
|
||||
//! Multiple commands on one line separated by `.`
|
||||
|
||||
Reference in New Issue
Block a user