Last active
October 27, 2016 16:01
-
-
Save mhudasch/5ff826f2e3c0b02c101a296b4e3671dc to your computer and use it in GitHub Desktop.
Test of Input mask for PS
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#requires -version 5 | |
Set-StrictMode -Version Latest | |
Function Read-Input { | |
[Diagnostics.CodeAnalysis.SuppressMessage("PSAvoidUsingWriteHost", "", Justification = "This is an interface cmdlet that should be seen in its host.")] | |
[CmdletBinding()] | |
param( | |
[Parameter(Mandatory=$true, Position=1)] | |
[string]$Message, | |
[Parameter(Mandatory=$false, Position=2)] | |
[ValidateSet("List", "RawList"<#, "Expand"#>, "Checkbox", "RawCheckbox", "Confirm", "Input", "RawInput", "Password"<#, "Editor"#>)] | |
[string]$Type = "Input", | |
[Parameter(Mandatory=$false, Position=3)] | |
[string]$Name = "Answer", | |
[Parameter(Mandatory=$false, Position=4)] | |
[string[]]$Default, | |
[Parameter(Mandatory=$false, Position=5)] | |
[string[]]$Choices = @()) | |
Begin { | |
Function Write-Question { | |
param([string]$q) | |
(Write-Host "? " -ForegroundColor Green -NoNewline); (Write-Host $q -NoNewline); | |
} | |
} | |
Process { | |
$CursorChar = [char]0x25B8; | |
$HighlightColor = "Cyan"; | |
$DefaultValueColor = "Yellow"; | |
$cx = $Host.UI.RawUI.CursorPosition.X; | |
$cy = $Host.UI.RawUI.CursorPosition.Y; | |
$mode = @("PS","ISE")[$null -ne (Get-Variable -Name "psISE" -ErrorAction Ignore)] | |
$arrowLeft = 37; $arrowUp = 38; $arrowRight = 39; $arrowDown = 40; $enter = 13; $spaceBar = 32; $backspace = 8; $delete = 46; $cursorPos = 0; | |
$sp = " "; | |
if($mode -eq "PS") { | |
Start-Sleep -Milliseconds 500; | |
$Host.UI.RawUI.FlushInputBuffer(); | |
} | |
$result = @{}; | |
# route the input to the raw versions when in ise host | |
switch ($Type) { | |
"List" { if($mode -eq "ISE") { $Type = "RawList"; } } | |
"Checkbox" { if($mode -eq "ISE") { $Type = "RawCheckbox"; } } | |
"Input" { if($mode -eq "ISE") { $Type = "RawInput"; } } | |
} | |
#region input | |
if($Type -eq "Input") { | |
if($Default -and $Default.Count -gt 0) { | |
$content = [string]$Default[0].Clone(); | |
} else { | |
$content = ""; | |
} | |
#draw | |
Write-Question $Message; Write-Host ": " -NoNewline; | |
$mx = $Host.UI.RawUI.CursorPosition.X; | |
if($content) { Write-Host $content -NoNewline; $nx = ($mx + $content.Length); } else { $nx = $mx; } | |
$vx = $mx; | |
#input loop | |
while($true){ | |
$cursel = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown"); | |
if($cursel.VirtualKeyCode -eq $arrowLeft) { | |
if($content -eq "") { | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
} else { | |
if($nx -gt $mx){ | |
$nx--; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $nx, $cy; | |
} | |
} | |
} elseif($cursel.VirtualKeyCode -eq $arrowRight) { | |
if($content -eq "") { | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
} else { | |
if($nx -lt ($mx + $content.Length)){ | |
$nx++; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $nx, $cy; | |
} | |
} | |
} elseif($cursel.VirtualKeyCode -eq $backspace) { | |
if($content -eq ""){ | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
} else { | |
if($nx -eq $mx) { | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
} elseif($nx -lt ($mx + $content.Length)) { | |
$vx = ($content.Length - 1) - ((($mx + $content.Length) - $nx)); | |
$content = $content.Remove($vx, 1); | |
$nx--; | |
} elseif($nx -eq ($mx + $content.Length)) { | |
if($nx -ge ($mx - $content.Length)) { | |
$nx--; | |
$content = $content.Substring(0, $content.Length - 1); | |
} | |
} | |
#clear | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
Write-Host ("".PadLeft($Host.UI.RawUI.BufferSize.Width - $mx, " ")) -NoNewline; | |
#draw | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
Write-Host $content -NoNewline; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $nx, $cy; | |
} | |
} elseif($cursel.VirtualKeyCode -eq $delete) { | |
if($content -eq ""){ | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
} else { | |
if($nx -ge ($mx + $content.Length)) { | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
} elseif($nx -lt ($mx + $content.Length)) { | |
$vx = $content.Length - ((($mx + $content.Length) - $nx)); | |
$content = $content.Remove($vx, 1); | |
} elseif($nx -eq $mx -and $content.Length -gt 0) { | |
if($nx -gt ($mx - $content.Length)) { | |
$content = $content.Substring(0, $content.Length - 1); | |
} | |
} | |
#clear | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
Write-Host ("".PadLeft($Host.UI.RawUI.BufferSize.Width - $mx, " ")) -NoNewline; | |
#draw | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
Write-Host $content -NoNewline; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $nx, $cy; | |
} | |
} elseif($cursel.VirtualKeyCode -eq $enter) { | |
break; | |
} elseif([char]::IsLetterOrDigit($cursel.Character) -or | |
[char]::IsPunctuation($cursel.Character) -or | |
[char]::IsWhiteSpace($cursel.Character)) { | |
$c = $cursel.Character; | |
if($nx -lt ($mx + $content.Length)) { | |
$vx = $content.Length - ((($mx + $content.Length) - $nx)); | |
$content = $content.Insert($vx, $c); | |
$nx++; | |
} else { | |
$content += $c; | |
$nx++; | |
} | |
#clear | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
Write-Host ("".PadLeft($Host.UI.RawUI.BufferSize.Width - $mx, " ")) -NoNewline; | |
#draw | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
Write-Host $content -NoNewline; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $nx, $cy; | |
} | |
} | |
#validate in | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $cx, $cy; | |
Write-Question $Message; Write-Host ": " -NoNewline; Write-Host $content -ForegroundColor $HighlightColor; | |
$result.Add($Name, $content); | |
return $result; | |
} | |
#endregion | |
#region confirm | |
if($Type -eq "Confirm") { | |
if($Default -and $Default.Count -gt 0) { | |
$def = [string]$Default[0].Clone(); | |
if($def -match "1|[yY](es)?") { $def = "Yes"; } | |
elseif($def -match "0|[nN]o?") { $def = "No"; } | |
$content = $def; | |
} else { | |
$content = ""; | |
} | |
#draw | |
Write-Question $Message; Write-Host ": " -NoNewline; | |
Write-Host "(" -NoNewline; Write-Host "Yes" -ForegroundColor @("White", $DefaultValueColor)[$content -eq "Yes"] -NoNewline; | |
Write-Host "/" -NoNewline; Write-Host "No" -ForegroundColor @("White", $DefaultValueColor)[$content -eq "No"] -NoNewline; Write-Host ") " -NoNewline; | |
$mx = $Host.UI.RawUI.CursorPosition.X; | |
while($true){ | |
$cursel = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown"); | |
if($cursel.Character -match "[1yY]+") { | |
$content = "Yes"; | |
break; | |
} elseif($cursel.Character -match "[0nN]+") { | |
$content = "No"; | |
break; | |
} elseif($cursel.VirtualKeyCode -eq $enter -and ($content -ne "")) { | |
break; | |
} | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
Write-Host ("".PadLeft($Host.UI.RawUI.BufferSize.Width - $mx, " ")) -NoNewline; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
} | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $cx, $cy; | |
Write-Question $Message; Write-Host ": " -NoNewline; | |
Write-Host "(" -NoNewline; Write-Host "Yes" -ForegroundColor @("White", "Yellow")[$def -eq "Yes"] -NoNewline; | |
Write-Host "/" -NoNewline; Write-Host "No" -ForegroundColor @("White", "Yellow")[$def -eq "No"] -NoNewline; Write-Host ") " -NoNewline; | |
Write-Host $content -ForegroundColor $HighlightColor; | |
$result.Add($Name, $content); | |
return $result; | |
} | |
#endregion | |
#region list | |
if($Type -eq "List") { | |
if($Default -and $Default.Count -gt 0) { | |
$content = [string]$Default[0].Clone(); | |
} else { | |
$content = $Choices[0]; | |
} | |
if("" -eq $content){ $cursorPos = 0; } | |
else { | |
$c = $Choices.IndexOf($content); | |
if($c -eq -1){ $cursorPos = 0; }else{ $cursorPos = $c; } | |
} | |
$chcc = ($Choices.Count - 1); | |
#input loop | |
while($true){ | |
Write-Question $Message; Write-Host ": " -NoNewline; | |
$mx = $Host.UI.RawUI.CursorPosition.X; | |
Write-Host ("".PadLeft($Host.UI.RawUI.BufferSize.Width - $mx, " ")) -NoNewline; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
if($content) { Write-Host $content; $nx = ($mx + $content.Length); } else { Write-Host ""; $nx = $mx; } | |
$vx = $mx; | |
$Choices | ForEach-Object {$ax=0}{ | |
if($ax -eq $cursorPos) { | |
Write-Host $CursorChar -NoNewline -ForegroundColor $HighlightColor | |
} else { Write-Host " " -NoNewline } | |
Write-Host ($sp + $sp + $_) -NoNewline:($ax -gt $Message.Length) -ForegroundColor @("White", $HighlightColor)[$ax -eq $cursorPos]; | |
$ax++; | |
}; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates ($mx + $content.Length), $cy; | |
$cursel = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown"); | |
if($cursel.VirtualKeyCode -eq $arrowUp) { | |
if(($cursorPos-1) -lt 0){ $cursorPos = $chcc; } else { $cursorPos--; } | |
} elseif($cursel.VirtualKeyCode -eq $arrowDown) { | |
if(($cursorPos+1) -gt $chcc){ $cursorPos = 0; } else { $cursorPos++; } | |
} elseif($cursel.VirtualKeyCode -eq $enter) { | |
break; | |
} | |
$content = $Choices[$cursorPos]; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $cx, $cy; | |
} | |
$cleanRange = $Choices.Count+1; | |
for($i=0;$i -lt $cleanRange; $i++){ Write-Host ("".PadRight($Host.UI.RawUI.BufferSize.Width, " ")) }; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $cx, $cy; | |
Write-Question $Message; Write-Host ": " -NoNewline; | |
Write-Host $content -ForegroundColor $HighlightColor -NoNewline; | |
Write-Host ""; | |
$result.Add($Name, $content); | |
return $result; | |
} | |
#endregion | |
#region raw list | |
if($Type -eq "RawList") { | |
if($Default -and $Default.Count -gt 0) { | |
$content = [string]$Default[0].Clone(); | |
} else { | |
$content = $null; | |
} | |
if($null -eq $content){ $cursorPos = $null; } | |
else { | |
$c = $Choices.IndexOf($content); | |
if($c -eq -1){ $cursorPos = $null; }else{ $cursorPos = $c; } | |
} | |
$chcc = ($Choices.Count - 1); | |
$chccDigits = $chcc.ToString().Length + 2; | |
#input loop | |
while($true) { | |
Write-Question $Message; Write-Host ": "; | |
$Choices | ForEach-Object {$ax=0}{ | |
if($ax -eq $cursorPos) { | |
Write-Host (($ax+1).ToString().PadLeft($chccDigits, " ") + ")") -NoNewline -ForegroundColor $DefaultValueColor | |
} else { Write-Host (($ax+1).ToString().PadLeft($chccDigits, " ") + ")") -NoNewline } | |
Write-Host ($sp + $sp + $_) -NoNewline:($ax -gt $Message.Length) -ForegroundColor @("White", $DefaultValueColor)[$ax -eq $cursorPos]; | |
$ax++; | |
}; | |
Write-Host "" | |
Write-Host ($sp + $sp + "Answer: ") -NoNewline; | |
$in = Read-Host | |
if($in -match "^\d+$"){ | |
$idx = [Convert]::ToUInt64($in); | |
if($idx -gt 0 -and $idx -le $Choices.Count) { | |
$content = $Choices[$idx - 1]; | |
break; | |
} | |
} elseif($null -ne $content -and [string]::IsNullOrEmpty($in)) { | |
break; | |
} | |
} | |
$result.Add($Name, $content); | |
return $result; | |
} | |
#endregion | |
#region password | |
if($Type -eq "Password") { | |
$result = @{}; | |
Write-Question -q $Message; Write-Host ": " -NoNewline; | |
$password = [securestring](Read-Host -AsSecureString); | |
$result.Add($Name, $password); | |
return $result; | |
} | |
#endregion | |
#region raw input | |
if($Type -eq "RawInput") { | |
$result = @{}; | |
if($Default -and $Default.Count -gt 0) { | |
$content = [string]$Default[0].Clone(); | |
} else { | |
$content = $null; | |
} | |
while($true) { | |
Write-Question -q $Message; | |
if($content) { | |
Write-Host " (Default: " -NoNewline; | |
Write-Host $content -ForegroundColor $DefaultValueColor -NoNewline; | |
Write-Host ")" -NoNewline; | |
} | |
Write-Host ": "; | |
Write-Host ($sp + $sp + "Answer: ") -NoNewline; | |
$in = [string](Read-Host); | |
if(($null -ne $content -and [string]::IsNullOrEmpty($in))) { | |
break; | |
} elseif(-not([string]::IsNullOrEmpty($in))) { | |
$content = $in; | |
break; | |
} | |
} | |
$result.Add($Name, $content); | |
return $result; | |
} | |
#endregion | |
#region checkbox | |
if($Type -eq "Checkbox") { | |
$selectedChar = [char]0x25CF; | |
$unselectedChar = [char]0x25CB; | |
if($Default -and $Default.Count -gt 0) { | |
$content = New-Object System.Collections.ArrayList -ArgumentList @(,$Default); | |
} else { | |
$content = New-Object System.Collections.ArrayList; | |
} | |
$cursorPos = 0; | |
$chcc = ($Choices.Count - 1); | |
#input loop | |
while($true){ | |
Write-Question $Message; Write-Host ": " -NoNewline; | |
$mx = $Host.UI.RawUI.CursorPosition.X; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
Write-Host ""; | |
$Choices | ForEach-Object {$ax=0}{ | |
if($ax -eq $cursorPos) { | |
Write-Host $CursorChar -NoNewline -ForegroundColor $HighlightColor | |
} else { Write-Host " " -NoNewline } | |
Write-Host ($sp + @($unselectedChar, $selectedChar)[$content.Contains($_)] + $sp + $_) -NoNewline:($ax -gt $Message.Length) -ForegroundColor @("White", $HighlightColor)[$ax -eq $cursorPos]; | |
$ax++; | |
}; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $mx, $cy; | |
$cursel = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown"); | |
if($cursel.VirtualKeyCode -eq $arrowUp) { | |
if(($cursorPos-1) -lt 0){ $cursorPos = $chcc; } else { $cursorPos--; } | |
} elseif($cursel.VirtualKeyCode -eq $arrowDown) { | |
if(($cursorPos+1) -gt $chcc){ $cursorPos = 0; } else { $cursorPos++; } | |
} elseif($cursel.VirtualKeyCode -eq $spaceBar) { | |
$s = $Choices[$cursorPos]; | |
#toggle selection | |
if($content.Contains($s)) { $content.Remove($s) | Out-Null; } | |
else { $content.Add($s) | Out-Null; } | |
} elseif($cursel.VirtualKeyCode -eq $enter) { | |
break; | |
} | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $cx, $cy; | |
} | |
$cleanRange = $Choices.Count+1; | |
for($i=0;$i -lt $cleanRange; $i++){ Write-Host ("".PadRight($Host.UI.RawUI.BufferSize.Width, " ")) }; | |
$Host.UI.RawUI.CursorPosition = New-Object System.Management.Automation.Host.Coordinates $cx, $cy; | |
Write-Question $Message; Write-Host ": " -NoNewline; | |
Write-Host $content -ForegroundColor $HighlightColor -NoNewline; | |
Write-Host ""; | |
$result.Add($Name, $content); | |
return $result; | |
} | |
#endregion | |
#region raw checkbox | |
if($Type -eq "RawCheckbox") { | |
if($Default -and $Default.Count -gt 0) { | |
$content = New-Object System.Collections.ArrayList -ArgumentList @(,$Default); | |
} else { | |
$content = New-Object System.Collections.ArrayList; | |
} | |
$chcc = ($Choices.Count - 1); | |
$chccDigits = $chcc.ToString().Length + 2; | |
#input loop | |
while($true) { | |
Write-Question $Message; Write-Host ": "; | |
$Choices | ForEach-Object {$ax=0}{ | |
Write-Host (($ax+1).ToString().PadLeft($chccDigits, " ") + ")") -NoNewline -ForegroundColor @("White", $DefaultValueColor)[ ($content -contains $Choices[$ax]) ]; | |
Write-Host ($sp + $sp + $_) -NoNewline:($ax -gt $Message.Length) -ForegroundColor @("White", $DefaultValueColor)[ ($content -contains $Choices[$ax]) ]; | |
$ax++; | |
}; | |
Write-Host "" | |
Write-Host ($sp + $sp + "Answer: ") -NoNewline; | |
$in = Read-Host | |
if($in -match "^\d+(?:,\d+)*$"){ | |
$idxs = @($in -split "," | ForEach-Object { [Convert]::ToUInt64($_.Trim()); } | Select-Object -Unique); | |
$inputNumberCount = $idxs.Length; | |
$chosen = @($idxs | ForEach-Object { $idx = $_; if($idx -gt 0 -and $idx -le $Choices.Count) { $idx | Write-Output; } else { $null | Write-Output; } } | Where-Object { $null -ne $_; }); | |
if($chosen.Length -eq $inputNumberCount) { | |
$content = ($chosen | Sort-Object | ForEach-Object { $Choices[$_ - 1]; }); | |
break; | |
} | |
} elseif($null -ne $content -and [string]::IsNullOrEmpty($in)) { | |
break; | |
} | |
} | |
$result.Add($Name, $content); | |
return $result; | |
} | |
#endregion | |
} | |
} | |
#Read-Input -Message "What's your name?" | |
#Read-Input -Message "What's your name?" -Default "Martin" | |
#Read-Input -Message "Wanna do this?" -Type Confirm -Default "Y" | |
#Read-Input -Message "What's your name?" -Type List -Choices "Martin","Lars","Benjamin" -Default "Lars" | |
#Read-Input -Message "Enter your git password" -Type Password; | |
#Read-Input -Message "What's your name?" -Type RawList -Choices "Martin","Lars","Benjamin" -Default "Lars" | |
Read-Input -Message "What's your name?" -Type Checkbox -Choices "Martin","Lars","Benjamin" -Default "Lars","Benjamin" | |
#Read-Input -Message "What's your name?" -Type RawInput -Default "Martin" | |
#$a = Read-Input -Question "What you want to do?" -Choices @("Angular", "Gulp", "Polymer") -DefaultChoice "Polymer" | |
# $b = Read-Choice -Question "What you want to do?" -Choices @("Angular", "Gulp", "Polymer") -HelpText "Something here" | |
#$b = Read-Input -Question "What you want to do?" -Choices @("Angular", "Gulp", "Polymer") -HelpText "Something here" -MultiSelect -DefaultChoice @("Gulp", "Angular") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment