private/functions/tabcompletion/tabcompletion.ps1
function global:New-DbaTeppCompletionResult { <# .SYNOPSIS Generates a completion result for dbatools internal tab completion. .DESCRIPTION Generates a completion result for dbatools internal tab completion. .PARAMETER CompletionText The text to propose. .PARAMETER ToolTip The tooltip to show in tooltip-aware hosts (ISE, mostly) .PARAMETER ListItemText ??? .PARAMETER CompletionResultType The type of object that is being completed. By default it generates one of type parameter value. .PARAMETER NoQuotes Whether to put the result in quotes or not. .EXAMPLE New-DbaTeppCompletionResult -CompletionText 'master' -ToolTip 'master' Returns a CompletionResult with the text and tooltip 'master' #> param ( [Parameter(ValueFromPipelineByPropertyName, Mandatory, ValueFromPipeline)] [ValidateNotNullOrEmpty()] [string] $CompletionText, [Parameter(Position = 1, ValueFromPipelineByPropertyName)] [string] $ToolTip, [Parameter(Position = 2, ValueFromPipelineByPropertyName)] [string] $ListItemText, [System.Management.Automation.CompletionResultType] $CompletionResultType = [System.Management.Automation.CompletionResultType]::ParameterValue, [switch] $NoQuotes = $false ) process { $toolTipToUse = if ($ToolTip -eq '') { $CompletionText } else { $ToolTip } $listItemToUse = if ($ListItemText -eq '') { $CompletionText } else { $ListItemText } # If the caller explicitly requests that quotes # not be included, via the -NoQuotes parameter, # then skip adding quotes. if ($CompletionResultType -eq [System.Management.Automation.CompletionResultType]::ParameterValue -and -not $NoQuotes) { # Add single quotes for the caller in case they are needed. # We use the parser to robustly determine how it will treat # the argument. If we end up with too many tokens, or if # the parser found something expandable in the results, we # know quotes are needed. $tokens = $null $null = [System.Management.Automation.Language.Parser]::ParseInput("echo $CompletionText", [ref]$tokens, [ref]$null) if ($tokens.Length -ne 3 -or ($tokens[1] -is [System.Management.Automation.Language.StringExpandableToken] -and $tokens[1].Kind -eq [System.Management.Automation.Language.TokenKind]::Generic)) { $CompletionText = "'$CompletionText'" } } return New-Object System.Management.Automation.CompletionResult($CompletionText, $listItemToUse, $CompletionResultType, $toolTipToUse.Trim()) } } (Get-Item Function:\New-DbaTeppCompletionResult).Visibility = "Private" function Register-DbaTeppArgumentCompleter { <# .SYNOPSIS Registers a parameter for a prestored Tepp. .DESCRIPTION Registers a parameter for a prestored Tepp. This function allows easily registering a function's parameter for Tepp in the function-file, rather than in a centralized location. .PARAMETER Command Name of the command whose parameter should receive Tepp. Supports multiple commands at the same time in order to optimize performance. .PARAMETER Parameter Name of the parameter that should be Tepp'ed. .PARAMETER Name Name of the Tepp Completioner to use. Defaults to the parameter name. Best practice requires a Completioner to be named the same as the completed parameter, in which case this parameter needs not be specified. However sometimes that may not be universally possible, which is when this parameter comes in. .PARAMETER All Whether this TEPP applies to all commands in dbatools that have the specified parameter. .EXAMPLE Register-DbaTeppArgumentCompleter -Command Get-DbaDbBackupHistory -Parameter Database Registers the "Database" parameter of the Get-DbaDbBackupHistory to receive Database-Tepp #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingEmptyCatchBlock", "")] param ( [string[]]$Command, [string[]]$Parameter, [string]$Name, [switch]$All ) #region ScriptBlock $scriptBlock = { param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter ) if ($teppScript = [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::GetTeppScript($commandName, $parameterName)) { $start = Get-Date $teppScript.LastExecution = $start $teppScript.LastDuration = New-Object System.TimeSpan(-1) # Null it, just in case. It's a new start. try { $ExecutionContext.InvokeCommand.InvokeScript($true, ([System.Management.Automation.ScriptBlock]::Create($teppScript.ScriptBlock.ToString())), $null, @($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter)) } catch { $null = 1 } $teppScript.LastDuration = (Get-Date) - $start } } #endregion ScriptBlock foreach ($p in $Parameter) { $lowername = $PSBoundParameters.Name if ($null -eq $lowername) { $lowername = $p.ToLowerInvariant() } else { $lowername = $lowername.ToLowerInvariant() } if ($All) { [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::AddTabCompletionSet("*", $p, $lowername) } else { foreach ($c in $Command) { [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::AddTabCompletionSet($c, $p, $lowername) } } if ($script:TEPP) { TabExpansionPlusPlus\Register-ArgumentCompleter -CommandName $Command -ParameterName $p -ScriptBlock $scriptBlock } else { Register-ArgumentCompleter -CommandName $Command -ParameterName $p -ScriptBlock $scriptBlock } } } function Register-DbaTeppInstanceCacheBuilder { <# .SYNOPSIS Registers a scriptblock used to build the TEPP cache from an instance connection. .DESCRIPTION Registers a scriptblock used to build the TEPP cache from an instance connection. Used only on import of the module. .PARAMETER ScriptBlock The ScriptBlock used to build the cache. The ScriptBlock may assume the following two variables to exist: - $FullSmoName (A string containing the full SMO name as presented by the DbaInstanceParameter class-interpreted input) - $server (An SMO connection object) .PARAMETER Slow This switch implies a gathering process that takes too much time to be performed synchronously. Basically, when retrieving the information takes more than 25ms on an average server (on top of establishing the original connection), this switch should be set. .EXAMPLE Register-DbaTeppInstanceCacheBuilder -ScriptBlock $ScriptBlock Registers the scriptblock stored in the aptly named variable $ScriptBlock as a fest cache building scriptblock. Note: The scriptblock must execute swiftly! (less than 25ms) .EXAMPLE Register-DbaTeppInstanceCacheBuilder -ScriptBlock $ScriptBlock -Slow Registers the scriptblock stored in the aptly named variable $ScriptBlock as a slow cache building scriptblock. This is suitable for cache building scriptblocks that take a while to execute. .NOTES Additional information about the function. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [System.Management.Automation.ScriptBlock] $ScriptBlock, [switch] $Slow ) if ($Slow -and ([Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppGatherScriptsSlow -notcontains $ScriptBlock)) { [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppGatherScriptsSlow.Add($ScriptBlock) } elseif ([Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppGatherScriptsFast -notcontains $ScriptBlock) { [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::TeppGatherScriptsFast.Add($ScriptBlock) } } function Register-DbaTeppScriptblock { <# .SYNOPSIS Registers a scriptblock under name, to later be available for TabExpansion. .DESCRIPTION Registers a scriptblock under name, to later be available for TabExpansion. .PARAMETER ScriptBlock The scriptblock to register. .PARAMETER Name The name under which the scriptblock should be registered. .EXAMPLE Register-DbaTeppScriptblock -ScriptBlock $scriptBlock -Name MyFirstTeppScriptBlock Stores the scriptblock stored in $scriptBlock under the name "MyFirstTeppScriptBlock" #> [CmdletBinding()] param ( [System.Management.Automation.ScriptBlock] $ScriptBlock, [string] $Name ) $scp = New-Object Dataplat.Dbatools.TabExpansion.ScriptContainer $scp.Name = $Name.ToLowerInvariant() $scp.ScriptBlock = $ScriptBlock $scp.LastDuration = New-TimeSpan -Seconds -1 [Dataplat.Dbatools.TabExpansion.TabExpansionHost]::Scripts[$Name.ToLowerInvariant()] = $scp } |