functions/tabexpansion/Register-PSFTeppScriptblock.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
function Register-PSFTeppScriptblock
{
    <#
        .SYNOPSIS
            Registers a scriptblock under name, to later be available for TabExpansion.
         
        .DESCRIPTION
            Registers a scriptblock under name, to later be available for TabExpansion.
  
   This system supports two separate types of input: Full or Simple.
  
   Simple:
   The scriptblock simply must return string values.
   PSFramework will then do the rest of the processing when the user asks for tab completion.
   This is the simple-most way to implement tab completion, for a full example, look at the first example in this help.
  
   Full:
   A full scriptblock implements all that is needed to provide Tab Expansion.
   For more details and guidance, see the following concept help:
    Get-Help about_psf_tabexpansion
         
        .PARAMETER ScriptBlock
            The scriptblock to register.
         
        .PARAMETER Name
            The name under which the scriptblock should be registered.
   It is recommended to prefix the name with the module (e.g.: mymodule.<name>), as names are shared across all implementing modules.
  
  .PARAMETER Mode
   Whether the script provided is a full or simple scriptblock.
   By default, this function automatically detects this, but just in case, you can override this detection.
  
  .EXAMPLE
   Register-PSFTeppScriptblock -Name "psalcohol-liquids" -ScriptBlock { "beer", "mead", "wine", "vodka", "whiskey", "rum" }
   Register-PSFTeppArgumentCompleter -Command Get-Alcohol -Parameter Type -Name "psalcohol-liquids"
  
   In step one we set a list of questionable liquids as the list of available beverages for parameter 'Type' on the command 'Get-Alcohol'
         
        .EXAMPLE
            Register-PSFTeppScriptblock -ScriptBlock $scriptBlock -Name MyFirstTeppScriptBlock
     
            Stores the scriptblock stored in $scriptBlock under the name "MyFirstTeppScriptBlock"
  
  .EXAMPLE
   $scriptBlock = { (Get-ChildItem (Get-PSFConfigValue -FullName mymodule.path.scripts -Fallback "$env:USERPROFILE\Documents\WindowsPowerShell\Scripts")).FullName }
   Register-PSFTeppScriptblock -Name mymodule-scripts -ScriptBlock $scriptBlock -Mode Simple
  
   Stores a simple scriptblock that will return a list of strings under the name "mymodule-scripts".
   The system will wrap all the stuff around this that is necessary to provide Tab Expansion and filter out output that doesn't fit the user input so far.
    #>

    [CmdletBinding()]
    Param (
        [Parameter(Mandatory = $true)]
        [System.Management.Automation.ScriptBlock]
        $ScriptBlock,
        
        [Parameter(Mandatory = $true)]
        [string]
        $Name,
        
        [PSFramework.TabExpansion.TeppScriptMode]
        $Mode = "Auto"
    )
    
    $scp = New-Object PSFramework.TabExpansion.ScriptContainer
    $scp.Name = $Name.ToLower()
    $scp.LastDuration = New-TimeSpan -Seconds -1
    
    if ($Mode -like "Auto")
    {
        $ast = [System.Management.Automation.Language.Parser]::ParseInput($ScriptBlock, [ref]$null, [ref]$null)
        $simple = $null -eq $ast.ParamBlock
    }
    elseif ($Mode -like "Simple") { $simple = $true }
    else { $simple = $false }
    
    if ($simple)
    {
        $scr = [scriptblock]::Create(@'
 param (
  $commandName,
   
  $parameterName,
   
  $wordToComplete,
   
  $commandAst,
   
  $fakeBoundParameter
 )
 
 $start = Get-Date
 [PSFramework.TabExpansion.TabExpansionHost]::Scripts["<name>"].LastExecution = $start
   
 $innerScript = [ScriptBlock]::Create(([PSFramework.TabExpansion.TabExpansionHost]::Scripts["<name>"].InnerScriptBlock))
 $items = $innerScript.Invoke()
   
 foreach ($item in ($items | Where-Object { "$_" -like "$wordToComplete*"} | Sort-Object))
 {
  New-PSFTeppCompletionResult -CompletionText $item -ToolTip $item
 }
 
 [PSFramework.TabExpansion.TabExpansionHost]::Scripts["<name>"].LastDuration = (Get-Date) - $start
'@
.Replace("<name>", $Name.ToLower()))
        $scp.ScriptBlock = $scr
        $scp.InnerScriptBlock = $ScriptBlock
    }
    else
    {
        $scp.ScriptBlock = $ScriptBlock
    }
    [PSFramework.TabExpansion.TabExpansionHost]::Scripts[$Name.ToLower()] = $scp
}