diff --git a/bin/uninstall.sh b/bin/uninstall.sh index 28b4fea..977e975 100755 --- a/bin/uninstall.sh +++ b/bin/uninstall.sh @@ -498,7 +498,12 @@ main() { fi # Interactive selection using paginated menu - if ! select_apps_for_uninstall; then + set +e + select_apps_for_uninstall + local exit_code=$? + set -e + + if [[ $exit_code -ne 0 ]]; then if [[ "${MOLE_ALT_SCREEN_ACTIVE:-}" == "1" ]]; then leave_alt_screen unset MOLE_ALT_SCREEN_ACTIVE @@ -508,6 +513,13 @@ main() { clear_screen printf '\033[2J\033[H' >&2 # Also clear stderr rm -f "$apps_file" + + # Handle Refresh (code 10) + if [[ $exit_code -eq 10 ]]; then + force_rescan=true + continue + fi + # User cancelled selection, exit the loop return 0 fi diff --git a/lib/core/app_protection.sh b/lib/core/app_protection.sh index 8f23dd4..1a3bf0d 100755 --- a/lib/core/app_protection.sh +++ b/lib/core/app_protection.sh @@ -708,32 +708,34 @@ find_app_receipt_files() { done < <(find /private/var/db/receipts -name "${bundle_id}*.bom" -print0 2> /dev/null) fi - for bom_file in "${bom_files[@]}"; do - [[ ! -f "$bom_file" ]] && continue + # Process bom files if any found + if [[ ${#bom_files[@]} -gt 0 ]]; then + for bom_file in "${bom_files[@]}"; do + [[ ! -f "$bom_file" ]] && continue - # Parse bom file - # lsbom -f: file paths only - # -s: suppress output (convert to text) - local bom_content - bom_content=$(lsbom -f -s "$bom_file" 2> /dev/null) + # Parse bom file + # lsbom -f: file paths only + # -s: suppress output (convert to text) + local bom_content + bom_content=$(lsbom -f -s "$bom_file" 2> /dev/null) - while IFS= read -r file_path; do - # Standardize path (remove leading dot) - local clean_path="${file_path#.}" + while IFS= read -r file_path; do + # Standardize path (remove leading dot) + local clean_path="${file_path#.}" - # Ensure it starts with / - if [[ "$clean_path" != /* ]]; then - clean_path="/$clean_path" - fi + # Ensure it starts with / + if [[ "$clean_path" != /* ]]; then + clean_path="/$clean_path" + fi - # ------------------------------------------------------------------------ - # SAFETY FILTER: Only allow specific removal paths - # ------------------------------------------------------------------------ - local is_safe=false + # ------------------------------------------------------------------------ + # SAFETY FILTER: Only allow specific removal paths + # ------------------------------------------------------------------------ + local is_safe=false - # Whitelisted prefixes - case "$clean_path" in - /Applications/*) is_safe=true ;; + # Whitelisted prefixes + case "$clean_path" in + /Applications/*) is_safe=true ;; /Users/*) is_safe=true ;; /usr/local/*) is_safe=true ;; /opt/*) is_safe=true ;; @@ -782,7 +784,7 @@ find_app_receipt_files() { done <<< "$bom_content" done - + fi if [[ ${#receipt_files[@]} -gt 0 ]]; then printf '%s\n' "${receipt_files[@]}" fi diff --git a/lib/ui/app_selector.sh b/lib/ui/app_selector.sh index c8e93c0..7454b6b 100755 --- a/lib/ui/app_selector.sh +++ b/lib/ui/app_selector.sh @@ -85,6 +85,11 @@ select_apps_for_uninstall() { unset MOLE_MENU_META_EPOCHS MOLE_MENU_META_SIZEKB # leave MOLE_MENU_SORT_DEFAULT untouched if user set it globally + # Refresh signal handling + if [[ $exit_code -eq 10 ]]; then + return 10 + fi + if [[ $exit_code -ne 0 ]]; then echo "Cancelled" return 1 diff --git a/lib/ui/menu_paginated.sh b/lib/ui/menu_paginated.sh index 40c5cab..9672490 100755 --- a/lib/ui/menu_paginated.sh +++ b/lib/ui/menu_paginated.sh @@ -474,11 +474,11 @@ paginated_multi_select() { fi # Footer: single line with controls - local sep=" ${GRAY}|${NC} " + local sep=" ${GRAY}|${NC} " if [[ "$filter_mode" == "true" ]]; then # Filter mode: simple controls without sort local -a _segs_filter=( - "${GRAY}Filter: ${filter_status}${NC}" + "${GRAY}Search: ${filter_status}${NC}" "${GRAY}Delete${NC}" "${GRAY}Enter Confirm${NC}" "${GRAY}ESC Cancel${NC}" @@ -490,7 +490,7 @@ paginated_multi_select() { [[ "$sort_reverse" == "true" ]] && reverse_arrow="↓" # Determine filter text based on whether filter is active - local filter_text="/ Filter" + local filter_text="/ Search" [[ -n "$applied_query" ]] && filter_text="/ Clear" if [[ "$has_metadata" == "true" ]]; then @@ -508,8 +508,9 @@ paginated_multi_select() { # Normal: show full controls local -a _segs_all=( "${GRAY}${ICON_NAV_UP}${ICON_NAV_DOWN}${NC}" - "${GRAY}Space${NC}" + "${GRAY}Space Select${NC}" "${GRAY}Enter${NC}" + "${GRAY}F Refresh${NC}" "${GRAY}${filter_text}${NC}" "${GRAY}S ${sort_status}${NC}" "${GRAY}R ${reverse_arrow}${NC}" @@ -521,7 +522,7 @@ paginated_multi_select() { # Without metadata: basic controls local -a _segs_simple=( "${GRAY}${ICON_NAV_UP}${ICON_NAV_DOWN}${NC}" - "${GRAY}Space${NC}" + "${GRAY}Space Select${NC}" "${GRAY}Enter${NC}" "${GRAY}${filter_text}${NC}" "${GRAY}Q Exit${NC}" @@ -643,6 +644,10 @@ paginated_multi_select() { "CHAR:f" | "CHAR:F") if [[ "$filter_mode" == "true" ]]; then filter_query+="${key#CHAR:}" + else + # Trigger Refresh signal + cleanup + return 10 fi ;; "CHAR:r") diff --git a/mole b/mole index f49c80d..635f48c 100755 --- a/mole +++ b/mole @@ -22,7 +22,7 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/lib/core/common.sh" # Version info -VERSION="1.12.13" +VERSION="1.12.14" MOLE_TAGLINE="can dig deep to clean your Mac." # Check if Touch ID is already configured