Skip to content

Commit cc3bbed

Browse files
authored
feat: search by filtering trash files (#19)
* feat: search by filtering trash files * test: add test for search filter
1 parent d44ecdd commit cc3bbed

2 files changed

Lines changed: 122 additions & 4 deletions

File tree

rm-safely

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env bash
22

3-
VERSION="1.7.0"
3+
VERSION="1.8.0"
44
HOOK_FILE="$HOME/.rm-safely"
55

66
GREEN='\033[0;32m'
@@ -183,8 +183,15 @@ rm() {
183183
fi
184184
;;
185185
--list-trash|-l)
186+
shift
187+
local filter_pattern="$1"
186188
local has_files=0
187-
echo "Trash Contents:"
189+
190+
if [ -n "$filter_pattern" ]; then
191+
echo "Trash Contents (filtered by: '$filter_pattern'):"
192+
else
193+
echo "Trash Contents:"
194+
fi
188195
echo "==============="
189196
echo "Hash | Filename | Original Path"
190197
echo "--------|------------------------------------------|--------------"
@@ -200,8 +207,27 @@ rm() {
200207
info_file="$trash_info/${basename}.info"
201208
# Generate short hash from filename
202209
hash=$(echo -n "$basename" | sha256sum | cut -c1-6)
210+
211+
# Get original path
212+
local original_path=""
203213
if [ -f "$info_file" ]; then
204214
original_path=$(cat "$info_file" 2>/dev/null)
215+
fi
216+
217+
# Apply filter if pattern provided
218+
if [ -n "$filter_pattern" ]; then
219+
# Extract original filename by removing timestamp suffix
220+
local original_filename="${basename%_*}"
221+
222+
# Case-insensitive match on filename or path
223+
if ! echo "$original_filename" | grep -qi "$filter_pattern" && \
224+
! echo "$original_path" | grep -qi "$filter_pattern"; then
225+
continue
226+
fi
227+
fi
228+
229+
# Display the file
230+
if [ -n "$original_path" ]; then
205231
printf "%-7s | %-40s | %s\n" "$hash" "$basename" "$original_path"
206232
else
207233
printf "%-7s | %-40s | %s\n" "$hash" "$basename" "(unknown)"
@@ -212,7 +238,11 @@ rm() {
212238
done < <(get_all_trash_dirs)
213239
214240
if [ $has_files -eq 0 ]; then
215-
echo "Trash is empty"
241+
if [ -n "$filter_pattern" ]; then
242+
echo "No files found matching pattern: '$filter_pattern'"
243+
else
244+
echo "Trash is empty"
245+
fi
216246
fi
217247
;;
218248
--undo|-u)
@@ -346,13 +376,23 @@ Files on other filesystems go to <mountpoint>/.Trash-<uid>
346376
347377
Options:
348378
--rm Skip trash!, really execute 'rm'
349-
--list-trash, -l Show trash contents from all filesystems
379+
--list-trash [pattern], -l [pattern]
380+
Show trash contents from all filesystems
381+
Optional: filter by pattern (case-insensitive)
350382
--restore <hash>, -s Restore a file from trash using its hash
351383
--undo, -u Restore the last deleted files
352384
--empty-trash Empty all trash directories
353385
--show-trash-path, -p Display all trash directory paths
354386
--version Show version information
355387
--help Show this help
388+
389+
Examples:
390+
rm file.txt Move file to trash
391+
rm -l List all files in trash
392+
rm -l ".js" List only JavaScript files in trash
393+
rm -l "project" List files with "project" in name or path
394+
rm -s a1b2c3 Restore file with hash a1b2c3
395+
rm -u Undo last deletion
356396
HELP
357397
;;
358398
*)

test_e2e.sh

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,84 @@ else
239239
print_fail "Should show trash path"
240240
fi
241241

242+
print_scenario "Search/Filter Trash Contents"
243+
244+
print_test "Create files with unique patterns for filter testing"
245+
echo "project code" >uniqueproject123_config.js
246+
echo "app code" >uniqueapp456_settings.json
247+
echo "readme text" >uniqueREADME789.md
248+
echo "test code" >uniquehelper999_test.py
249+
rm uniqueproject123_config.js uniqueapp456_settings.json uniqueREADME789.md uniquehelper999_test.py
250+
print_pass "Created and deleted 4 files with unique patterns"
251+
252+
print_test "Filter by filename pattern - includes match"
253+
filter_output=$(rm --list-trash "uniqueproject123" 2>&1)
254+
if echo "$filter_output" | grep -q "uniqueproject123_config.js"; then
255+
print_pass "Filter includes matching file (uniqueproject123)"
256+
else
257+
print_fail "Filter should show uniqueproject123_config.js"
258+
fi
259+
260+
print_test "Filter by filename pattern - excludes non-match"
261+
filter_output=$(rm --list-trash "uniqueproject123" 2>&1)
262+
if ! echo "$filter_output" | grep -q "uniqueapp456_settings.json"; then
263+
print_pass "Filter excludes non-matching file"
264+
else
265+
print_fail "Filter should not show uniqueapp456_settings.json when filtering by uniqueproject123"
266+
fi
267+
268+
print_test "Filter with different unique pattern"
269+
filter_output=$(rm --list-trash "helper999" 2>&1)
270+
if echo "$filter_output" | grep -q "uniquehelper999_test.py"; then
271+
print_pass "Filter shows matching file (helper999)"
272+
else
273+
print_fail "Filter should show uniquehelper999_test.py"
274+
fi
275+
276+
print_test "Filter with file extension pattern"
277+
filter_output=$(rm --list-trash "uniqueREADME789.md" 2>&1)
278+
if echo "$filter_output" | grep -q "uniqueREADME789.md" && \
279+
! echo "$filter_output" | grep -q "uniquehelper999_test.py"; then
280+
print_pass "Filter matches specific markdown file"
281+
else
282+
print_fail "Filter should show uniqueREADME789.md but not .py files"
283+
fi
284+
285+
print_test "Filter with guaranteed no matches"
286+
filter_output=$(rm --list-trash "xYz123NoMatchEver456" 2>&1)
287+
if echo "$filter_output" | grep -q "No files found matching pattern"; then
288+
print_pass "Filter correctly reports no matches"
289+
else
290+
print_fail "Should show 'No files found' message for non-existent pattern"
291+
fi
292+
293+
print_test "Case-insensitive filter test (uppercase)"
294+
filter_output=$(rm --list-trash "UNIQUEREADME789" 2>&1)
295+
if echo "$filter_output" | grep -q "uniqueREADME789.md"; then
296+
print_pass "Filter is case-insensitive (uppercase pattern)"
297+
else
298+
print_fail "Filter should match uniqueREADME789.md with uppercase pattern"
299+
fi
300+
301+
print_test "Case-insensitive filter test (lowercase)"
302+
filter_output=$(rm --list-trash "uniquereadme789" 2>&1)
303+
if echo "$filter_output" | grep -q "uniqueREADME789.md"; then
304+
print_pass "Filter is case-insensitive (lowercase pattern)"
305+
else
306+
print_fail "Filter should match uniqueREADME789.md with lowercase pattern"
307+
fi
308+
309+
print_test "List all trash without filter shows test files"
310+
list_output=$(rm --list-trash 2>&1)
311+
if echo "$list_output" | grep -q "uniqueproject123_config.js" && \
312+
echo "$list_output" | grep -q "uniqueapp456_settings.json" && \
313+
echo "$list_output" | grep -q "uniqueREADME789.md" && \
314+
echo "$list_output" | grep -q "uniquehelper999_test.py"; then
315+
print_pass "Listing all trash shows all test files"
316+
else
317+
print_fail "Should show all test files when no filter is provided"
318+
fi
319+
242320
print_scenario "Direct Deletion (Bypass Trash)"
243321
print_test "Create file for permanent deletion"
244322
echo "disposable" >disposable.txt

0 commit comments

Comments
 (0)