aboutsummaryrefslogtreecommitdiff
path: root/clap/src/completions/powershell.rs
diff options
context:
space:
mode:
authorRobin Krahl <robin.krahl@ireas.org>2020-01-07 11:18:04 +0000
committerDaniel Mueller <deso@posteo.net>2020-01-08 09:20:25 -0800
commit5e20a29b4fdc8a2d442d1093681b396dcb4b816b (patch)
tree55ab083fa8999d2ccbb5e921c1ffe52560dca152 /clap/src/completions/powershell.rs
parent203e691f46d591a2cc8acdfd850fa9f5b0fb8a98 (diff)
downloadnitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.gz
nitrocli-5e20a29b4fdc8a2d442d1093681b396dcb4b816b.tar.bz2
Add structopt dependency in version 0.3.7
This patch series replaces argparse with structopt in the argument handling code. As a first step, we need structopt as a dependency. Import subrepo structopt/:structopt at efbdda4753592e27bc430fb01f7b9650b2f3174d Import subrepo bitflags/:bitflags at 30668016aca6bd3b02c766e8347e0b4080d4c296 Import subrepo clap/:clap at 784524f7eb193e35f81082cc69454c8c21b948f7 Import subrepo heck/:heck at 093d56fbf001e1506e56dbfa38631d99b1066df1 Import subrepo proc-macro-error/:proc-macro-error at 6c4cfe79a622c5de8ae68557993542be46eacae2 Import subrepo proc-macro2/:proc-macro2 at d5d48eddca4566e5438e8a2cbed4a74e049544de Import subrepo quote/:quote at 727436c6c137b20f0f34dde5d8fda2679b9747ad Import subrepo rustversion/:rustversion at 0c5663313516263059ce9059ef81fc7a1cf655ca Import subrepo syn-mid/:syn-mid at 5d3d85414a9e6674e1857ec22a87b96e04a6851a Import subrepo syn/:syn at e87c27e87f6f4ef8919d0372bdb056d53ef0d8f3 Import subrepo textwrap/:textwrap at abcd618beae3f74841032aa5b53c1086b0a57ca2 Import subrepo unicode-segmentation/:unicode-segmentation at 637c9874c4fe0c205ff27787faf150a40295c6c3 Import subrepo unicode-width/:unicode-width at 3033826f8bf05e82724140a981d5941e48fce393 Import subrepo unicode-xid/:unicode-xid at 4baae9fffb156ba229665b972a9cd5991787ceb7
Diffstat (limited to 'clap/src/completions/powershell.rs')
-rw-r--r--clap/src/completions/powershell.rs139
1 files changed, 139 insertions, 0 deletions
diff --git a/clap/src/completions/powershell.rs b/clap/src/completions/powershell.rs
new file mode 100644
index 0000000..9fc77c7
--- /dev/null
+++ b/clap/src/completions/powershell.rs
@@ -0,0 +1,139 @@
+// Std
+use std::io::Write;
+
+// Internal
+use app::parser::Parser;
+use INTERNAL_ERROR_MSG;
+
+pub struct PowerShellGen<'a, 'b>
+where
+ 'a: 'b,
+{
+ p: &'b Parser<'a, 'b>,
+}
+
+impl<'a, 'b> PowerShellGen<'a, 'b> {
+ pub fn new(p: &'b Parser<'a, 'b>) -> Self { PowerShellGen { p: p } }
+
+ pub fn generate_to<W: Write>(&self, buf: &mut W) {
+ let bin_name = self.p.meta.bin_name.as_ref().unwrap();
+
+ let mut names = vec![];
+ let subcommands_cases =
+ generate_inner(self.p, "", &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('-')) {{
+ 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<'a, 'b, 'p>(
+ p: &'p Parser<'a, 'b>,
+ previous_command_name: &str,
+ names: &mut Vec<&'p str>,
+) -> String {
+ debugln!("PowerShellGen::generate_inner;");
+ let command_name = if previous_command_name.is_empty() {
+ p.meta.bin_name.as_ref().expect(INTERNAL_ERROR_MSG).clone()
+ } else {
+ format!("{};{}", previous_command_name, &p.meta.name)
+ };
+
+ let mut completions = String::new();
+ let preamble = String::from("\n [CompletionResult]::new(");
+
+ for option in p.opts() {
+ if let Some(data) = option.s.short {
+ let tooltip = get_tooltip(option.b.help, data);
+ completions.push_str(&preamble);
+ completions.push_str(format!("'-{}', '{}', {}, '{}')",
+ data, data, "[CompletionResultType]::ParameterName", tooltip).as_str());
+ }
+ if let Some(data) = option.s.long {
+ let tooltip = get_tooltip(option.b.help, data);
+ completions.push_str(&preamble);
+ completions.push_str(format!("'--{}', '{}', {}, '{}')",
+ data, data, "[CompletionResultType]::ParameterName", tooltip).as_str());
+ }
+ }
+
+ for flag in p.flags() {
+ if let Some(data) = flag.s.short {
+ let tooltip = get_tooltip(flag.b.help, data);
+ completions.push_str(&preamble);
+ completions.push_str(format!("'-{}', '{}', {}, '{}')",
+ data, data, "[CompletionResultType]::ParameterName", tooltip).as_str());
+ }
+ if let Some(data) = flag.s.long {
+ let tooltip = get_tooltip(flag.b.help, data);
+ completions.push_str(&preamble);
+ completions.push_str(format!("'--{}', '{}', {}, '{}')",
+ data, data, "[CompletionResultType]::ParameterName", tooltip).as_str());
+ }
+ }
+
+ for subcommand in &p.subcommands {
+ let data = &subcommand.p.meta.name;
+ let tooltip = get_tooltip(subcommand.p.meta.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.subcommands {
+ let subcommand_subcommands_cases =
+ generate_inner(&subcommand.p, &command_name, names);
+ subcommands_cases.push_str(&subcommand_subcommands_cases);
+ }
+
+ subcommands_cases
+}