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

Keyboard optimization processing and log performance optimization

This commit is contained in:
Tw93
2025-11-15 13:18:57 +08:00
parent 53ebd90d91
commit 018afa396c
3 changed files with 41 additions and 71 deletions

View File

@@ -120,8 +120,12 @@ readonly LOG_MAX_SIZE_DEFAULT=1048576 # 1MB
# Ensure log directory exists # Ensure log directory exists
mkdir -p "$(dirname "$LOG_FILE")" 2> /dev/null || true mkdir -p "$(dirname "$LOG_FILE")" 2> /dev/null || true
# Log file maintenance (must be defined before logging functions) # Log rotation check (called once at startup, not per log entry)
rotate_log() { rotate_log_once() {
# Skip if already checked this session
[[ -n "${MOLE_LOG_ROTATED:-}" ]] && return 0
export MOLE_LOG_ROTATED=1
local max_size="${MOLE_MAX_LOG_SIZE:-$LOG_MAX_SIZE_DEFAULT}" local max_size="${MOLE_MAX_LOG_SIZE:-$LOG_MAX_SIZE_DEFAULT}"
if [[ -f "$LOG_FILE" ]] && [[ $(stat -f%z "$LOG_FILE" 2> /dev/null || echo 0) -gt "$max_size" ]]; then if [[ -f "$LOG_FILE" ]] && [[ $(stat -f%z "$LOG_FILE" 2> /dev/null || echo 0) -gt "$max_size" ]]; then
mv "$LOG_FILE" "${LOG_FILE}.old" 2> /dev/null || true mv "$LOG_FILE" "${LOG_FILE}.old" 2> /dev/null || true
@@ -129,37 +133,35 @@ rotate_log() {
fi fi
} }
# Enhanced logging functions with file logging support # Simplified logging functions (no per-call rotation check)
log_info() { log_info() {
rotate_log
echo -e "${BLUE}$1${NC}" echo -e "${BLUE}$1${NC}"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1" >> "$LOG_FILE" 2> /dev/null || true echo "[$(date '+%Y-%m-%d %H:%M:%S')] INFO: $1" >> "$LOG_FILE" 2> /dev/null || true
} }
log_success() { log_success() {
rotate_log
echo -e " ${GREEN}${ICON_SUCCESS}${NC} $1" echo -e " ${GREEN}${ICON_SUCCESS}${NC} $1"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS: $1" >> "$LOG_FILE" 2> /dev/null || true echo "[$(date '+%Y-%m-%d %H:%M:%S')] SUCCESS: $1" >> "$LOG_FILE" 2> /dev/null || true
} }
log_warning() { log_warning() {
rotate_log
echo -e "${YELLOW}$1${NC}" echo -e "${YELLOW}$1${NC}"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1" >> "$LOG_FILE" 2> /dev/null || true echo "[$(date '+%Y-%m-%d %H:%M:%S')] WARNING: $1" >> "$LOG_FILE" 2> /dev/null || true
} }
log_error() { log_error() {
rotate_log
echo -e "${RED}${ICON_ERROR}${NC} $1" >&2 echo -e "${RED}${ICON_ERROR}${NC} $1" >&2
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >> "$LOG_FILE" 2> /dev/null || true echo "[$(date '+%Y-%m-%d %H:%M:%S')] ERROR: $1" >> "$LOG_FILE" 2> /dev/null || true
} }
log_header() { log_header() {
rotate_log
echo -e "\n${PURPLE}${ICON_ARROW} $1${NC}" echo -e "\n${PURPLE}${ICON_ARROW} $1${NC}"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] SECTION: $1" >> "$LOG_FILE" 2> /dev/null || true echo "[$(date '+%Y-%m-%d %H:%M:%S')] SECTION: $1" >> "$LOG_FILE" 2> /dev/null || true
} }
# Call rotation check once when common.sh is sourced
rotate_log_once
# Icon output helpers # Icon output helpers
icon_confirm() { icon_confirm() {
echo -e "${BLUE}${ICON_CONFIRM}${NC} $1" echo -e "${BLUE}${ICON_CONFIRM}${NC} $1"
@@ -244,7 +246,7 @@ show_cursor() {
printf '\033[?25h' printf '\033[?25h'
} }
# Keyboard input handling (simple and robust) # Keyboard input handling (simplified)
read_key() { read_key() {
local key rest read_status local key rest read_status
@@ -260,7 +262,6 @@ read_key() {
# Raw typing mode (filter): map most keys to CHAR:<key> # Raw typing mode (filter): map most keys to CHAR:<key>
if [[ "${MOLE_READ_KEY_FORCE_CHAR:-}" == "1" ]]; then if [[ "${MOLE_READ_KEY_FORCE_CHAR:-}" == "1" ]]; then
# Some terminals return empty on Enter with -n1
if [[ -z "$key" ]]; then if [[ -z "$key" ]]; then
echo "ENTER" echo "ENTER"
return 0 return 0
@@ -269,17 +270,13 @@ read_key() {
$'\n' | $'\r') echo "ENTER" ;; $'\n' | $'\r') echo "ENTER" ;;
$'\x7f' | $'\x08') echo "DELETE" ;; $'\x7f' | $'\x08') echo "DELETE" ;;
$'\x1b') echo "QUIT" ;; # ESC cancels filter $'\x1b') echo "QUIT" ;; # ESC cancels filter
*)
case "$key" in
[[:print:]]) echo "CHAR:$key" ;; [[:print:]]) echo "CHAR:$key" ;;
*) echo "OTHER" ;; *) echo "OTHER" ;;
esac esac
;;
esac
return 0 return 0
fi fi
# Some terminals can yield empty on Enter with -n1; treat as ENTER # Empty key = Enter
if [[ -z "$key" ]]; then if [[ -z "$key" ]]; then
echo "ENTER" echo "ENTER"
return 0 return 0
@@ -292,15 +289,14 @@ read_key() {
'h' | 'H') echo "HELP" ;; 'h' | 'H') echo "HELP" ;;
'R') echo "RETRY" ;; 'R') echo "RETRY" ;;
'o' | 'O') echo "OPEN" ;; 'o' | 'O') echo "OPEN" ;;
'/') echo "FILTER" ;; # Trigger filter mode '/') echo "FILTER" ;;
$'\x03') echo "QUIT" ;; # Ctrl+C $'\x03') echo "QUIT" ;; # Ctrl+C
$'\x7f' | $'\x08') echo "DELETE" ;; # Backspace/Delete key $'\x7f' | $'\x08') echo "DELETE" ;;
$'\x1b') $'\x1b')
# ESC sequence - could be arrow key, delete key, or ESC alone # ESC sequence - could be arrow key, delete key, or ESC alone
# Read the next bytes with 1s timeout for maximum compatibility
if IFS= read -r -s -n 1 -t 1 rest 2> /dev/null; then if IFS= read -r -s -n 1 -t 1 rest 2> /dev/null; then
if [[ "$rest" == "[" ]]; then if [[ "$rest" == "[" ]]; then
# Got ESC [, read next character # ESC [ sequence
if IFS= read -r -s -n 1 -t 1 rest2 2> /dev/null; then if IFS= read -r -s -n 1 -t 1 rest2 2> /dev/null; then
case "$rest2" in case "$rest2" in
"A") echo "UP" ;; "A") echo "UP" ;;
@@ -308,74 +304,48 @@ read_key() {
"C") echo "RIGHT" ;; "C") echo "RIGHT" ;;
"D") echo "LEFT" ;; "D") echo "LEFT" ;;
"3") "3")
# Delete key (Fn+Delete): ESC [ 3 ~ # Delete key: ESC [ 3 ~
IFS= read -r -s -n 1 -t 1 rest3 2> /dev/null IFS= read -r -s -n 1 -t 1 rest3 2> /dev/null
if [[ "$rest3" == "~" ]]; then [[ "$rest3" == "~" ]] && echo "DELETE" || echo "OTHER"
echo "DELETE" ;;
*) echo "OTHER" ;;
esac
else
echo "QUIT"
fi
elif [[ "$rest" == "O" ]]; then
# ESC O sequence (application keypad mode)
if IFS= read -r -s -n 1 -t 1 rest2 2> /dev/null; then
case "$rest2" in
"A") echo "UP" ;;
"B") echo "DOWN" ;;
"C") echo "RIGHT" ;;
"D") echo "LEFT" ;;
*) echo "OTHER" ;;
esac
else else
echo "OTHER" echo "OTHER"
fi fi
;;
"5")
# Page Up key: ESC [ 5 ~
IFS= read -r -s -n 1 -t 1 rest3 2> /dev/null
[[ "$rest3" == "~" ]] && echo "OTHER" || echo "OTHER"
;;
"6")
# Page Down key: ESC [ 6 ~
IFS= read -r -s -n 1 -t 1 rest3 2> /dev/null
[[ "$rest3" == "~" ]] && echo "OTHER" || echo "OTHER"
;;
*) echo "OTHER" ;;
esac
else else
echo "QUIT" # ESC [ timeout echo "OTHER"
fi
elif [[ "$rest" == "O" ]]; then
# Application keypad mode sequences (mouse wheel often generates these)
if IFS= read -r -s -n 1 -t 1 rest2 2> /dev/null; then
case "$rest2" in
"A") echo "UP" ;; # ESC O A
"B") echo "DOWN" ;; # ESC O B
"C") echo "RIGHT" ;; # ESC O C
"D") echo "LEFT" ;; # ESC O D
*) echo "OTHER" ;; # Ignore other ESC O sequences
esac
else
echo "OTHER" # ESC O timeout
fi fi
else else
echo "OTHER" # ESC + something else (not [ or O) # ESC alone
fi
else
# ESC pressed alone - treat as quit
echo "QUIT" echo "QUIT"
fi fi
;; ;;
*)
# Printable ASCII -> expose as CHAR:<key> (for live filtering)
case "$key" in
[[:print:]]) echo "CHAR:$key" ;; [[:print:]]) echo "CHAR:$key" ;;
*) echo "OTHER" ;; *) echo "OTHER" ;;
esac esac
;;
esac
} }
# Drain pending input (useful for scrolling prevention) # Drain pending input (simplified single-pass)
drain_pending_input() { drain_pending_input() {
local drained=0 local drained=0
# Multiple passes with very short timeout to catch mouse wheel bursts # Single pass with 0.01s timeout is sufficient for mouse wheel events
# Mouse wheel scrolling can generate rapid sequences like B^[OB^[OB^[O...
while IFS= read -r -s -n 1 -t 0.01 _ 2> /dev/null; do while IFS= read -r -s -n 1 -t 0.01 _ 2> /dev/null; do
((drained++)) ((drained++))
# Safety limit for mouse wheel sequences [[ $drained -gt 100 ]] && break
[[ $drained -gt 200 ]] && break
done
# Second pass with even shorter timeout to catch any remaining input
while IFS= read -r -s -n 1 -t 0.001 _ 2> /dev/null; do
((drained++))
[[ $drained -gt 500 ]] && break
done done
} }