diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:02:58 +0000 |
commit | 698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch) | |
tree | 173a775858bd501c378080a10dca74132f05bc50 /vendor/clap_complete/src/shells/powershell.rs | |
parent | Initial commit. (diff) | |
download | rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip |
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/clap_complete/src/shells/powershell.rs')
-rw-r--r-- | vendor/clap_complete/src/shells/powershell.rs | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/vendor/clap_complete/src/shells/powershell.rs b/vendor/clap_complete/src/shells/powershell.rs new file mode 100644 index 000000000..d35e61c7d --- /dev/null +++ b/vendor/clap_complete/src/shells/powershell.rs @@ -0,0 +1,178 @@ +use std::io::Write; + +use clap::*; + +use crate::generator::{utils, Generator}; +use crate::INTERNAL_ERROR_MSG; + +/// Generate powershell completion file +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub struct PowerShell; + +impl Generator for PowerShell { + fn file_name(&self, name: &str) -> String { + format!("_{}.ps1", name) + } + + fn generate(&self, cmd: &Command, buf: &mut dyn Write) { + let bin_name = cmd + .get_bin_name() + .expect("crate::generate should have set the bin_name"); + + let mut names = vec![]; + let subcommands_cases = generate_inner(cmd, "", &mut names); + + let result = format!( + r#" +using namespace System.Management.Automation +using namespace System.Management.Automation.Language + +Register-ArgumentCompleter -Native -CommandName '{bin_name}' -ScriptBlock {{ + param($wordToComplete, $commandAst, $cursorPosition) + + $commandElements = $commandAst.CommandElements + $command = @( + '{bin_name}' + for ($i = 1; $i -lt $commandElements.Count; $i++) {{ + $element = $commandElements[$i] + if ($element -isnot [StringConstantExpressionAst] -or + $element.StringConstantType -ne [StringConstantType]::BareWord -or + $element.Value.StartsWith('-') -or + $element.Value -eq $wordToComplete) {{ + break + }} + $element.Value + }}) -join ';' + + $completions = @(switch ($command) {{{subcommands_cases} + }}) + + $completions.Where{{ $_.CompletionText -like "$wordToComplete*" }} | + Sort-Object -Property ListItemText +}} +"#, + bin_name = bin_name, + subcommands_cases = subcommands_cases + ); + + w!(buf, result.as_bytes()); + } +} + +// Escape string inside single quotes +fn escape_string(string: &str) -> String { + string.replace('\'', "''") +} + +fn get_tooltip<T: ToString>(help: Option<&str>, data: T) -> String { + match help { + Some(help) => escape_string(help), + _ => data.to_string(), + } +} + +fn generate_inner<'help>( + p: &Command<'help>, + previous_command_name: &str, + names: &mut Vec<&'help str>, +) -> String { + debug!("generate_inner"); + + let command_name = if previous_command_name.is_empty() { + p.get_bin_name().expect(INTERNAL_ERROR_MSG).to_string() + } else { + format!("{};{}", previous_command_name, &p.get_name()) + }; + + let mut completions = String::new(); + let preamble = String::from("\n [CompletionResult]::new("); + + for option in p.get_opts() { + if let Some(shorts) = option.get_short_and_visible_aliases() { + let tooltip = get_tooltip(option.get_help(), shorts[0]); + for short in shorts { + completions.push_str(&preamble); + completions.push_str( + format!( + "'-{}', '{}', {}, '{}')", + short, short, "[CompletionResultType]::ParameterName", tooltip + ) + .as_str(), + ); + } + } + + if let Some(longs) = option.get_long_and_visible_aliases() { + let tooltip = get_tooltip(option.get_help(), longs[0]); + for long in longs { + completions.push_str(&preamble); + completions.push_str( + format!( + "'--{}', '{}', {}, '{}')", + long, long, "[CompletionResultType]::ParameterName", tooltip + ) + .as_str(), + ); + } + } + } + + for flag in utils::flags(p) { + if let Some(shorts) = flag.get_short_and_visible_aliases() { + let tooltip = get_tooltip(flag.get_help(), shorts[0]); + for short in shorts { + completions.push_str(&preamble); + completions.push_str( + format!( + "'-{}', '{}', {}, '{}')", + short, short, "[CompletionResultType]::ParameterName", tooltip + ) + .as_str(), + ); + } + } + + if let Some(longs) = flag.get_long_and_visible_aliases() { + let tooltip = get_tooltip(flag.get_help(), longs[0]); + for long in longs { + completions.push_str(&preamble); + completions.push_str( + format!( + "'--{}', '{}', {}, '{}')", + long, long, "[CompletionResultType]::ParameterName", tooltip + ) + .as_str(), + ); + } + } + } + + for subcommand in p.get_subcommands() { + let data = &subcommand.get_name(); + let tooltip = get_tooltip(subcommand.get_about(), data); + + completions.push_str(&preamble); + completions.push_str( + format!( + "'{}', '{}', {}, '{}')", + data, data, "[CompletionResultType]::ParameterValue", tooltip + ) + .as_str(), + ); + } + + let mut subcommands_cases = format!( + r" + '{}' {{{} + break + }}", + &command_name, completions + ); + + for subcommand in p.get_subcommands() { + let subcommand_subcommands_cases = generate_inner(subcommand, &command_name, names); + subcommands_cases.push_str(&subcommand_subcommands_cases); + } + + subcommands_cases +} |