Skip to content

Instantly share code, notes, and snippets.

@dpo007
Created September 14, 2020 21:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dpo007/216e61cfd8b375116645da1d11ddfdd5 to your computer and use it in GitHub Desktop.
Save dpo007/216e61cfd8b375116645da1d11ddfdd5 to your computer and use it in GitHub Desktop.
PowerShell :: Console input with search list by typed letters, tab cycling, etc.
function GetPickListChoice {
param (
[Parameter(Mandatory=$true)]
[string[]]$PickList,
[string]$Prompt = 'Type to search, Tab to cycle matches, Backspace to reset, ''?'' for a list: ',
[switch]$PromptNoNewLine
)
function ClearCurrentChoice {
for ($i = $origCursorPos.X; $i -lt $endPos; $i++) {
$currentCursorPos.X = $i
$Host.UI.RawUI.CursorPosition = $currentCursorPos
Write-Host ' ' -NoNewLine
$Host.UI.RawUI.CursorPosition = $origCursorPos
}
}
# Alphabetize pick list.
$PickList = $PickList | Sort-Object
# Init result.
$result = ''
$searchTerm = ''
# Display prompt.
Write-Host $Prompt -NoNewLine:$PromptNoNewLine
# Get current cursor position as a starting point.
$origCursorPos = New-Object System.Management.Automation.Host.Coordinates
$origCursorPos.X = $Host.UI.RawUI.CursorPosition.X
$origCursorPos.Y = $Host.UI.RawUI.CursorPosition.Y
do {
# Get current cursor position
$currentCursorPos = New-Object System.Management.Automation.Host.Coordinates
$currentCursorPos.X = $Host.UI.RawUI.CursorPosition.X
$currentCursorPos.Y = $Host.UI.RawUI.CursorPosition.Y
$endPos = $currentCursorPos.X
# Process one key at a time. Don't echo the character back.
$key = $Host.UI.RawUI.ReadKey('NoEcho, IncludeKeyDown')
switch ($key.VirtualKeyCode) {
191 {
$searchTerm = ''
Write-Host
Write-Host
Write-Host ' Available Choices'
Write-Host '.=================.'
Write-Host
$PickList | ForEach-Object { Write-Host "- $_" }
Write-Host
Write-Host $Prompt -NoNewLine:$PromptNoNewLine
break
} # '?' (191)
13 {
break
} # Enter (13)
9 {
ClearCurrentChoice
[string[]]$matches = $PickList | Where-Object { $_.StartsWith($searchTerm, "CurrentCultureIgnoreCase") }
if ($matches) {
$Host.UI.RawUI.CursorPosition = $origCursorPos
$lastMatch++
if ($lastMatch -gt ($matches.Count-1)) {
$lastMatch = 0
}
$result = $matches[$lastMatch].Trim()
Write-Host $result -NoNewline
}
break
} # Tab (9)
8 {
ClearCurrentChoice
$searchTerm = ''
$result = ''
break
} # Backspace (8)
default {
$lastChar = $key.Character
if ($key.VirtualKeyCode -ne 8) {
$searchTerm += $lastChar
}
[string[]]$matches = $PickList | Where-Object { $_.StartsWith($searchTerm, "CurrentCultureIgnoreCase") }
if ($matches) {
ClearCurrentChoice
$lastMatch = 0
$result = $matches[$lastMatch].Trim()
Write-Host $result -NoNewline
} else {
if ($searchTerm.Length -gt 1) {
$searchTerm = $searchTerm.Substring(0,$searchTerm.Length-1)
} else {
$searchTerm = ''
$result = ''
}
}
} # default
}
} until (($key.VirtualKeyCode -eq 13) -and $result)
Write-Host
return $result
}
# Example
$choices = @('Fart', 'Farted', 'Frat', 'Fred', 'John', 'Car', 'Jack', 'Zed', 'Cow', 'Container99')
Write-Host ('Choice: {0}' -f $(GetPickListChoice -PickList $choices -PromptNoNewLine))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment