1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-15 05:15:10 +00:00

fix(windows): support arrow key escape sequences in interactive menus

Some terminals send escape sequences (ESC [ A/B) instead of VirtualKeyCode
for arrow keys. Now handles both methods for better terminal compatibility.
This commit is contained in:
Bhadra
2026-01-08 22:49:43 +05:30
parent 800db2429d
commit 9b40c5acf4

View File

@@ -180,9 +180,35 @@ function Show-Menu {
Write-Host "" Write-Host ""
Write-Host " ${gray}Use arrows or j/k to navigate, Enter to select, q to quit${nc}" Write-Host " ${gray}Use arrows or j/k to navigate, Enter to select, q to quit${nc}"
# Read key # Read key - handle both VirtualKeyCode and escape sequences
$key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
# Debug: uncomment to see key codes
# Write-Host "VKey: $($key.VirtualKeyCode), Char: $([int]$key.Character)"
# Handle escape sequences for arrow keys (some terminals send these)
$moved = $false
if ($key.VirtualKeyCode -eq 0 -or $key.Character -eq [char]27) {
# Escape sequence - read the next characters
if ($Host.UI.RawUI.KeyAvailable) {
$key2 = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
if ($key2.Character -eq '[' -and $Host.UI.RawUI.KeyAvailable) {
$key3 = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
switch ($key3.Character) {
'A' { # Up arrow escape sequence
$selected = if ($selected -gt 0) { $selected - 1 } else { $maxIndex }
$moved = $true
}
'B' { # Down arrow escape sequence
$selected = if ($selected -lt $maxIndex) { $selected + 1 } else { 0 }
$moved = $true
}
}
}
}
}
if (-not $moved) {
switch ($key.VirtualKeyCode) { switch ($key.VirtualKeyCode) {
38 { # Up arrow 38 { # Up arrow
$selected = if ($selected -gt 0) { $selected - 1 } else { $maxIndex } $selected = if ($selected -gt 0) { $selected - 1 } else { $maxIndex }
@@ -212,6 +238,7 @@ function Show-Menu {
} }
} }
} }
}
finally { finally {
# Ensure cursor is shown # Ensure cursor is shown
Write-Host -NoNewline "$([char]27)[?25h" Write-Host -NoNewline "$([char]27)[?25h"
@@ -274,6 +301,29 @@ function Show-SelectionList {
$key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") $key = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
# Handle escape sequences for arrow keys (some terminals send these)
$moved = $false
if ($key.VirtualKeyCode -eq 0 -or $key.Character -eq [char]27) {
# Escape sequence - read the next characters
if ($Host.UI.RawUI.KeyAvailable) {
$key2 = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
if ($key2.Character -eq '[' -and $Host.UI.RawUI.KeyAvailable) {
$key3 = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
switch ($key3.Character) {
'A' { # Up arrow escape sequence
$cursor = if ($cursor -gt 0) { $cursor - 1 } else { $maxIndex }
$moved = $true
}
'B' { # Down arrow escape sequence
$cursor = if ($cursor -lt $maxIndex) { $cursor + 1 } else { 0 }
$moved = $true
}
}
}
}
}
if (-not $moved) {
switch ($key.VirtualKeyCode) { switch ($key.VirtualKeyCode) {
38 { $cursor = if ($cursor -gt 0) { $cursor - 1 } else { $maxIndex } } 38 { $cursor = if ($cursor -gt 0) { $cursor - 1 } else { $maxIndex } }
40 { $cursor = if ($cursor -lt $maxIndex) { $cursor + 1 } else { 0 } } 40 { $cursor = if ($cursor -lt $maxIndex) { $cursor + 1 } else { 0 } }
@@ -288,9 +338,9 @@ function Show-SelectionList {
13 { # Enter 13 { # Enter
Write-Host -NoNewline "$([char]27)[?25h" Write-Host -NoNewline "$([char]27)[?25h"
$result = @() $result = @()
foreach ($key in $selected.Keys) { foreach ($selKey in $selected.Keys) {
if ($selected[$key]) { if ($selected[$selKey]) {
$result += $Items[$key] $result += $Items[$selKey]
} }
} }
return $result return $result
@@ -316,6 +366,7 @@ function Show-SelectionList {
} }
} }
} }
}
finally { finally {
Write-Host -NoNewline "$([char]27)[?25h" Write-Host -NoNewline "$([char]27)[?25h"
} }