From 579c9639405bd0ee23d8c7b6e59ed1d95ef383db Mon Sep 17 00:00:00 2001 From: tw93 Date: Tue, 3 Feb 2026 17:36:15 +0800 Subject: [PATCH] uninstall: refine protection flow and menu filtering --- lib/core/app_protection.sh | 11 ++++++-- lib/ui/menu_paginated.sh | 8 ++++++ lib/uninstall/batch.sh | 57 ++++++++++++-------------------------- 3 files changed, 34 insertions(+), 42 deletions(-) diff --git a/lib/core/app_protection.sh b/lib/core/app_protection.sh index ed930db..90fa7dd 100755 --- a/lib/core/app_protection.sh +++ b/lib/core/app_protection.sh @@ -707,7 +707,13 @@ should_protect_data() { ;; esac - # Most apps won't match, return early + # Fallback: check against the full DATA_PROTECTED_BUNDLES list + for pattern in "${DATA_PROTECTED_BUNDLES[@]}"; do + if bundle_matches_pattern "$bundle_id" "$pattern"; then + return 0 + fi + done + return 1 } @@ -772,7 +778,8 @@ should_protect_path() { # Matches: .../Library/Group Containers/group.id/... if [[ "$path" =~ /Library/Containers/([^/]+) ]] || [[ "$path" =~ /Library/Group\ Containers/([^/]+) ]]; then local bundle_id="${BASH_REMATCH[1]}" - if should_protect_data "$bundle_id"; then + # In uninstall mode, only system components are protected; skip data protection + if [[ "${MOLE_UNINSTALL_MODE:-0}" != "1" ]] && should_protect_data "$bundle_id"; then return 0 fi fi diff --git a/lib/ui/menu_paginated.sh b/lib/ui/menu_paginated.sh index 05316cd..57c2478 100755 --- a/lib/ui/menu_paginated.sh +++ b/lib/ui/menu_paginated.sh @@ -657,6 +657,14 @@ paginated_multi_select() { fi ;; "SPACE") + # In filter mode with active text, treat space as search character + if [[ -n "$filter_text" ]]; then + filter_text+=" " + rebuild_view + cursor_pos=0 + need_full_redraw=true + continue + fi local idx=$((top_index + cursor_pos)) if [[ $idx -lt ${#view_indices[@]} ]]; then local real="${view_indices[idx]}" diff --git a/lib/uninstall/batch.sh b/lib/uninstall/batch.sh index cba0ee8..9d03af9 100755 --- a/lib/uninstall/batch.sh +++ b/lib/uninstall/batch.sh @@ -300,18 +300,15 @@ batch_uninstall_applications() { echo -e "${PURPLE_BOLD}Files to be removed:${NC}" echo "" - # Warn if user data is detected. - local has_user_data=false + # Warn if brew cask apps are present. + local has_brew_cask=false for detail in "${app_details[@]}"; do - IFS='|' read -r _ _ _ _ _ _ has_sensitive_data <<< "$detail" - if [[ "$has_sensitive_data" == "true" ]]; then - has_user_data=true - break - fi + IFS='|' read -r _ _ _ _ _ _ _ _ is_brew_cask_flag _ <<< "$detail" + [[ "$is_brew_cask_flag" == "true" ]] && has_brew_cask=true done - if [[ "$has_user_data" == "true" ]]; then - echo -e "${GRAY}${ICON_WARNING}${NC} ${YELLOW}Note: Some apps contain user configurations/themes${NC}" + if [[ "$has_brew_cask" == "true" ]]; then + echo -e "${GRAY}${ICON_WARNING}${NC} ${YELLOW}Homebrew apps will be fully cleaned (--zap: removes configs & data)${NC}" echo "" fi @@ -431,6 +428,7 @@ batch_uninstall_applications() { local related_files=$(decode_file_list "$encoded_files" "$app_name") local system_files=$(decode_file_list "$encoded_system_files" "$app_name") local reason="" + local suggestion="" # Show progress for current app local brew_tag="" @@ -567,7 +565,7 @@ batch_uninstall_applications() { [[ "$used_brew_successfully" == "true" ]] && ((brew_apps_removed++)) ((files_cleaned++)) ((total_items++)) - success_items+=("$app_name") + success_items+=("$app_path") else if [[ -t 1 ]]; then if [[ ${#app_details[@]} -gt 1 ]]; then @@ -593,7 +591,6 @@ batch_uninstall_applications() { local -a summary_details=() if [[ $success_count -gt 0 ]]; then - local success_list="${success_items[*]}" local success_text="app" [[ $success_count -gt 1 ]] && success_text="apps" local success_line="Removed ${success_count} ${success_text}" @@ -602,13 +599,15 @@ batch_uninstall_applications() { fi # Format app list with max 3 per line. - if [[ -n "$success_list" ]]; then + if [[ ${#success_items[@]} -gt 0 ]]; then local idx=0 local is_first_line=true local current_line="" - for app_name in "${success_items[@]}"; do - local display_item="${GREEN}${app_name}${NC}" + for success_path in "${success_items[@]}"; do + local display_name + display_name=$(basename "$success_path" .app) + local display_item="${GREEN}${display_name}${NC}" if ((idx % 3 == 0)); then if [[ -n "$current_line" ]]; then @@ -709,20 +708,8 @@ batch_uninstall_applications() { fi # Clean up Dock entries for uninstalled apps. - if [[ $success_count -gt 0 ]]; then - local -a removed_paths=() - for detail in "${app_details[@]}"; do - IFS='|' read -r app_name app_path _ _ _ _ <<< "$detail" - for success_name in "${success_items[@]}"; do - if [[ "$success_name" == "$app_name" ]]; then - removed_paths+=("$app_path") - break - fi - done - done - if [[ ${#removed_paths[@]} -gt 0 ]]; then - remove_apps_from_dock "${removed_paths[@]}" 2> /dev/null || true - fi + if [[ $success_count -gt 0 && ${#success_items[@]} -gt 0 ]]; then + remove_apps_from_dock "${success_items[@]}" 2> /dev/null || true fi _cleanup_sudo_keepalive @@ -733,18 +720,8 @@ batch_uninstall_applications() { if [[ $success_count -gt 0 ]]; then local cache_file="$HOME/.cache/mole/app_scan_cache" if [[ -f "$cache_file" ]]; then - local -a removed_paths=() - for detail in "${app_details[@]}"; do - IFS='|' read -r app_name app_path _ _ _ _ <<< "$detail" - for success_name in "${success_items[@]}"; do - if [[ "$success_name" == "$app_name" ]]; then - removed_paths+=("$app_path") - break - fi - done - done - - if [[ ${#removed_paths[@]} -gt 0 ]]; then + if [[ ${#success_items[@]} -gt 0 ]]; then + local -a removed_paths=("${success_items[@]}") local temp_cache temp_cache=$(create_temp_file) local line_removed=false