1
0
mirror of https://github.com/tw93/Mole.git synced 2026-02-04 15:39:42 +00:00

Fix search problems and best practices

This commit is contained in:
Tw93
2025-12-08 17:40:54 +08:00
parent 95ff2e30ac
commit 2386701897
7 changed files with 151 additions and 24 deletions

View File

@@ -456,7 +456,10 @@ safe_clean() {
}
start_cleanup() {
clear
if [[ -t 1 ]]; then
# Avoid relying on TERM since CI often runs without it
printf '\033[2J\033[H'
fi
printf '\n'
echo -e "${PURPLE_BOLD}Clean Your Mac${NC}"
echo ""

View File

@@ -73,11 +73,12 @@ scan_applications() {
local cache_dir="$HOME/.cache/mole"
local cache_file="$cache_dir/app_scan_cache"
local cache_ttl=86400 # 24 hours
local force_rescan="${1:-false}"
mkdir -p "$cache_dir" 2> /dev/null
# Check if cache exists and is fresh
if [[ -f "$cache_file" ]]; then
if [[ $force_rescan == false && -f "$cache_file" ]]; then
local cache_age=$(($(date +%s) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(date +%s) ]] && cache_age=86401 # Handle missing file
if [[ $cache_age -lt $cache_ttl ]]; then
@@ -405,11 +406,15 @@ trap cleanup EXIT INT TERM
# Main function
main() {
# Parse args
local force_rescan=false
for arg in "$@"; do
case "$arg" in
"--debug")
export MO_DEBUG=1
;;
"--force-rescan")
force_rescan=true
;;
esac
done
@@ -425,7 +430,7 @@ main() {
# (scan_applications handles cache internally)
local needs_scanning=true
local cache_file="$HOME/.cache/mole/app_scan_cache"
if [[ -f "$cache_file" ]]; then
if [[ $force_rescan == false && -f "$cache_file" ]]; then
local cache_age=$(($(date +%s) - $(get_file_mtime "$cache_file")))
[[ $cache_age -eq $(date +%s) ]] && cache_age=86401 # Handle missing file
[[ $cache_age -lt 86400 ]] && needs_scanning=false
@@ -444,7 +449,7 @@ main() {
# Scan applications
local apps_file=""
if ! apps_file=$(scan_applications); then
if ! apps_file=$(scan_applications "$force_rescan"); then
if [[ "${MOLE_ALT_SCREEN_ACTIVE:-}" == "1" ]]; then
printf "\033[2J\033[H" >&2
leave_alt_screen

View File

@@ -73,3 +73,93 @@ update_via_homebrew() {
# Clear update cache
rm -f "$HOME/.cache/mole/version_check" "$HOME/.cache/mole/update_message" 2> /dev/null || true
}
# Remove apps from Dock
# Args: app paths to remove
remove_apps_from_dock() {
if [[ $# -eq 0 ]]; then
return 0
fi
local plist="$HOME/Library/Preferences/com.apple.dock.plist"
[[ -f "$plist" ]] || return 0
if ! command -v python3 > /dev/null 2>&1; then
return 0
fi
# Execute Python helper to prune dock entries for the given app paths
python3 - "$@" << 'PY' 2>/dev/null || return 0
import os
import plistlib
import subprocess
import sys
import urllib.parse
plist_path = os.path.expanduser('~/Library/Preferences/com.apple.dock.plist')
if not os.path.exists(plist_path):
sys.exit(0)
def normalise(path):
if not path:
return ''
return os.path.normpath(os.path.realpath(path.rstrip('/')))
targets = {normalise(arg) for arg in sys.argv[1:] if arg}
targets = {t for t in targets if t}
if not targets:
sys.exit(0)
with open(plist_path, 'rb') as fh:
try:
data = plistlib.load(fh)
except Exception:
sys.exit(0)
apps = data.get('persistent-apps')
if not isinstance(apps, list):
sys.exit(0)
changed = False
filtered = []
for item in apps:
try:
url = item['tile-data']['file-data']['_CFURLString']
except (KeyError, TypeError):
filtered.append(item)
continue
if not isinstance(url, str):
filtered.append(item)
continue
parsed = urllib.parse.urlparse(url)
path = urllib.parse.unquote(parsed.path or '')
if not path:
filtered.append(item)
continue
candidate = normalise(path)
if any(candidate == t or candidate.startswith(t + os.sep) for t in targets):
changed = True
continue
filtered.append(item)
if not changed:
sys.exit(0)
data['persistent-apps'] = filtered
with open(plist_path, 'wb') as fh:
try:
plistlib.dump(data, fh, fmt=plistlib.FMT_BINARY)
except Exception:
plistlib.dump(data, fh)
# Restart Dock to apply changes
try:
subprocess.run(['killall', 'Dock'], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, check=False)
except Exception:
pass
PY
}

View File

@@ -49,6 +49,9 @@ read_key() {
case "$key" in
$'\n' | $'\r') echo "ENTER" ;;
' ') echo "SPACE" ;;
'/') echo "FILTER" ;;
'q' | 'Q') echo "QUIT" ;;
'R') echo "RETRY" ;;
$'\x03') echo "QUIT" ;;
$'\x7f' | $'\x08') echo "DELETE" ;;
$'\x1b')

