mirror of
https://github.com/tw93/Mole.git
synced 2026-03-22 17:55:08 +00:00
@@ -26,6 +26,7 @@ readonly PURGE_CONFIG_FILE="$HOME/.config/mole/purge_paths"
|
||||
|
||||
# Resolved search paths.
|
||||
PURGE_SEARCH_PATHS=()
|
||||
PURGE_CATEGORY_FULL_PATHS_ARRAY=()
|
||||
|
||||
# Project indicators for container detection.
|
||||
# Monorepo indicators (higher priority)
|
||||
@@ -155,6 +156,53 @@ load_purge_config() {
|
||||
# Initialize paths on script load.
|
||||
load_purge_config
|
||||
|
||||
format_purge_target_path() {
|
||||
local path="$1"
|
||||
echo "${path/#$HOME/~}"
|
||||
}
|
||||
|
||||
compact_purge_menu_path() {
|
||||
local path="$1"
|
||||
local max_width="${2:-0}"
|
||||
|
||||
if ! [[ "$max_width" =~ ^[0-9]+$ ]] || [[ "$max_width" -lt 4 ]]; then
|
||||
max_width=4
|
||||
fi
|
||||
|
||||
local path_width
|
||||
path_width=$(get_display_width "$path")
|
||||
if [[ $path_width -le $max_width ]]; then
|
||||
echo "$path"
|
||||
return
|
||||
fi
|
||||
|
||||
local tail=""
|
||||
local remainder="$path"
|
||||
local prefix_width=3
|
||||
|
||||
while [[ "$remainder" == */* ]]; do
|
||||
local segment="/${remainder##*/}"
|
||||
remainder="${remainder%/*}"
|
||||
|
||||
local candidate="${segment}${tail}"
|
||||
local candidate_width
|
||||
candidate_width=$(get_display_width "$candidate")
|
||||
if [[ $((candidate_width + prefix_width)) -le $max_width ]]; then
|
||||
tail="$candidate"
|
||||
else
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ -n "$tail" ]]; then
|
||||
echo "...${tail}"
|
||||
return
|
||||
fi
|
||||
|
||||
local suffix_len=$((max_width - 3))
|
||||
echo "...${path: -$suffix_len}"
|
||||
}
|
||||
|
||||
# Args: $1 - directory path
|
||||
# Determine whether a directory is a project root.
|
||||
# This is used to safely allow cleaning direct-child artifacts when
|
||||
@@ -542,7 +590,7 @@ select_purge_categories() {
|
||||
term_height=24
|
||||
fi
|
||||
fi
|
||||
local reserved=6
|
||||
local reserved=8
|
||||
local available=$((term_height - reserved))
|
||||
if [[ $available -lt 3 ]]; then
|
||||
echo 3
|
||||
@@ -680,6 +728,13 @@ select_purge_categories() {
|
||||
# Keep one blank line between the list and footer tips.
|
||||
printf "%s\n" "$clear_line"
|
||||
|
||||
local current_index=$((top_index + cursor_pos))
|
||||
local current_full_path="${PURGE_CATEGORY_FULL_PATHS_ARRAY[current_index]:-}"
|
||||
if [[ -n "$current_full_path" ]]; then
|
||||
printf "%s${GRAY}Full path:${NC} %s\n" "$clear_line" "$current_full_path"
|
||||
printf "%s\n" "$clear_line"
|
||||
fi
|
||||
|
||||
# Adaptive footer hints — mirrors menu_paginated.sh pattern
|
||||
local _term_w
|
||||
_term_w=$(tput cols 2> /dev/null || echo 80)
|
||||
@@ -821,6 +876,7 @@ confirm_purge_cleanup() {
|
||||
local item_count="${1:-0}"
|
||||
local total_size_kb="${2:-0}"
|
||||
local unknown_count="${3:-0}"
|
||||
local -a selected_paths=("${@:4}")
|
||||
|
||||
[[ "$item_count" =~ ^[0-9]+$ ]] || item_count=0
|
||||
[[ "$total_size_kb" =~ ^[0-9]+$ ]] || total_size_kb=0
|
||||
@@ -839,6 +895,15 @@ confirm_purge_cleanup() {
|
||||
unknown_hint=", ${unknown_count} ${unknown_text}"
|
||||
fi
|
||||
|
||||
if [[ ${#selected_paths[@]} -gt 0 ]]; then
|
||||
echo ""
|
||||
echo -e "${GRAY}Selected paths:${NC}"
|
||||
local selected_path=""
|
||||
for selected_path in "${selected_paths[@]}"; do
|
||||
echo " $selected_path"
|
||||
done
|
||||
fi
|
||||
|
||||
echo -ne "${PURPLE}${ICON_ARROW}${NC} Remove ${item_count} ${item_text}, ${size_display}${unknown_hint} ${GREEN}Enter${NC} confirm, ${GRAY}ESC${NC} cancel: "
|
||||
drain_pending_input
|
||||
local key=""
|
||||
@@ -1179,7 +1244,7 @@ clean_project_artifacts() {
|
||||
|
||||
# Truncate project path if needed
|
||||
local truncated_path
|
||||
truncated_path=$(truncate_by_display_width "$project_path" "$available_width")
|
||||
truncated_path=$(compact_purge_menu_path "$project_path" "$available_width")
|
||||
local current_width
|
||||
current_width=$(get_display_width "$truncated_path")
|
||||
local char_count=${#truncated_path}
|
||||
@@ -1193,6 +1258,7 @@ clean_project_artifacts() {
|
||||
# Sizes are read from pre-computed results (parallel du calls launched above).
|
||||
local -a raw_project_paths=()
|
||||
local -a raw_artifact_types=()
|
||||
local -a item_display_paths=()
|
||||
local _sz_idx=0
|
||||
for item in "${safe_to_clean[@]}"; do
|
||||
local project_path
|
||||
@@ -1232,6 +1298,7 @@ clean_project_artifacts() {
|
||||
raw_project_paths+=("$project_path")
|
||||
raw_artifact_types+=("$artifact_type")
|
||||
item_paths+=("$item")
|
||||
item_display_paths+=("$(format_purge_target_path "$item")")
|
||||
item_sizes+=("$size_kb")
|
||||
item_size_unknown_flags+=("$size_unknown")
|
||||
item_recent_flags+=("$is_recent")
|
||||
@@ -1349,8 +1416,10 @@ clean_project_artifacts() {
|
||||
)
|
||||
# Interactive selection (only if terminal is available)
|
||||
PURGE_SELECTION_RESULT=""
|
||||
PURGE_CATEGORY_FULL_PATHS_ARRAY=("${item_display_paths[@]}")
|
||||
if [[ -t 0 ]]; then
|
||||
if ! select_purge_categories "${menu_options[@]}"; then
|
||||
PURGE_CATEGORY_FULL_PATHS_ARRAY=()
|
||||
unset PURGE_CATEGORY_SIZES PURGE_RECENT_CATEGORIES PURGE_SELECTION_RESULT
|
||||
return 1
|
||||
fi
|
||||
@@ -1367,12 +1436,14 @@ clean_project_artifacts() {
|
||||
echo ""
|
||||
echo -e "${GRAY}No items selected${NC}"
|
||||
printf '\n'
|
||||
PURGE_CATEGORY_FULL_PATHS_ARRAY=()
|
||||
unset PURGE_CATEGORY_SIZES PURGE_RECENT_CATEGORIES PURGE_SELECTION_RESULT
|
||||
return 0
|
||||
fi
|
||||
IFS=',' read -r -a selected_indices <<< "$PURGE_SELECTION_RESULT"
|
||||
local selected_total_kb=0
|
||||
local selected_unknown_count=0
|
||||
local -a selected_display_paths=()
|
||||
for idx in "${selected_indices[@]}"; do
|
||||
local selected_size_kb="${item_sizes[idx]:-0}"
|
||||
[[ "$selected_size_kb" =~ ^[0-9]+$ ]] || selected_size_kb=0
|
||||
@@ -1380,16 +1451,19 @@ clean_project_artifacts() {
|
||||
if [[ "${item_size_unknown_flags[idx]:-false}" == "true" ]]; then
|
||||
selected_unknown_count=$((selected_unknown_count + 1))
|
||||
fi
|
||||
selected_display_paths+=("${item_display_paths[idx]}")
|
||||
done
|
||||
|
||||
if [[ -t 0 ]]; then
|
||||
if ! confirm_purge_cleanup "${#selected_indices[@]}" "$selected_total_kb" "$selected_unknown_count"; then
|
||||
if ! confirm_purge_cleanup "${#selected_indices[@]}" "$selected_total_kb" "$selected_unknown_count" "${selected_display_paths[@]}"; then
|
||||
echo -e "${GRAY}Purge cancelled${NC}"
|
||||
printf '\n'
|
||||
PURGE_CATEGORY_FULL_PATHS_ARRAY=()
|
||||
unset PURGE_CATEGORY_SIZES PURGE_RECENT_CATEGORIES PURGE_SELECTION_RESULT
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
PURGE_CATEGORY_FULL_PATHS_ARRAY=()
|
||||
|
||||
# Clean selected items
|
||||
echo ""
|
||||
@@ -1398,8 +1472,8 @@ clean_project_artifacts() {
|
||||
local dry_run_mode="${MOLE_DRY_RUN:-0}"
|
||||
for idx in "${selected_indices[@]}"; do
|
||||
local item_path="${item_paths[idx]}"
|
||||
local artifact_type=$(basename "$item_path")
|
||||
local project_path=$(get_project_path "$item_path")
|
||||
local display_item_path
|
||||
display_item_path=$(format_purge_target_path "$item_path")
|
||||
local size_kb="${item_sizes[idx]}"
|
||||
local size_unknown="${item_size_unknown_flags[idx]:-false}"
|
||||
local size_human
|
||||
@@ -1413,7 +1487,7 @@ clean_project_artifacts() {
|
||||
continue
|
||||
fi
|
||||
if [[ -t 1 ]]; then
|
||||
start_inline_spinner "Cleaning $project_path/$artifact_type..."
|
||||
start_inline_spinner "Cleaning $display_item_path..."
|
||||
fi
|
||||
local removal_recorded=false
|
||||
if [[ -e "$item_path" ]]; then
|
||||
@@ -1431,9 +1505,9 @@ clean_project_artifacts() {
|
||||
stop_inline_spinner
|
||||
if [[ "$removal_recorded" == "true" ]]; then
|
||||
if [[ "$dry_run_mode" == "1" ]]; then
|
||||
echo -e "${GREEN}${ICON_SUCCESS}${NC} [DRY RUN] $project_path, $artifact_type${NC}, ${GREEN}$size_human${NC}"
|
||||
echo -e "${GREEN}${ICON_SUCCESS}${NC} [DRY RUN] $display_item_path${NC}, ${GREEN}$size_human${NC}"
|
||||
else
|
||||
echo -e "${GREEN}${ICON_SUCCESS}${NC} $project_path, $artifact_type${NC}, ${GREEN}$size_human${NC}"
|
||||
echo -e "${GREEN}${ICON_SUCCESS}${NC} $display_item_path${NC}, ${GREEN}$size_human${NC}"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user