mirror of
https://github.com/tw93/Mole.git
synced 2026-02-06 19:30:38 +00:00
feat(menu): add sort (date/name/size), live filter, reverse; visible-only A/N; responsive footer (#34)
Paginated menu: - Sorting: press S/s to cycle Date → Name → Size; press R/r to reverse. - Live filter: press F/f to enter; case-insensitive substring; prefix with ' to anchor at start; DELETE to backspace; ENTER to apply; ESC to cancel. Shows “searching…” while rebuilding. - Selection scope: A (All) and N (None) now work on the currently visible items only (after filter/sort), not the entire list. - Footer: adds A/N to the help line and wraps only at ' | ' separators so labels are never broken; adapts to terminal width. - Internals: view_indices mapping for filtered/sorted view; glob-safe matching via _pm_escape_glob; drain_pending_input; robust stty restore; optional MOLE_MANAGED_ALT_SCREEN; cleanup unsets MOLE_READ_KEY_FORCE_CHAR; shellcheck clean. common.sh: - read_key supports a raw typing mode (MOLE_READ_KEY_FORCE_CHAR=1) emitting CHAR:<k>; ENTER/DELETE/ESC handled. - Uppercase A/N/R mappings (ALL/NONE/RETRY), printable-key detection, better ESC sequence handling. app_selector.sh: - Builds and exports per-item metadata CSV for epochs and size_kb via MOLE_MENU_META_EPOCHS and MOLE_MENU_META_SIZEKB; unsets them after the menu. - Menu options keep display text; sorting/filtering use metadata. uninstall.sh: - Computes app_size_kb using du -sk for numeric sorting while keeping human-readable size; writes it as the final field. - load_applications reads the new size_kb field. Notes: - Footer grew due to new commands; responsive wrapping prevents mid-word breaks. - ./tests/run.sh: only the two upstream failures remain (unchanged by this patch). Co-authored-by: Jonas Bertossa <jonas.bertossa@eoc.ch>
This commit is contained in:
@@ -176,9 +176,29 @@ show_cursor() {
|
||||
# Keyboard input handling (simple and robust)
|
||||
read_key() {
|
||||
local key rest
|
||||
# Use macOS bash 3.2 compatible read syntax
|
||||
IFS= read -r -s -n 1 key || return 1
|
||||
|
||||
# Raw typing mode (filter): map most keys to CHAR:<key>
|
||||
if [[ "${MOLE_READ_KEY_FORCE_CHAR:-}" == "1" ]]; then
|
||||
# Some terminals return empty on Enter with -n1
|
||||
if [[ -z "$key" ]]; then
|
||||
echo "ENTER"
|
||||
return 0
|
||||
fi
|
||||
case "$key" in
|
||||
$'\n'|$'\r') echo "ENTER" ;;
|
||||
$'\x7f'|$'\x08') echo "DELETE" ;;
|
||||
$'\x1b') echo "QUIT" ;; # ESC cancels filter
|
||||
*)
|
||||
case "$key" in
|
||||
[[:print:]]) echo "CHAR:$key" ;;
|
||||
*) echo "OTHER" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Some terminals can yield empty on Enter with -n1; treat as ENTER
|
||||
if [[ -z "$key" ]]; then
|
||||
echo "ENTER"
|
||||
@@ -189,14 +209,13 @@ read_key() {
|
||||
$'\n' | $'\r') echo "ENTER" ;;
|
||||
' ') echo "SPACE" ;;
|
||||
'q' | 'Q') echo "QUIT" ;;
|
||||
'a' | 'A') echo "ALL" ;;
|
||||
'n' | 'N') echo "NONE" ;;
|
||||
'd' | 'D') echo "DELETE" ;;
|
||||
'r' | 'R') echo "RETRY" ;;
|
||||
'A') echo "ALL" ;;
|
||||
'N') echo "NONE" ;;
|
||||
'R') echo "RETRY" ;;
|
||||
'?') echo "HELP" ;;
|
||||
'o' | 'O') echo "OPEN" ;;
|
||||
$'\x03') echo "QUIT" ;; # Ctrl+C
|
||||
$'\x7f' | $'\x08') echo "DELETE" ;; # Delete key (labeled "delete" on Mac, actually backspace)
|
||||
$'\x7f' | $'\x08') echo "DELETE" ;; # Backspace/Delete key
|
||||
$'\x1b')
|
||||
# ESC sequence - could be arrow key, delete key, or ESC alone
|
||||
# Read the next two bytes within 1s
|
||||
@@ -241,7 +260,13 @@ read_key() {
|
||||
echo "QUIT"
|
||||
fi
|
||||
;;
|
||||
*) echo "OTHER" ;;
|
||||
*)
|
||||
# Printable ASCII -> expose as CHAR:<key> (for live filtering)
|
||||
case "$key" in
|
||||
[[:print:]]) echo "CHAR:$key" ;;
|
||||
*) echo "OTHER" ;;
|
||||
esac
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user