Skip to content

Commit

Permalink
Add support for static shell completions
Browse files Browse the repository at this point in the history
Closes #170
  • Loading branch information
shanesveller committed Nov 18, 2024
1 parent a94fea2 commit 1d16ff4
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 0 deletions.
31 changes: 31 additions & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,15 @@ fn build_cli(default_user: Option<User>, default_host: Option<Host>) -> Command
.action(ArgAction::SetTrue),
),
)
.subcommand(Command::new("completions")
.about("Print tab-completion code for a given supported shell")
.arg(
Arg::new("shell")
.help("Shell dialect")
.action(ArgAction::Set)
.value_parser(value_parser!(clap_complete::Shell))
)
)
}

/// Use [`clap`] to implement the intended command line interface.
Expand Down Expand Up @@ -383,6 +392,14 @@ fn specified_workflow<'a>(
});
}

("completions", matches) => {
if let Some(shell) = matches.get_one::<clap_complete::Shell>("shell").copied() {
return Ok(Workflow::Completions(shell));
} else {
return Err(anyhow::anyhow!("Unsupported shell"));
}
}

_ => unreachable!("unknown subcommand"),
};
}
Expand Down Expand Up @@ -464,6 +481,20 @@ mod test_e2e {
assert!(!renderer.as_str().is_empty());
}

/// Invoking all the real logic in `nomad` should not panic.
#[test]
fn nomad_completions() {
let origin = GitRemote::init(None);
let mut renderer = MemoryRenderer::new();
nomad(
&mut renderer,
["git-nomad", "completions", "bash"],
origin.working_directory(),
)
.unwrap();
assert!(renderer.as_str().contains("complete -F _git-nomad -o"));
}

/// Syncing should pick up nomad refs from other hosts.
///
/// When the other host deletes their branch (and thus deletes their nomad ref on the remote),
Expand Down
15 changes: 15 additions & 0 deletions src/workflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub enum Workflow<'a> {
remote: Remote<'a>,
host_filter: Filter<Host<'a>>,
},
Completions(clap_complete::Shell),
}

impl Workflow<'_> {
Expand Down Expand Up @@ -58,6 +59,7 @@ impl Workflow<'_> {
remote,
host_filter,
} => purge(renderer, git, &user, &remote, host_filter),
Self::Completions(shell) => print_completions(renderer, shell),
}
}
}
Expand Down Expand Up @@ -200,6 +202,19 @@ fn purge(
Ok(())
}

/// Use [`clap_complete`] to emit shell syntax for tab-completions
fn print_completions(
renderer: &mut impl Renderer,
gen: impl clap_complete::Generator,
) -> Result<()> {
let mut cmd = crate::build_cli(None, None);
let bin_name = cmd.get_name().to_string();
renderer.writer(|writer| {
clap_complete::generate(gen, &mut cmd, bin_name, writer);
Ok(())
})
}

#[cfg(test)]
mod test {
use crate::{
Expand Down

0 comments on commit 1d16ff4

Please sign in to comment.