View File

@@ -11,16 +11,25 @@ source "$_MOLE_MANAGE_DIR/../ui/menu_simple.sh"
# Config file paths
readonly WHITELIST_CONFIG_CLEAN="$HOME/.config/mole/whitelist"
readonly WHITELIST_CONFIG_OPTIMIZE="$HOME/.config/mole/whitelist_checks"
readonly WHITELIST_CONFIG_OPTIMIZE="$HOME/.config/mole/whitelist_optimize"
readonly WHITELIST_CONFIG_OPTIMIZE_LEGACY="$HOME/.config/mole/whitelist_checks"
# Default whitelist patterns defined in lib/core/common.sh:
# - DEFAULT_WHITELIST_PATTERNS
# - FINDER_METADATA_SENTINEL
# Save whitelist patterns to config
# Save whitelist patterns to config (defaults to "clean" for legacy callers)
save_whitelist_patterns() {
local mode="$1"
shift
local mode="clean"
if [[ $# -gt 0 ]]; then
case "$1" in
clean | optimize)
mode="$1"
shift
;;
esac
fi
local -a patterns
patterns=("$@")
@@ -170,13 +179,21 @@ load_whitelist() {
local mode="${1:-clean}"
local -a patterns=()
local config_file
local legacy_file=""
if [[ "$mode" == "optimize" ]]; then
config_file="$WHITELIST_CONFIG_OPTIMIZE"
legacy_file="$WHITELIST_CONFIG_OPTIMIZE_LEGACY"
else
config_file="$WHITELIST_CONFIG_CLEAN"
fi
local using_legacy="false"
if [[ ! -f "$config_file" && -n "$legacy_file" && -f "$legacy_file" ]]; then
config_file="$legacy_file"
using_legacy="true"
fi
if [[ -f "$config_file" ]]; then
while IFS= read -r line; do
# shellcheck disable=SC2295
@@ -210,6 +227,11 @@ load_whitelist() {
unique_patterns+=("$pattern")
done
CURRENT_WHITELIST_PATTERNS=("${unique_patterns[@]}")
# Migrate legacy optimize config to the new path automatically
if [[ "$mode" == "optimize" && "$using_legacy" == "true" && "$config_file" != "$WHITELIST_CONFIG_OPTIMIZE" ]]; then
save_whitelist_patterns "$mode" "${CURRENT_WHITELIST_PATTERNS[@]}"
fi
else
CURRENT_WHITELIST_PATTERNS=()
fi

View File

@@ -399,7 +399,7 @@ paginated_multi_select() {
for ((i = 0; i < items_per_page; i++)); do
printf "${clear_line}\n" >&2
done
printf "${clear_line}${GRAY}Type to filter | Delete | Enter | / Exit | ESC${NC}\n" >&2
printf "${clear_line}${GRAY}Type to filter | Delete | Enter Confirm | ESC Cancel${NC}\n" >&2
printf "${clear_line}" >&2
return
else
@@ -480,9 +480,8 @@ paginated_multi_select() {
local -a _segs_filter=(
"${GRAY}Filter: ${filter_status}${NC}"
"${GRAY}Delete${NC}"
"${GRAY}Enter${NC}"
"${GRAY}/ Exit${NC}"
"${GRAY}ESC${NC}"
"${GRAY}Enter Confirm${NC}"
"${GRAY}ESC Cancel${NC}"
)
_print_wrapped_controls "$sep" "${_segs_filter[@]}"
else
@@ -668,15 +667,8 @@ paginated_multi_select() {
CHAR:*)
if [[ "$filter_mode" == "true" ]]; then
local ch="${key#CHAR:}"
# Special handling for /: exit filter mode
if [[ "$ch" == "/" ]]; then
filter_mode="false"
unset MOLE_READ_KEY_FORCE_CHAR
filter_query=""
applied_query=""
rebuild_view
# avoid accidental leading spaces
elif [[ -n "$filter_query" || "$ch" != " " ]]; then
if [[ -n "$filter_query" || "$ch" != " " ]]; then
filter_query+="$ch"
fi
fi

View File

@@ -113,7 +113,6 @@ batch_uninstall_applications() {
local -a sudo_apps=()
local total_estimated_size=0
local -a app_details=()
local -a dock_cleanup_paths=()
# Analyze selected apps with progress indicator
if [[ -t 1 ]]; then start_inline_spinner "Scanning files..."; fi
@@ -315,7 +314,6 @@ batch_uninstall_applications() {
((files_cleaned++))
((total_items++))
success_items+=("$app_name")
dock_cleanup_paths+=("$app_path")
else
((failed_count++))
failed_items+=("$app_name:$reason")
@@ -406,8 +404,22 @@ batch_uninstall_applications() {
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[@]}"
# 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"
# Check if this app was successfully removed
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
fi
# Clean up sudo keepalive if it was started