Skip to content

Instantly share code, notes, and snippets.

@deanbot
Last active July 3, 2021 09:27
Show Gist options
  • Save deanbot/bf8fdda6713be84369e2179e8ea396e7 to your computer and use it in GitHub Desktop.
Save deanbot/bf8fdda6713be84369e2179e8ea396e7 to your computer and use it in GitHub Desktop.
(PowerShell) Read-InputLine
# Like Read-Line but can be exited from via a configured key press
#
# Returns the entered string or $false if CancelKeyCode (default is Esc) pressed
# Input truncated in display to fit one line
function Read-InputLine {
param (
[Parameter(Mandatory = $false, Position = 0)]
[string]$Prompt = "",
[Parameter(Mandatory = $false, Position = 1)]
[int]$CancelKeyCode = 27 # 27 = Escape
)
Try {
$Host.UI.RawUI.FlushInputBuffer()
}
Catch {
}
# display initial prompt
if ($Prompt.Length -gt 0) {
Write-Host "`r$Prompt" -NoNewLine
}
# accept and display input until enter or esc is pressed
$cancelled = $false
$inputLine = "";
$inputLineDisplay = ""
do {
# Test to see if escape was pressed within the loop
$key = $Host.UI.RawUI.ReadKey("IncludeKeyUp,NoEcho")
# exit if enter or esc pressed
# 13 = Enter
$exit = $key.VirtualKeyCode -eq 13 -or $key.VirtualKeyCode -eq $CancelKeyCode
# add char to input line
if (!$exit -and $key.Character) {
$inputLine += $key.Character
}
elseif ($key.VirtualKeyCode -eq $CancelKeyCode) {
$cancelled = $true
}
$maxWidth = $Host.Ui.RawUI.WindowSize.Width
# 8 = Backspace
if ($key.VirtualKeyCode -eq 8) {
# remove last character from input line
$newLength = $inputLine.Length - 2;
if ($newLength -lt 0) {
$newLength = 0
}
$inputLine = $inputLine.Substring(0, $newLength)
}
# update display line (truncate if console edge reached)
$startIndex = 0
$totalLength = $prompt.Length + $inputLine.Length
$inputLineDisplay = if ($totalLength -le $maxWidth - 1) {
$inputLine
}
else {
$startIndex = $totalLength - $maxWidth
$inputLine.SubString($startIndex, ($inputLine.Length - $startIndex))
}
# replace line with blank space
if ($totalLength -le $maxWidth - 1) {
$blank = ""
$lineLength = $prompt.length + $inputLine.Length
if ($lineLength -gt $maxWidth) {
$lineLength = $maxWidth
}
for ($l = 0; $l -le $lineLength; $l++) {
$blank = $blank + " "
}
Write-Host "`r$blank" -NoNewline
}
# replace line with new input line
if (!$exit) {
Write-Host "`r$prompt$inputLineDisplay" -NoNewline
}
} while (!$exit)
# replace line with blank space
$blank = ""
$lineLength = $prompt.length + $inputLine.Length
if ($lineLength -gt $maxWidth) {
$lineLength = $maxWidth
}
for ($l = 0; $l -le $lineLength; $l++) {
$blank = $blank + " "
}
Write-Host "`r$blank" -NoNewline
# empty input line if esc pressed
if ($cancelled) {
$inputLine = $false
}
# start console at beginning of line
Write-Host "`r" -NoNewline
$inputLine
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment