1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-04 21:29:42 +00:00
Files
Mole/lib/app_selector.sh
Else00 cfdd414320 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>
2025-10-14 09:40:47 +08:00

104 lines
3.3 KiB
Bash
Executable File

#!/bin/bash
# App selection functionality
set -euo pipefail
# Format app info for display
format_app_display() {
local display_name="$1" size="$2" last_used="$3"
# Truncate long names
local truncated_name="$display_name"
if [[ ${#display_name} -gt 24 ]]; then
truncated_name="${display_name:0:21}..."
fi
# Format size
local size_str="Unknown"
[[ "$size" != "0" && "$size" != "" && "$size" != "Unknown" ]] && size_str="$size"
printf "%-24s (%s) | %s" "$truncated_name" "$size_str" "$last_used"
}
# Global variable to store selection result (bash 3.2 compatible)
MOLE_SELECTION_RESULT=""
# Main app selection function
# shellcheck disable=SC2154 # apps_data is set by caller
select_apps_for_uninstall() {
if [[ ${#apps_data[@]} -eq 0 ]]; then
log_warning "No applications available for uninstallation"
return 1
fi
# Build menu options
local -a menu_options=()
# Prepare metadata (comma-separated) for sorting/filtering inside the menu
local epochs_csv=""
local sizekb_csv=""
local idx=0
for app_data in "${apps_data[@]}"; do
# Keep extended field 7 (size_kb) if present
IFS='|' read -r epoch _ display_name _ size last_used size_kb <<< "$app_data"
menu_options+=("$(format_app_display "$display_name" "$size" "$last_used")")
# Build csv lists (avoid trailing commas)
if [[ $idx -eq 0 ]]; then
epochs_csv="${epoch:-0}"
sizekb_csv="${size_kb:-0}"
else
epochs_csv+=",${epoch:-0}"
sizekb_csv+=",${size_kb:-0}"
fi
((idx++))
done
# Expose metadata for the paginated menu (optional inputs)
# - MOLE_MENU_META_EPOCHS: numeric last_used_epoch per item
# - MOLE_MENU_META_SIZEKB: numeric size in KB per item
# The menu will gracefully fallback if these are unset or malformed.
export MOLE_MENU_META_EPOCHS="$epochs_csv"
export MOLE_MENU_META_SIZEKB="$sizekb_csv"
# Optional: allow default sort override via env (date|name|size)
# export MOLE_MENU_SORT_DEFAULT="${MOLE_MENU_SORT_DEFAULT:-date}"
# Use paginated menu - result will be stored in MOLE_SELECTION_RESULT
# Note: paginated_multi_select enters alternate screen and handles clearing
MOLE_SELECTION_RESULT=""
paginated_multi_select "Select Apps to Remove" "${menu_options[@]}"
local exit_code=$?
# Clean env leakage for safety
unset MOLE_MENU_META_EPOCHS MOLE_MENU_META_SIZEKB
# leave MOLE_MENU_SORT_DEFAULT untouched if user set it globally
if [[ $exit_code -ne 0 ]]; then
echo "Cancelled"
return 1
fi
if [[ -z "$MOLE_SELECTION_RESULT" ]]; then
echo "No apps selected"
return 1
fi
# Build selected apps array (global variable in bin/uninstall.sh)
selected_apps=()
# Parse indices and build selected apps array
IFS=',' read -r -a indices_array <<< "$MOLE_SELECTION_RESULT"
for idx in "${indices_array[@]}"; do
if [[ "$idx" =~ ^[0-9]+$ ]] && [[ $idx -ge 0 ]] && [[ $idx -lt ${#apps_data[@]} ]]; then
selected_apps+=("${apps_data[idx]}")
fi
done
return 0
}
# Export function for external use
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
echo "This is a library file. Source it from other scripts." >&2
exit 1
fi