Skip to content

Commit

Permalink
feat(complete): Dynamic powershell completions
Browse files Browse the repository at this point in the history
  • Loading branch information
MrJerB committed Feb 3, 2024
1 parent 7425ee7 commit f917ec4
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 1 deletion.
2 changes: 2 additions & 0 deletions clap_complete/src/dynamic/shells/mod.rs
Expand Up @@ -3,10 +3,12 @@
mod bash;
mod fish;
mod shell;
mod powershell;

pub use bash::*;
pub use fish::*;
pub use shell::*;
pub use powershell::*;

use std::ffi::OsString;
use std::io::Write as _;
Expand Down
68 changes: 68 additions & 0 deletions clap_complete/src/dynamic/shells/powershell.rs
@@ -0,0 +1,68 @@
/// Completion support for Powershell
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
pub struct Powershell;

impl crate::dynamic::Completer for Powershell {
fn file_name(&self, name: &str) -> String {
format!("{name}.ps1")
}

fn write_registration(
&self,
name: &str,
bin: &str,
completer: &str,
buf: &mut dyn std::io::Write,
) -> Result<(), std::io::Error> {
let bin = shlex::quote(bin);
let completer = shlex::quote(completer);

writeln!(
buf,
r#"
Register-ArgumentCompleter -Native -CommandName {bin} -ScriptBlock {{
param($wordToComplete, $commandAst, $cursorPosition)
$results = Invoke-Expression "&{bin} complete --shell powershell -- $($commandAst.ToString())";
$results | ForEach-Object {{
$split = $_.Split("`t");
$cmd = $split[0];
if ($split.Length -eq 2) {{
$help = $split[1];
}}
else {{
$help = $split[0];
}}
[System.Management.Automation.CompletionResult]::new($cmd, $cmd, 'ParameterValue', $help)
}}
}};
"#
)
}

fn write_complete(
&self,
cmd: &mut clap::Command,
args: Vec<std::ffi::OsString>,
current_dir: Option<&std::path::Path>,
buf: &mut dyn std::io::Write,
) -> Result<(), std::io::Error> {
let index = args.len() - 1;
let completions = crate::dynamic::complete(cmd, args, index, current_dir)?;

for (completion, help) in completions {
write!(buf, "{}", completion.to_string_lossy())?;
if let Some(help) = help {
write!(
buf,
"\t{}",
help.to_string().lines().next().unwrap_or_default()
)?;
}
writeln!(buf)?;
}
Ok(())
}
}
6 changes: 5 additions & 1 deletion clap_complete/src/dynamic/shells/shell.rs
Expand Up @@ -12,6 +12,8 @@ pub enum Shell {
Bash,
/// Friendly Interactive SHell (fish)
Fish,
/// Powershell
Powershell,
}

impl Display for Shell {
Expand Down Expand Up @@ -39,13 +41,14 @@ impl FromStr for Shell {
// Hand-rolled so it can work even when `derive` feature is disabled
impl ValueEnum for Shell {
fn value_variants<'a>() -> &'a [Self] {
&[Shell::Bash, Shell::Fish]
&[Shell::Bash, Shell::Fish, Shell::Powershell]
}

fn to_possible_value<'a>(&self) -> Option<PossibleValue> {
Some(match self {
Shell::Bash => PossibleValue::new("bash"),
Shell::Fish => PossibleValue::new("fish"),
Shell::Powershell => PossibleValue::new("powershell"),
})
}
}
Expand All @@ -55,6 +58,7 @@ impl Shell {
match self {
Self::Bash => &super::Bash,
Self::Fish => &super::Fish,
Self::Powershell => &super::Powershell,
}
}
}
Expand Down

0 comments on commit f917ec4

Please sign in to comment.