NRip
nrip is a safe replacement for rm: instead of permanently deleting files, it moves them to a graveyard from which you can list, prune (permanently delete), or resurrect (restore), with fzf feature.
Inspired by rip — hence the binary name nrip (new rip).
MVP v0.8.2: --prune, --list, --resurrect, contextual shell completion, interactive picker (fzf).
Default paths (XDG)
- Graveyard:
${XDG_DATA_HOME:-$HOME/.local/share}/nrip/graveyard- Index:
${XDG_DATA_HOME:-$HOME/.local/share}/nrip/index.json
Installation
Arch User Repository (AUR)
# or
Cargo
From source
Runtime dependency
Interactive -p/--prune and -r/--resurrect require fzf.
- Arch:
pacman -S fzf - Debian/Ubuntu:
sudo apt install fzf - macOS (Homebrew):
brew install fzf
# binary will be in ~/.cargo/bin/nrip
Local build
Usage
Safe rm with a graveyard
Usage: nrip [OPTIONS] [PATHS]...
Arguments:
[PATHS]... Files/dirs to remove (default action)
Options:
-p, --prune [<TARGET>] Prune graveyard; optional TARGET value allows `-p TARGET`
--target <TARGET> (optional) explicit target (used with --prune)
-r, --resurrect [<TARGET>] Resurrect (restore) from graveyard; optional TARGET allows `-r TARGET`
-l, --list List graveyard contents
--dry-run Simulation (no changes)
-y, --yes Skip interactive confirmations
-h, --help Print help
-V, --version Print version
Basic actions
-
Bury (default action):
Items are moved to the graveyard under a unique name:
YYYYMMDDTHHMMSS__RANDOM__basename. -
List:
For each entry it shows:
- a short ID (first 7 chars of
RANDOM), - the
deleted_attimestamp, - the
basename, - the original path.
- a short ID (first 7 chars of
-
Prune (permanent deletion):
-
Resurrect (restore):
Restoration is non-destructive: if the original destination already exists, restoration fails (no overwrite).
Matching rules (for prune/resurrect)
TARGETcan be a substring of the basename or a prefix of the short ID (the 7 chars printed by-l). WithoutTARGET, an interactive picker is displayed (0=ALL).
Interactive picker (fzf)
When -p/--prune or -r/--resurrect are used without a TARGET, NRip opens an fzf picker:
- Multi-select with Tab (press Tab repeatedly, Enter to confirm). :contentReference[oaicite:2]{index=2}
- Displayed fields: timestamp, original path,
->, trashed path (index hidden via--with-nth). :contentReference[oaicite:3]{index=3} - Output is parsed with
--print0to handle arbitrary characters safely. :contentReference[oaicite:4]{index=4}
Shell completion
NRip exposes a hidden completion endpoint used by the functions below:
nrip --__complete <context> <prefix> where <context> is prune or resurrect.
Zsh
# ~/.zshrc
Bash
# ~/.bashrc
How it works (robustness & safety)
-
Atomic move when possible: NRip first tries an atomic
rename(2)to move the file/dir into the graveyard. If the move crosses filesystems (EXDEV), it falls back to copy then remove. -
Durability: after writing/renaming, the parent directory is
fdatasync’d to ensure directory entries are persisted. -
Index file:
index.jsontracks original/trashed paths and timestamps. It is read/written under an advisory lock to avoid corruption across concurrent NRip processes. -
Journal: a plain-text
.journallogsPENDING/DONEandRESTORE_*events for basic auditing and recovery hints. -
Symlinks: preserved (copied as links) during recursive operations when applicable.
Security note: NRip is a user-space trash bin. It does not perform secure shredding/erasure.
Environment & version
- Paths honor
XDG_DATA_HOME(fallback to$HOME/.local/share). nrip -Vprints the Cargo package version used at build time.
Troubleshooting
- Cross-device moves: seeing a cross-device fallback is expected when source and graveyard live on different filesystems; NRip copies then removes.
License
Dual-licensed under MIT and Apache-2.0 (see LICENSE*).