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

fix: buffered escape sequence parsing to prevent stray A/B and restore arrow navigation

This commit is contained in:
Tw93
2025-10-02 19:30:54 +08:00
parent 9b50c35fe7
commit 68e34fcbe9

View File

@@ -89,50 +89,45 @@ show_cursor() {
# Keyboard input handling (simple and robust) # Keyboard input handling (simple and robust)
read_key() { read_key() {
local key # Robust parser that accumulates pending bytes to avoid leaking raw 'A'/'B'
IFS= read -r -s -n 1 key || return 1 local first rest
IFS= read -r -s -n 1 first || return 1
# Empty = ENTER (some terminals) # Enter (some terminals send empty before newline in -n1 mode)
if [[ -z "$key" ]]; then if [[ -z "$first" || "$first" == $'\n' || "$first" == $'\r' ]]; then
echo "ENTER"; return 0 echo "ENTER"; return 0
fi fi
case "$key" in case "$first" in
$'\n'|$'\r') echo "ENTER" ;; ' ') echo "SPACE"; return 0 ;;
' ') echo "SPACE" ;; 'q'|'Q') echo "QUIT"; return 0 ;;
'q'|'Q') echo "QUIT" ;; 'a'|'A') echo "ALL"; return 0 ;;
'a'|'A') echo "ALL" ;; 'n'|'N') echo "NONE"; return 0 ;;
'n'|'N') echo "NONE" ;; '?') echo "HELP"; return 0 ;;
'?') echo "HELP" ;; $'\x7f'|$'\b') echo "BACKSPACE"; return 0 ;;
$'\x7f'|$'\b') echo "BACKSPACE" ;; # Support Backspace
$'\x1b') $'\x1b')
# ESC sequence handling. Allow slightly longer window so we don't misinterpret slow terminals. # Collect rest of possible escape sequence quickly (non-blocking)
local next third local buf=""
if IFS= read -r -s -n 1 -t 0.15 next 2>/dev/null; then local count=0
if [[ "$next" == "[" ]]; then while IFS= read -r -s -n 1 -t 0.005 rest 2>/dev/null; do
if IFS= read -r -s -n 1 -t 0.15 third 2>/dev/null; then buf+="$rest"; ((count++))
case "$third" in # Stop if final byte of a simple CSI seq
'A') echo "UP" ;; [[ "$rest" =~ [A-Za-z~] ]] && break
'B') echo "DOWN" ;; [[ $count -ge 5 ]] && break
'C') echo "RIGHT" ;; done
'D') echo "LEFT" ;; case "$buf" in
*) echo "OTHER" ;; "[A") echo "UP" ;;
esac "[B") echo "DOWN" ;;
else "[C") echo "RIGHT" ;;
# ESC [ then timeout treat as OTHER to ignore "[D") echo "LEFT" ;;
echo "OTHER" "") echo "OTHER" ;; # Bare ESC -> ignore
fi *) echo "OTHER" ;;
else esac
# ESC + something (Alt modified key) → ignore as OTHER return 0
echo "OTHER"
fi
else
# Bare ESC alone: instead of quitting directly, emit OTHER so user doesn't exit accidentally
echo "OTHER"
fi
;; ;;
*) echo "OTHER" ;;
esac esac
echo "OTHER"
} }
# Drain any pending input bytes (used to swallow rapid trackpad scroll sequences) # Drain any pending input bytes (used to swallow rapid trackpad scroll sequences)
drain_pending_input() { drain_pending_input() {