Skip to content

Commit

Permalink
feat: Untested Bash impl
Browse files Browse the repository at this point in the history
  • Loading branch information
ysthakur committed Aug 17, 2023
1 parent 6a1969a commit 1f43bd4
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 18 deletions.
75 changes: 62 additions & 13 deletions src/gen/bash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,71 @@ use crate::{gen::util::Output, parse::CommandInfo};
/// Generate a completion file for Bash
pub fn generate(
cmd_name: &str,
_cmd_info: &CommandInfo,
cmd_info: &CommandInfo,
out_dir: &Path,
) -> Result<()> {
// TODO make option to not overwrite file
let comp_name = format!("_comp_cmd_{cmd_name}");

let mut res = Output::new(String::from("\t"));
res.writeln("#!/usr/bin/env bash\n");
res.writeln(&format!("function {comp_name} {{"));
res.writeln("COMPREPLY=()");
res.writeln("case ${COMP_CWORD} in");
// generate_fn(&cmd_name, cmd_info, &mut res, 0, &comp_name);
res.writeln("esac");
res.writeln("return 0");
res.writeln("}");

fs::write(out_dir.join(format!("_{cmd_name}.bash")), res.text())?;
let mut out = Output::new(String::from("\t"));
out.writeln("#!/usr/bin/env bash\n");
out.writeln(format!("function {comp_name} {{"));
out.indent();
out.writeln("COMPREPLY=()");

generate_cmd(cmd_info, 1, &mut out);

out.writeln("return 0");
out.dedent();
out.writeln("}\n");

out.writeln(format!("complete -F _comp_cmd_{cmd_name} {cmd_name}"));

fs::write(out_dir.join(format!("_{cmd_name}.bash")), out.text())?;
Ok(())
}

fn generate_cmd(cmd_info: &CommandInfo, pos: usize, out: &mut Output) {
out.writeln("case $COMP_CWORD in");
out.indent();

let flags = cmd_info
.flags
.iter()
.map(|f| f.forms.join(" "))
.collect::<Vec<_>>()
.join(" ");
let subcmds = cmd_info
.subcommands
.keys()
.map(String::from)
.collect::<Vec<_>>()
.join(" ");
let completions = format!("{flags} {subcmds}");
// This case is for when the subcommand we're processing is the one to
// complete
out.writeln(format!(
"{pos}) COMPREPLY=($(compgen -W '{completions}' -- $2)) ;;"
));

// This case is in case we need to go further to a deeper subcommand
if !cmd_info.subcommands.is_empty() {
out.writeln("*)");
out.indent();
out.writeln(format!("case ${{COMP_WORDS[{pos}]}} in"));
out.indent();
for (cmd_name, cmd_info) in &cmd_info.subcommands {
out.writeln(format!("{cmd_name})"));
out.indent();
generate_cmd(cmd_info, pos + 1, out);
out.writeln(";;");
out.dedent();
}
out.dedent();
out.writeln("esac");
out.writeln(";;");
out.dedent();
}

out.dedent();
out.writeln("esac");
}
5 changes: 5 additions & 0 deletions tests/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,11 @@ fn test1_zsh() {
run_test("zsh", &["test1"], &["--cmds", "^test1"]);
}

#[test]
fn test1_bash() {
run_test("bash", &["test1"], &["--cmds", "^test1"]);
}

#[test]
fn test1_nu() {
run_test("nu", &["test1"], &["--cmds", "^test1"]);
Expand Down
17 changes: 12 additions & 5 deletions tests/resources/expected/_test1.bash

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 1f43bd4

Please sign in to comment.