feat: Add completions subcommand via clap_complete
`ramekin completions <shell>` prints shell completions for bash, zsh,
fish, elvish, or powershell to stdout.
Assisted-by: Claude Opus 4.6 via pi
diff --git a/Cargo.lock b/Cargo.lock
index 854f960..0345cd8 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -146,6 +146,15 @@ dependencies = [
"strsim",
]
+[[package]]
+name = "clap_complete"
+version = "4.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19c9f1dde76b736e3681f28cec9d5a61299cbaae0fce80a68e43724ad56031eb"
+dependencies = [
+ "clap",
+]
+
[[package]]
name = "clap_derive"
version = "4.6.0"
@@ -579,6 +588,7 @@ name = "ramekin"
version = "0.1.0"
dependencies = [
"clap",
+ "clap_complete",
"fastrand",
"fs-err",
"miette",
diff --git a/Cargo.toml b/Cargo.toml
index f74c864..ffeaae1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -7,12 +7,13 @@ edition = "2024"
[dependencies]
clap = { version = "*", features = ["derive"] }
+clap_complete = "*"
miette = { version = "*", features = ["fancy"] }
fastrand = "*"
fs-err = "*"
serde = { version = "*", features = ["derive"] }
# Pinned to prerelease — alpha.4 fixes serde defaults with bare KDL values.
-serde-kdl2 = "0.1.1-alpha.5"
+serde-kdl2 = "0.1.1-alpha.6"
serde_yaml = "*"
shellexpand = "*"
tracing = "*"
diff --git a/src/main.rs b/src/main.rs
index 195ed4c..62ca8b2 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,7 +3,8 @@ mod config;
use std::path::{Path, PathBuf};
use std::process::{Command, Stdio};
-use clap::{Parser, Subcommand};
+use clap::{CommandFactory, Parser, Subcommand};
+use clap_complete::Shell;
use miette::{Context, IntoDiagnostic, Result, bail};
use serde::Serialize;
use tracing::{error, info};
@@ -39,6 +40,11 @@ enum Cmd {
},
/// Show resolved paths and mount configuration
Config,
+ /// Generate shell completions
+ Completions {
+ /// Shell to generate completions for
+ shell: Shell,
+ },
}
fn main() -> Result<()> {
@@ -52,11 +58,19 @@ fn main() -> Result<()> {
let cli = Cli::parse();
let command = cli.command.unwrap_or(Cmd::Run { rebuild: false });
+
+ // Completions doesn't need workspace resolution.
+ if let Cmd::Completions { shell } = command {
+ clap_complete::generate(shell, &mut Cli::command(), "ramekin", &mut std::io::stdout());
+ return Ok(());
+ }
+
let ramekin = Ramekin::resolve(cli.workspace)?;
match command {
Cmd::Run { rebuild } => ramekin.run(rebuild, &cli.pi_args),
Cmd::Config => ramekin.config(),
+ Cmd::Completions { .. } => unreachable!(),
}
}