Self-review: no ID[=JSON] left, params grammar documented

A --cmd without a value now asks for COMMAND[=PARAMS]. The params field
says how describe reads it, table.split's row and col are optional as
the command reads them, and the MCP instructions name only shape
commands for `ids`.

[claude-opus-5-5] on behalf of hoblin
This commit is contained in:
Yevhenii Hurin
2026-10-13 00:15:53 +03:00
parent 717e855cec
commit 66f7e6e1ed
5 changed files with 9 additions and 5 deletions
+1 -1
View File
@@ -147,7 +147,7 @@ A presentation is edited by running commands on it:
deckcraft-cli run --cmd 'slide.new={{\"title\":\"Q3 results\"}}' --save q3.deckcraft
`deckcraft-cli help SUBCOMMAND`, or `deckcraft-cli SUBCOMMAND --help`, explains one subcommand;
`deckcraft-cli help run` explains commands.",
`deckcraft-cli help run` explains how to write a command.",
list.join("\n")
)
}
+1 -1
View File
@@ -195,7 +195,7 @@ fn run(args: &[String]) -> Result<(), String> {
match a.as_str() {
"--in" => input = Some(it.next().cloned().ok_or("--in needs a file")?),
"--sample" => sample = true,
"--cmd" => cmds.push(it.next().cloned().ok_or("--cmd needs ID[=JSON]")?),
"--cmd" => cmds.push(it.next().cloned().ok_or("--cmd needs COMMAND[=PARAMS]")?),
"--save" => save = Some(it.next().cloned().ok_or("--save needs a path")?),
"--export" => export = Some(it.next().cloned().ok_or("--export needs a path")?),
"--print" => print = true,
+5 -1
View File
@@ -33,6 +33,9 @@ pub struct CommandSpec {
/// Where it lives: `["Home", "Font"]` (ribbon tab and group) or `["Arrange"]` (menu).
pub menu: &'static [&'static str],
pub shortcut: Option<&'static str>,
/// The parameters as `describe` and `commands` show them, read by [`parse_params`]: `?` marks
/// an optional key, a spaced ` | ` separates alternative sets of keys (so alternative values
/// are written unspaced, `ms|null`), `(…)` is a remark and `→` starts the answer.
pub params: &'static str,
pub enabled: Enabled,
pub run: Run,
@@ -53,6 +56,7 @@ pub struct CommandInfo {
}
impl CommandSpec {
/// Holds because `Session::execute` skips the selection check when `id` or `ids` is given.
pub fn acts_on(&self) -> Option<String> {
let keys = param_keys(self.params).unwrap_or_default();
let named = if keys.contains(&"ids") {
@@ -114,7 +118,7 @@ pub fn has_text(s: &Session) -> std::result::Result<(), String> {
has_doc(s)?;
if s.active().is_some_and(|d| d.selection.text.is_some()) { Ok(()) } else { Err(NO_TEXT_POINT.into()) }
}
/// Text editing or shapes with text selected (formatting commands apply to either).
/// Text editing or selected shapes (formatting commands apply to either).
pub fn has_text_or_shapes(s: &Session) -> std::result::Result<(), String> {
has_doc(s)?;
if s.active().is_some_and(|d| d.selection.text.is_some() || !d.selection.shapes.is_empty()) { Ok(()) } else { Err(SELECT_TEXT_OR_SHAPE.into()) }
+1 -1
View File
@@ -32,7 +32,7 @@ pub fn specs() -> Vec<CommandSpec> {
"Split Cells",
["Table Layout", "Merge"],
None,
"{cell?: [r, c] (else the edited cell), id?} | {row: index, col: index, id?}",
"{cell?: [r, c] (else the edited cell), id?} | {row?: index, col?: index, id?}",
has_selection,
split
),
+1 -1
View File
@@ -24,7 +24,7 @@ list_commands and run them with run_command (or several with batch). Typical flo
{layout:\"titleAndContent\", title, body} → add_shape / add_text_box / insert_picture / insert_chart → \
inspect_slide to read back ids, boxes and text → render_slide to look at the result. Shape ids are looked up on the \
current slide. An inserted shape is selected; run_command edit.select {ids:[…]} selects others. format.* acts on \
the selected text or shapes; shape.fill, shape.line and the other commands whose parameters list `ids` act on \
the selected text or shapes; shape.fill, shape.line and the other shape commands whose parameters list `ids` act on \
those shapes, else on the selected ones. Save with save_presentation (.deckcraft or .pptx).";
/// Resource URIs.