1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-08 03:54:19 +00:00

Well-structured output

This commit is contained in:
Tw93
2025-10-11 22:43:18 +08:00
parent 3b33c5a4a8
commit 55f6bd352f
7 changed files with 126 additions and 69 deletions

View File

@@ -87,23 +87,36 @@ batch_uninstall_applications() {
local remaining=$((file_count - max_files))
echo -e " ${GRAY} ... and ${remaining} more files${NC}"
fi
echo ""
done
# Show summary and get batch confirmation first (before asking for password)
local app_total=${#selected_apps[@]}
local app_text="app"
[[ $app_total -gt 1 ]] && app_text="apps"
echo ""
local removal_note="Remove ${app_total} ${app_text}"
[[ -n "$size_display" ]] && removal_note+=" (${size_display})"
if [[ ${#running_apps[@]} -gt 0 ]]; then
echo -n "${BLUE}${ICON_CONFIRM}${NC} Remove ${app_total} ${app_text} | ${size_display} | Force quit: ${running_apps[*]} | Enter=go / ESC=q: "
else
echo -n "${BLUE}${ICON_CONFIRM}${NC} Remove ${app_total} ${app_text} | ${size_display} | Enter=go / ESC=q: "
removal_note+=" - will force quit: ${running_apps[*]}"
fi
echo -ne "${PURPLE}${NC} ${removal_note}. Press ${GREEN}Enter${NC} to confirm, ${GRAY}ESC${NC} to cancel: "
IFS= read -r -s -n1 key || key=""
case "$key" in
$'\e'|q|Q) echo ""; return 0 ;;
""|$'\n'|$'\r'|y|Y) echo "" ;;
*) echo ""; return 0 ;;
$'\e'|q|Q)
echo ""
echo ""
return 0
;;
""|$'\n'|$'\r'|y|Y)
printf "\r\033[K" # Clear the prompt line
;;
*)
echo ""
echo ""
return 0
;;
esac
# User confirmed, now request sudo access if needed
@@ -117,19 +130,9 @@ batch_uninstall_applications() {
fi
fi
(while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null) &
local sudo_keepalive_pid=$!
local _trap_cleanup_cmd="kill $sudo_keepalive_pid 2>/dev/null || true; wait $sudo_keepalive_pid 2>/dev/null || true"
for signal in EXIT INT TERM; do
local existing_trap; existing_trap=$(trap -p "$signal" | awk -F"'" '{print $2}')
if [[ -n "$existing_trap" ]]; then
trap "$existing_trap; $_trap_cleanup_cmd" "$signal"
else
trap "$_trap_cleanup_cmd" "$signal"
fi
done
sudo_keepalive_pid=$!
fi
echo ""
if [[ -t 1 ]]; then start_inline_spinner "Uninstalling apps..."; fi
# Force quit running apps first (batch)
@@ -183,8 +186,23 @@ batch_uninstall_applications() {
if [[ $success_count -gt 0 ]]; then
local success_list="${success_items[*]}"
summary_details+=("Removed: ${GREEN}${success_list}${NC}")
summary_details+=("Freed space: ${GREEN}${freed_display}${NC}")
local success_text="app"
[[ $success_count -gt 1 ]] && success_text="apps"
local success_line="Removed ${success_count} ${success_text}"
if [[ -n "$freed_display" ]]; then
success_line+=", freed ${GREEN}${freed_display}${NC}"
fi
if [[ -n "$success_list" ]]; then
local -a formatted_apps=()
for app_name in "${success_items[@]}"; do
formatted_apps+=("${GREEN}${app_name}${NC}")
done
if [[ ${#formatted_apps[@]} -gt 0 ]]; then
local IFS=', '
success_line+=": ${formatted_apps[*]}"
fi
fi
summary_details+=("$success_line")
fi
if [[ $failed_count -gt 0 ]]; then
@@ -216,6 +234,7 @@ batch_uninstall_applications() {
fi
print_summary_block "$summary_status" "Uninstall complete" "${summary_details[@]}"
printf '\n'
if [[ ${#dock_cleanup_paths[@]} -gt 0 ]]; then
remove_apps_from_dock "${dock_cleanup_paths[@]}"
@@ -225,6 +244,7 @@ batch_uninstall_applications() {
if [[ -n "${sudo_keepalive_pid:-}" ]]; then
kill "$sudo_keepalive_pid" 2>/dev/null || true
wait "$sudo_keepalive_pid" 2>/dev/null || true
sudo_keepalive_pid=""
fi
((total_size_cleaned += total_size_freed))

View File

@@ -28,7 +28,7 @@ readonly ICON_ERROR="✗" # Error
readonly ICON_EMPTY="○" # Empty state
readonly ICON_LIST="-" # List item
readonly ICON_MENU="▸" # Menu item
readonly ICON_SYSTEM="" # System/Architecture info
readonly ICON_SYSTEM="" # System/Architecture info
readonly ICON_SETTINGS="⚙" # Settings/Configuration
# Spinner character helpers (ASCII by default, overridable via env)
@@ -741,7 +741,37 @@ clean_tool_cache() {
}
# ============================================================================
# Confirmation prompt abstraction (Enter=confirm ESC/q=cancel)
# Unified confirmation prompt with consistent style
# ============================================================================
# Unified action prompt
# Usage: prompt_action "action" "cancel_text" -> returns 0 for yes, 1 for no
# Example: prompt_action "enable" "quit" -> "☛ Press Enter to enable, ESC to quit: "
prompt_action() {
local action="$1"
local cancel="${2:-cancel}"
echo ""
echo -ne "${PURPLE}${NC} Press ${GREEN}Enter${NC} to ${action}, ${GRAY}ESC${NC} to ${cancel}: "
IFS= read -r -s -n1 key || key=""
case "$key" in
$'\e') # ESC
echo ""
return 1
;;
""|$'\n'|$'\r') # Enter
printf "\r\033[K" # Clear the prompt line
return 0
;;
*)
echo ""
return 1
;;
esac
}
# Legacy confirmation prompt (kept for compatibility)
# confirm_prompt "Message" -> 0 yes, 1 no
confirm_prompt() {
local message="$1"

View File

@@ -262,6 +262,14 @@ EOF
fi
done
if [[ ${#selected_indices[@]} -eq 0 ]]; then
local default_idx=$((top_index + cursor_pos))
if [[ $default_idx -ge 0 && $default_idx -lt $total_items ]]; then
selected[default_idx]=true
selected_indices=("$default_idx")
fi
fi
local final_result=""
if [[ ${#selected_indices[@]} -gt 0 ]]; then
local IFS=','

View File

@@ -179,7 +179,6 @@ manage_whitelist_categories() {
echo ""
echo -e "${PURPLE}Whitelist Manager${NC}"
echo ""
echo -e "${GRAY}Select caches to protect from cleanup.${NC}"
echo ""
# Load currently enabled patterns from both sources
@@ -248,7 +247,7 @@ manage_whitelist_categories() {
fi
MOLE_SELECTION_RESULT=""
paginated_multi_select "Select caches to protect" "${menu_options[@]}"
paginated_multi_select "Whitelist Manager Select caches to protect" "${menu_options[@]}"
unset MOLE_PRESELECTED_INDICES
local exit_code=$?
@@ -283,6 +282,7 @@ manage_whitelist_categories() {
print_summary_block "success" \
"Protected ${#selected_patterns[@]} cache(s)" \
"Saved to ${WHITELIST_CONFIG}"
printf '\n'
}