Commands/Get-Turtle.ps1
function Get-Turtle { <# .EXAMPLE turtle square 50 .EXAMPLE turtle circle 10 .EXAMPLE turtle polygon 10 6 .EXAMPLE turtle ('forward', 10, 'rotate', 120 * 3) #> [CmdletBinding(PositionalBinding=$false)] [Alias('turtle')] param( # The arguments to pass to turtle. [ArgumentCompleter({ param ( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters ) if (-not $script:TurtleTypeData) { $script:TurtleTypeData = Get-TypeData -TypeName Turtle } $methodNames = @(foreach ($memberName in $script:TurtleTypeData.Members.Keys) { if ($script:TurtleTypeData.Members[$memberName] -is [Management.Automation.Runspaces.ScriptMethodData]) { $memberName } }) if ($wordToComplete) { return $methodNames -like "$wordToComplete*" } else { return $methodNames } })] [Parameter(ValueFromRemainingArguments)] [PSObject[]] $ArgumentList, # Any input object to process. # If this is already a turtle object, the arguments will be applied to this object. # If the input object is not a turtle object, it will be ignored and a new turtle object will be created. [Parameter(ValueFromPipeline)] [PSObject] $InputObject ) begin { $turtleType = Get-TypeData -TypeName Turtle $memberNames = @(foreach ($memberName in $turtleType.Members.Keys) { if ( ($turtleType.Members[$memberName] -is [Management.Automation.Runspaces.ScriptMethodData]) -or ( $turtleType.Members[$memberName] -is [Management.Automation.Runspaces.AliasPropertyData] -and $turtleType.Members[ $turtleType.Members[$memberName].ReferencedMemberName ] -is [Management.Automation.Runspaces.ScriptMethodData] ) ) { $memberName } }) $memberNames = $memberNames | Sort-Object @{Expression={ $_.Length };Descending=$true}, Name $currentTurtle = [PSCustomObject]@{PSTypeName='Turtle'} } process { if ($PSBoundParameters.InputObject -and $PSBoundParameters.InputObject.pstypenames -eq 'Turtle') { $currentTurtle = $PSBoundParameters.InputObject } $currentMethod = $null $wordsAndArguments = foreach ($arg in $ArgumentList) { if ($arg -is [string]) { $arg -split '\s{1,}' } else { $arg } } :findCommand for ($argIndex =0; $argIndex -lt $wordsAndArguments.Length; $argIndex++) { $arg = $wordsAndArguments[$argIndex] if ($arg -in $memberNames) { $currentMethod = $arg for ( $methodArgIndex = $argIndex + 1; $methodArgIndex -lt $wordsAndArguments.Length -and $wordsAndArguments[$methodArgIndex] -notin $memberNames; $methodArgIndex++) { } # Command without parameters if ($methodArgIndex -eq $argIndex) { $argList = @() $currentTurtle = $currentTurtle.$currentMethod.Invoke() } else { $argList = $wordsAndArguments[($argIndex + 1)..($methodArgIndex - 1)] $currentTurtle = $currentTurtle.$currentMethod.Invoke($argList) # "$($currentMethod) $($argList -join ' ')" $argIndex = $methodArgIndex - 1 } } } return $currentTurtle } } |