1use super::Generator;
2
3use crate::acore::Error;
4use crate::SHELL_PSH;
5
6#[derive(Debug, Clone, Copy, Default)]
7pub struct PowerShell;
8
9impl Generator for PowerShell {
10 type Err = Error;
11
12 fn is_avail(&self, name: &str) -> bool {
13 name == SHELL_PSH
14 }
15
16 fn generate(&self, name: &str, bin: &str) -> Result<String, Self::Err> {
17 let template = r#"Register-ArgumentCompleter -Native -CommandName PROGRAM -ScriptBlock {
18 param($wordToComplete, $commandAst, $cursorPosition)
19
20 $words = $commandAst.CommandElements
21 $curr = $wordToComplete
22 $prev = 'PROGRAM'
23 $cword = 0
24 $index = 0
25 $commandline = $commandAst.ToString()
26 for (; $index -lt $cursorPosition; $index++) {
27 if ($commandline[$index] -match '\s+') {
28 $cword++
29 }
30 }
31 if (-not [char]::IsWhiteSpace($commandline[$cursorPosition]) -and [string]::IsNullOrWhiteSpace($curr)) {
32 $cword ++
33 }
34 if ($words.Count -gt 1) {
35 $prev = if ([string]::IsNullOrWhiteSpace($curr)) { $words[-1] } else { $words[-2] }
36 }
37 try {
38 $completions = & PROGRAM --_shell SHELL --_curr "`"$curr`"" --_prev "`"$prev`"" --_cword "`"$cword`"" $words;
39
40 if ($LASTEXITCODE -eq 0) {
41 return $completions | ForEach-Object {
42 $split = $_.Split("`t");
43 $name = $split[0].Trim();
44 $desc = if ($split.Length -gt 1) { $split[1] } else { $name }
45
46 [System.Management.Automation.CompletionResult]::new($name, $name, 'ParameterValue', $desc)
47 }
48 }
49 }
50 catch { }
51
52 return @()
53};
54"#;
55
56 Ok(template
57 .replace("NAME", name)
58 .replace("PROGRAM", bin)
59 .replace("SHELL", SHELL_PSH))
60 }
61}