Microsoft.PowerShell.Utility.ArgumentCompleters.ps1
# # Reading the registry for progids takes > 500ms, so we do it just once # function InitClassIdTable { $progIds = [Microsoft.Win32.Registry]::ClassesRoot.GetSubKeyNames() $versionedProgIds = new-object System.Collections.Generic.List[string] function AddProgId($progId) { $subKey = [Microsoft.Win32.Registry]::ClassesRoot.OpenSubKey($progId) foreach ($clsidSubkey in $subKey.GetSubKeyNames()) { if ($clsidSubkey -eq 'CLSID') { $description = $subKey.GetValue('') $result[$progId] = $description break } } } $result = [ordered]@{} foreach ($progId in $progIds) { # Skip versioned progIds (ends in digits) for now - we'll make a second pass # and add those if there is no version indepent progId. if ($progId -match '^(\w+\.\w+)\.[\d]+(\.\d+)?$') { $versionedProgIds.Add($progId) continue } # Check if it really is a progId - does it have a CLSID underneath AddProgId $progId } foreach ($progId in $versionedProgIds) { $null = $progId -match '^(\w+\.\w+)\.[\d]+(\.\d+)?$' if (!$result[$matches[1]]) { AddProgId $progId } } return $result } # # .SYNOPSIS # # Complete -ComObject arguments # function NewComObjectCompletion { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) $allProgIds = Get-CompletionPrivateData -Key New-Object_ComObject if (!$allProgIds) { $allProgIds = InitClassIdTable Set-CompletionPrivateData -Key New-Object_ComObject -Value $allProgIds } # TODO - is sorting from intialization good enough? This completion is pretty slow # as is if $wordToComplete is empty. $allProgIds.GetEnumerator() | Where-Object Key -like "$wordToComplete*" | ForEach-Object { $progId = $_.Key $tooltip = $_.Value New-CompletionResult $progId $tooltip } } # # .SYNOPSIS # # Complete event name arguments # function EventNameCompletion { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) $inputObject = $fakeBoundParameter["InputObject"] if ($null -ne $inputObject) { $inputObject.GetType().GetEvents("Public,Instance").Name | Where-Object { $_ -like "$wordToComplete*" } | Sort-Object | ForEach-Object { New-CompletionResult $_ "Event $_" } } } # # .SYNOPSIS # # Complete the -Name argument to Out-Printer # function OutPrinterNameArgumentCompletion { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) Get-WmiObject -Class Win32_Printer | Where-Object Name -like "$wordToComplete*" | Sort-Object Name | ForEach-Object { New-CompletionResult $_.Name $_.Location } } # # .SYNOPSIS # # Complete arguments that take ps1xml files for the Update-[Type|Format]Data commands. # function AddTypePathArgumentCompletion { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) Get-CompletionWithExtension $lastWord ('.dll', '.cs', '.vb', '.js') } # # .SYNOPSIS # # Complete arguments that take ps1xml files for the Update-[Type|Format]Data commands. # function Ps1xmlPathArgumentCompletion { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) Get-CompletionWithExtension $lastWord '.ps1xml' } # # .SYNOPSIS # # Complete the -SerializationMethod argument to Update-TypeData # function UpdateTypeDataSerializationMethodCompleter { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) $sm = [PSObject].Assembly.GetType('System.Management.Automation.SerializationMethod') [System.Enum]::GetNames($sm) | Where-Object {$_ -like "*$wordToComplete*"} | Sort-Object | Foreach-Object { New-CompletionResult $_ $_ } } # # .SYNOPSIS # # Complete the SourceIdentifier argument to Register-EngineEvent # function EventNameCompletion { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) [System.Management.Automation.PsEngineEvent].GetFields() | ForEach-Object { $_.GetValue($null) } | Sort-Object | Where-Object {$_ -like "*$wordToComplete*"} | ForEach-Object { New-CompletionResult $_ $_ } } # # .SYNOPSIS # # Complete the TypeName argument to Update-TypeData # function UpdateTypeTypeNameCompleter { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) [System.Management.Automation.CompletionCompleters]::CompleteType($wordToComplete) } # # .SYNOPSIS # # Complete the Id argument for Disable-PSBreakPoint # function DisablePSBreakpointIdCompleter { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) Microsoft.PowerShell.Utility\Get-PSBreakpoint | Where-Object { $_.Enabled -and $_.Id -like "*$wordToComplete*" } | ForEach-Object { $toolTip = "Script: {0} Type: {1}" -f $_.Script, $_.GetType().Name New-CompletionResult $_.Id $toolTip } } # # .SYNOPSIS # # Complete the Id argument for Disable-PSBreakPoint # function RemovePSBreakpointIdCompleter { param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter) Microsoft.PowerShell.Utility\Get-PSBreakpoint | Where-Object { $_.Id -like "*$wordToComplete*" } | ForEach-Object { $toolTip = "Script: {0} Type: {1}" -f $_.Script, $_.GetType().Name New-CompletionResult $_.Id $toolTip } } Register-ArgumentCompleter ` -Command 'New-Object' ` -Parameter 'ComObject' ` -Description 'Complete com object class ids for New-Object -ComObject <TAB>' ` -ScriptBlock $function:NewComObjectCompletion Register-ArgumentCompleter ` -Command 'Register-ObjectEvent' ` -Parameter 'EventName' ` -Description @' Complete the -EventName argument for Register-ObjectEvent, for example: $timer = new-object System.Timers.Timer Register-ObjectEvent -InputObject $timer -EventName <TAB> '@ ` -ScriptBlock $function:EventNameCompletion Register-ArgumentCompleter ` -Command 'Out-Printer' ` -Parameter 'Name' ` -Description 'Complete printer names for Out-Printer' ` -ScriptBlock $function:OutPrinterNameArgumentCompletion Register-ArgumentCompleter ` -Command 'Add-Type' ` -Parameter 'Path' ` -Description 'Complete source code and dlls for Add-Type -Path' ` -ScriptBlock $function:AddTypePathArgumentCompletion Register-ArgumentCompleter ` -Command 'Add-Type' ` -Parameter 'LiteralPath' ` -Description 'Complete source code and dlls for Add-Type -LiteralPath' ` -ScriptBlock $function:AddTypePathArgumentCompletion Register-ArgumentCompleter ` -Command ('Update-TypeData', 'Update-FormatData') ` -Parameter 'AppendPath' ` -Description 'Complete ps1xml files for -AppendPath' ` -ScriptBlock $function:Ps1xmlPathArgumentCompletion Register-ArgumentCompleter ` -Command ('Update-TypeData', 'Update-FormatData') ` -Parameter 'PrependPath' ` -Description 'Complete ps1xml files for -PrependPath' ` -ScriptBlock $function:Ps1xmlPathArgumentCompletion Register-ArgumentCompleter ` -Command 'Update-TypeData' ` -Parameter 'SerializationMethod' ` -Description 'Complete the -SerializationMethod argument to Update-TypeData. For example: Update-TypeData -SerializationMethod <TAB>' ` -ScriptBlock $function:UpdateTypeDataSerializationMethodCompleter Register-ArgumentCompleter ` -Command 'Register-EngineEvent' ` -Parameter 'SourceIdentifier' ` -Description 'Complete the -SourceIdentifier argument for Register-ObjectEvent, for example: Register-EngineEvent -SourceIdentifier <TAB>' ` -ScriptBlock $function:EventNameCompletion Register-ArgumentCompleter ` -Command ('Get-TypeData','Remove-TypeData','Update-TypeData') ` -Parameter 'TypeName' ` -Description 'Complete names of types: Update-TypeData -TypeName <TAB>' ` -ScriptBlock $function:UpdateTypeTypeNameCompleter Register-ArgumentCompleter ` -Command ('Disable-PSBreakpoint') ` -Parameter 'Id' ` -Description 'Complete Id parameter: Disable-PSBreakpoint -Id <TAB>' ` -ScriptBlock $function:DisablePSBreakpointIdCompleter Register-ArgumentCompleter ` -Command ('Remove-PSBreakpoint') ` -Parameter 'Id' ` -Description 'Complete Id parameter: Remove-PSBreakpoint -Id <TAB>' ` -ScriptBlock $function:RemovePSBreakpointIdCompleter |