1
0
mirror of https://github.com/tw93/Mole.git synced 2026-03-22 17:55:08 +00:00

fix: show full purge paths during confirmation

Fixes #576
This commit is contained in:
Tw93
2026-03-17 19:20:15 +08:00
parent 13274154d4
commit 25892594b0
3 changed files with 187 additions and 22 deletions

View File

@@ -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