use crate::Generator;
use argh_shared::{CommandInfoWithArgs, FlagInfoKind};
use std::fmt::Write;
pub struct Fish;
impl Generator for Fish {
fn generate(cmd_name: &str, cmd: &CommandInfoWithArgs<'_>) -> String {
let mut out = String::new();
generate_fish_cmd(&mut out, cmd_name, cmd, "");
for subcmd in &cmd.commands {
let subcmd_condition = format!("-n \"__fish_seen_subcommand_from {}\"", subcmd.name);
generate_fish_cmd(&mut out, cmd_name, &subcmd.command, &subcmd_condition);
}
out
}
}
fn generate_fish_cmd(
out: &mut String,
base_cmd: &str,
cmd: &CommandInfoWithArgs<'_>,
condition: &str,
) {
for flag in cmd.flags {
let mut line = format!("complete -c {}", base_cmd);
if !condition.is_empty() {
line.push(' ');
line.push_str(condition);
}
if !flag.long.is_empty() {
let stripped_long = flag.long.trim_start_matches('-');
if !stripped_long.is_empty() {
line.push_str(&format!(" -l {}", stripped_long));
}
}
if let Some(short) = flag.short {
line.push_str(&format!(" -s {}", short));
}
if let FlagInfoKind::Option { arg_name } = flag.kind {
line.push_str(" -r");
let _ = arg_name; }
if !flag.description.is_empty() {
let description = flag.description.replace("'", "\\'");
line.push_str(&format!(" -d '{}'", description));
}
writeln!(out, "{}", line).unwrap();
}
for subcmd in &cmd.commands {
let mut line = format!("complete -c {}", base_cmd);
if !condition.is_empty() {
line.push_str(&format!(" {} -f -a '{}'", condition, subcmd.name));
} else {
line.push_str(&format!(
" -n \"not __fish_seen_subcommand_from ...\" -f -a '{}'",
subcmd.name
));
line = format!(
"complete -c {} -f -a '{}' -d '{}'",
base_cmd,
subcmd.name,
subcmd.command.description.replace("'", "\\'")
);
}
writeln!(out, "{}", line).unwrap();
}
}