A better rm written in Rust.
Find a file
2025-08-26 17:59:42 +02:00
assets fix : demo.gif 2025-08-26 12:04:42 +02:00
src chore : changing name prune to cremate 2025-08-26 00:14:35 +02:00
tests fix : fix clippy error 2025-08-25 18:12:26 +02:00
.gitignore init 2025-08-23 18:01:23 +02:00
Cargo.lock chore : changing prune name + better readme;NRip v0.8.9 2025-08-26 00:40:21 +02:00
Cargo.toml chore : changing prune name + better readme;NRip v0.8.9 2025-08-26 00:40:21 +02:00
LICENSE-APACHE fix : update license 2025-08-25 15:32:53 +02:00
LICENSE-MIT fix : update license 2025-08-25 15:32:53 +02:00
README.md fix : fix readme 2025-08-26 17:59:42 +02:00

NRip

neo rip — a safe and modern replacement for rm that sends your files to the graveyard. Bury now, decide later. If you like living dangerously, theres always the crematorium.

NRip tombstone


NRip moves files/dirs to a graveyard instead of deleting them. You can then list, cremate (permanently delete), or resurrect them — interactively with fzf or noninteractively by targeting a basename substring or an ID prefix.

Inspired by rip. Binary name: nrip (neo rip — a wink to nvim and rip).

Default paths (XDG)

  • Graveyard: ${XDG_DATA_HOME:-$HOME/.local/share}/nrip/graveyard
  • Index: ${XDG_DATA_HOME:-$HOME/.local/share}/nrip/index.json

What you get (in the dead of night)

  • 🪦 Bury (default action): timestamped, unique names — no collisions among the dearly departed.
  • 🔎 List: readable output with age, kind, short IDs, and original path.
  • ⚰️ Cremate: permanently erase from the graveyard (interactive or targeted).
  • 🧟 Resurrect: bring files back to their old haunt; refuses to overwrite the living.
  • 🔗 CrossFS aware: falls back to copy→swap when EXDEV strikes.
  • ☠️ Shell completion: contextual suggestions for cremation and resurrection.

Short IDs — list view prints a 7char ID derived from the unique graveyard name. You can target cremate/resurrect using a basename substring or that ID prefix.


Gloomy tour (demo)

Resurrect demo


Installation

Arch User Repository (AUR)

yay -S nrip
# or
paru -S nrip

Cargo

cargo install nrip

From source

Runtime dependency: interactive cremate/resurrect requires fzf.

  • Arch: pacman -S fzf
  • Debian/Ubuntu: sudo apt install fzf
  • macOS (Homebrew): brew install fzf
git clone https://github.com/Samtroulcode/NRip
cd NRip
cargo install --path .
# binary will be in ~/.cargo/bin/nrip

Local build

cargo build --release
./target/release/nrip --help

Usage

Usage: nrip [OPTIONS] [PATHS]...

Arguments:
  [PATHS]...  Files/dirs to remove (default action)

Options:
  -c, --cremate [<TARGET>]    Permanently remove from graveyard
  -r, --resurrect [<TARGET>]  Resurrect (restore) from graveyard
      --target <TARGET>       (optional) explicit target (used with --cremate/--resurrect)
  -f, --force                 (optional) force
  -l, --list                  List graveyard contents
      --dry-run               Dry run (no changes)
  -y, --yes                   (optional) skip confirmation prompts
  -h, --help                  Print help
  -V, --version               Print version

Basic rites

Bury (default action)

nrip file1 dir2

The deceased are moved to the graveyard under a unique name: YYYYMMDDTHHMMSS__RANDOM__basename.

List the dearly departed

nrip -l

Shows short ID, timestamp, age, type icon, basename, and original path.

Cremate (permanent deletion)

nrip -c               # FZF interactive menu
nrip -c foo           # target by basename substring or ID prefix
nrip -c --dry-run     # simulate
nrip -c -y            # no prompts (the quick burn)

Resurrect (restore)

nrip -r               # FZF interactive menu
nrip -r foo           # target by basename substring or ID prefix
nrip -r --dry-run     # simulate
nrip -r -y            # raise without confirmation

Restoration is nondestructive: if the original destination already exists, NRip refuses to disturb the living.

Matching rulesTARGET can be a substring of the basename or a prefix of the short ID. Without TARGET, an interactive picker (fzf) is displayed.


Shell completion

Hidden completion endpoint: nrip --__complete <context> <prefix> where <context> is cremate or resurrect.

Zsh

# ~/.zshrc
_nrip_complete() {
  local cur prev
  cur=${words[-1]}
  prev=${words[-2]}

  if [[ $prev == "-c" || $prev == "--cremate" ]]; then
    compadd -- ${(f)"$(nrip --__complete cremate "$cur")"}
    return 0
  elif [[ $prev == "-r" || $prev == "--resurrect" ]]; then
    compadd -- ${(f)"$(nrip --__complete resurrect "$cur")"}
    return 0
  fi
  return 1
}
compdef _nrip_complete nrip

Bash

# ~/.bashrc
_nrip_complete() {
  local cur prev
  COMPREPLY=()
  cur="${COMP_WORDS[COMP_CWORD]}"
  prev="${COMP_WORDS[COMP_CWORD-1]}"

  if [[ "$prev" == "-c" || "$prev" == "--cremate" ]]; then
    mapfile -t COMPREPLY < <(nrip --__complete cremate "$cur")
  elif [[ "$prev" == "-r" || "$prev" == "--resurrect" ]]; then
    mapfile -t COMPREPLY < <(nrip --__complete resurrect "$cur")
  fi
}
complete -F _nrip_complete nrip

Under the slab (how it works)

  • Atomic move first — attempt rename(2); on crossdevice (EXDEV), use copy → swap → remove.
  • Durability — directory entries are synced to keep the graveyard from losing corpses on power loss.
  • Indexindex.json tracks original/trashed paths, timestamps, and kind; guarded by a lock to prevent concurrent corruption.
  • Journal.journal notes PENDING/DONE and RESTORE_* events for basic forensics.
  • Symlinks — preserved during recursive operations when applicable.

Security note — NRip is a userspace trash bin. It does not perform secure shredding.


Roadmap of horrors (configuration)

Planned ~/.config/nrip/config.toml keys:

# Change the graveyard location
graveyard_dir = "/data/nrip/graveyard"

# Customize list format (order, fields, colors)
list.format = "{id} {icon} {kind} {deleted_at} {age} {basename} {original_path}"

# FZF preview command used for interactive modes
fzf.preview = "ls -l --color=always {trashed_path} || tree -C {trashed_path}"

# Confirmation policy
confirm.resurrect = true
confirm.cremate_all = "type-YES"

Knobs to expect:

  • graveyard_dir
  • list.format / list.time_format
  • fzf.preview / fzf.height
  • color = auto|always|never (honors NO_COLOR)

FAQ from beyond

What if the destination exists during resurrection? NRip refuses to overwrite; the living stay undisturbed.

Crossdevice moves? On EXDEV, NRip copies to a temp in the graveyard, syncs, swaps into place, removes the source.

Disable colors? Set NO_COLOR=1 or pipe; NRip autodetects TTY.

Uninstall

  • Cargo: cargo uninstall nrip
  • AUR: yay -Rns nrip
  • Optional: nuke ${XDG_DATA_HOME:-$HOME/.local/share}/nrip/

Contributing

Before opening a coffin—err, PR—please run cargo fmt, cargo clippy -D warnings, and cargo test.


License

Duallicensed under MIT and Apache2.0. See LICENSE*.