Mineplex2018-withcommit/Website/packages/T4Scaffolding.1.0.6/tools/scaffoldingTabExpansion.psm1

114 lines
4.3 KiB
PowerShell

# Mostly copied from NuGet's native tab expansion function
# Maybe a future version of NuGet will have some kind of pluggable tab expansion system
# so that 3rd-party packages can provide expansions without duplicating all this logic
if (!$global:scaffolderTabExpansion) { $global:scaffolderTabExpansion = @{ } }
# make sure we stop on exceptions
$ErrorActionPreference = "Stop"
# This object reprents the result value for tab expansion functions when no result is returned.
# This is so that we can distinguish it from $null, which has different semantics
$NoResultValue = New-Object 'System.Object'
# Backup the original tab expansion function
if ((Test-Path Function:\TabExpansionPreT4Scaffolding) -eq $false) {
Rename-Item Function:\TabExpansion global:TabExpansionPreT4Scaffolding
}
function TabExpansion($line, $lastWord) {
$filter = $lastWord.Trim()
if ($filter.StartsWith('-')) {
# if this is a parameter, let default PS tab expansion supply the list of parameters
return (TabExpansionPreT4Scaffolding $line $lastWord)
}
# remove double quotes around last word
$trimmedFilter = $filter.Trim( '"', "'" )
if ($trimmedFilter.length -lt $filter.length) {
$filter = $trimmedFilter
$addQuote = $true
}
$e = $null
$tokens = @([System.Management.Automation.PSParser]::Tokenize($line, [ref]$e)) | %{ $_.Content }
if (-not($tokens -is [Array])) {
$tokens = ,$tokens
}
if (!$filter) {
$tokens = $tokens + $filter
}
switch ($tokens[0]) {
'Invoke-Scaffolder' {
$choices = TabExpansionForInvokeScaffolder $filter $tokens
}
'Scaffold' {
$choices = TabExpansionForInvokeScaffolder $filter $tokens
}
'Set-DefaultScaffolder' {
$choices = TabExpansionForSetDefaultScaffolder $filter $tokens
}
default {
$choices = $NoResultValue
}
}
if ($choices -eq $NoResultValue) {
# Fallback to the default tab expansion
TabExpansionPreT4Scaffolding $line $lastWord
}
elseif ($choices) {
# Return all the choices, do some filtering based on the last word, sort them and wrap each suggestion in a double quote if necessary
$choices |
Where-Object { $_.StartsWith($filter, "OrdinalIgnoreCase") } |
Sort-Object |
ForEach-Object { if ($addQuote -or $_.IndexOf(' ') -gt -1) { "'" + ($_ -replace "'", "''") + "'"} else { $_ } }
}
else {
# return null here will tell the console not to show system file paths
return $null
}
}
function TabExpansionForInvokeScaffolder([string]$filter, $allTokens) {
$secondLastToken = $allTokens[-2]
if (($secondLastToken -eq '-scaffolder') -or ($allTokens.length -eq 2) -or (($allTokens.length -eq 4) -and ($allTokens[-3] -eq '-project'))) {
$project = FindNamedParameterValue $allTokens Project
$filter += "*"
return @() + (Get-DefaultScaffolder -Project $project | %{ $_.DefaultName }) + (Get-Scaffolder $filter -Project $project | %{ $_.Name })
} elseif ($secondLastToken -eq '-project') {
return (Get-Project -All) | %{ $_.Name }
} else {
# We don't know how to complete custom scaffolder params here, so ask the scaffolder itself to do so
$scaffolder = Get-Scaffolder $tokens[1]
if ($scaffolder -is [T4Scaffolding.Core.ScaffolderLocators.ScaffolderInfo]) {
$registeredScriptBlock = $global:scaffolderTabExpansion[$scaffolder.Name]
if ($registeredScriptBlock -is [ScriptBlock]) {
return . $registeredScriptBlock $filter $tokens
}
}
return $NoResultValue
}
}
function TabExpansionForSetDefaultScaffolder([string]$filter, $allTokens) {
$secondLastToken = $allTokens[-2]
if (($secondLastToken -eq '-name') -or ($allTokens.length -eq 2)) {
return (Get-DefaultScaffolder | %{ $_.DefaultName })
} elseif (($secondLastToken -eq '-scaffolder') -or ($allTokens.length -eq 3)) {
$project = FindNamedParameterValue $allTokens Project
$filter += "*"
return (Get-Scaffolder $filter -Project $project | %{ $_.Name })
}
return $NoResultValue
}
function FindNamedParameterValue($allTokens, $parameterName) {
$foundAtPreviousToken = $false
foreach($token in $allTokens) {
if ($foundAtPreviousToken) { return $token }
if ($token -eq ("-" + $parameterName)) { $foundAtPreviousToken = $true }
}
}