{"id":31074198,"url":"https://github.com/samtroulcode/nrip","last_synced_at":"2025-12-30T21:23:13.759Z","repository":{"id":311321883,"uuid":"1043344182","full_name":"Samtroulcode/NRip","owner":"Samtroulcode","description":"A safe replacement for rm with a graveyard","archived":false,"fork":false,"pushed_at":"2025-08-24T16:27:26.000Z","size":132,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-24T17:10:59.901Z","etag":null,"topics":["bash","cli","command","command-line-tool","gnu-linux","linux","linux-shell","rust","rust-lang","shell","zsh"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Samtroulcode.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE-APACHE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-08-23T16:51:44.000Z","updated_at":"2025-08-24T16:27:24.000Z","dependencies_parsed_at":"2025-08-24T17:11:05.177Z","dependency_job_id":null,"html_url":"https://github.com/Samtroulcode/NRip","commit_stats":null,"previous_names":["samtroulcode/riptide","samtroulcode/nrip"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/Samtroulcode/NRip","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samtroulcode%2FNRip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samtroulcode%2FNRip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samtroulcode%2FNRip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samtroulcode%2FNRip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Samtroulcode","download_url":"https://codeload.github.com/Samtroulcode/NRip/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Samtroulcode%2FNRip/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275348511,"owners_count":25448626,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-16T02:00:10.229Z","response_time":65,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bash","cli","command","command-line-tool","gnu-linux","linux","linux-shell","rust","rust-lang","shell","zsh"],"created_at":"2025-09-16T02:06:46.387Z","updated_at":"2025-09-16T02:06:47.542Z","avatar_url":"https://github.com/Samtroulcode.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# NRip\n\n\u003e **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, there’s always the crematorium.\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/img/tombstone.svg\" width=\"120\" alt=\"NRip tombstone\"/\u003e\n\u003c/p\u003e\n\n---\n\nNRip moves files/dirs to a **graveyard** instead of deleting them. You can then **list**, **cremate** (permanently delete), or **resurrect** them — interactively with **fzf** or non‑interactively by targeting a basename substring or an ID prefix.\n\n\u003e Inspired by [rip](https://github.com/nivekuil/rip). Binary name: **nrip** (neo rip — a wink to nvim and rip).\n\n\u003e **Default paths (XDG)**\n\u003e\n\u003e * **Graveyard**: `${XDG_DATA_HOME:-$HOME/.local/share}/nrip/graveyard`\n\u003e * **Index**: `${XDG_DATA_HOME:-$HOME/.local/share}/nrip/index.json`\n\n## What you get (in the dead of night)\n\n* 🪦 **Bury** (default action): timestamped, unique names — no collisions among the dearly departed.\n* 🔎 **List**: readable output with age, kind, short IDs, and original path.\n* ⚰️ **Cremate**: permanently erase from the graveyard (interactive or targeted).\n* 🧟 **Resurrect**: bring files back to their old haunt; refuses to overwrite the living.\n* 🔗 **Cross‑FS aware**: falls back to copy→swap when `EXDEV` strikes.\n* ☠️ **Shell completion**: contextual suggestions for cremation and resurrection.\n\n\u003e **Short IDs** — list view prints a 7‑char ID derived from the unique graveyard name. You can target **cremate**/**resurrect** using a basename substring *or* that ID prefix.\n\n---\n\n## Gloomy tour (demo)\n\n  ![Resurrect demo](assets/gifs/demo.gif)\n\n---\n\n## Installation\n\n### Arch User Repository (AUR)\n\n```bash\nyay -S nrip\n# or\nparu -S nrip\n```\n\n### Cargo\n\n```bash\ncargo install nrip\n```\n\n### From source\n\n\u003e **Runtime dependency**: interactive **cremate/resurrect** requires [`fzf`](https://github.com/junegunn/fzf).\n\u003e\n\u003e * Arch: `pacman -S fzf`\n\u003e * Debian/Ubuntu: `sudo apt install fzf`\n\u003e * macOS (Homebrew): `brew install fzf`\n\n```bash\ngit clone https://github.com/Samtroulcode/NRip\ncd NRip\ncargo install --path .\n# binary will be in ~/.cargo/bin/nrip\n```\n\n### Local build\n\n```bash\ncargo build --release\n./target/release/nrip --help\n```\n\n---\n\n## Usage\n\n```\nUsage: nrip [OPTIONS] [PATHS]...\n\nArguments:\n  [PATHS]...  Files/dirs to remove (default action)\n\nOptions:\n  -c, --cremate [\u003cTARGET\u003e]    Permanently remove from graveyard\n  -r, --resurrect [\u003cTARGET\u003e]  Resurrect (restore) from graveyard\n      --target \u003cTARGET\u003e       (optional) explicit target (used with --cremate/--resurrect)\n  -f, --force                 (optional) force\n  -l, --list                  List graveyard contents\n      --dry-run               Dry run (no changes)\n  -y, --yes                   (optional) skip confirmation prompts\n  -h, --help                  Print help\n  -V, --version               Print version\n```\n\n### Basic rites\n\n**Bury (default action)**\n\n```bash\nnrip file1 dir2\n```\n\nThe deceased are moved to the graveyard under a **unique name**:\n`YYYYMMDDTHHMMSS__RANDOM__basename`.\n\n**List the dearly departed**\n\n```bash\nnrip -l\n```\n\nShows short **ID**, timestamp, age, type icon, basename, and original path.\n\n**Cremate (permanent deletion)**\n\n```bash\nnrip -c               # FZF interactive menu\nnrip -c foo           # target by basename substring or ID prefix\nnrip -c --dry-run     # simulate\nnrip -c -y            # no prompts (the quick burn)\n```\n\n**Resurrect (restore)**\n\n```bash\nnrip -r               # FZF interactive menu\nnrip -r foo           # target by basename substring or ID prefix\nnrip -r --dry-run     # simulate\nnrip -r -y            # raise without confirmation\n```\n\n\u003e Restoration is **non‑destructive**: if the original destination already exists, NRip refuses to disturb the living.\n\n\u003e **Matching rules** — `TARGET` can be a **substring of the basename** or a **prefix of the short ID**. Without `TARGET`, an **interactive picker** (fzf) is displayed.\n\n---\n\n## Shell completion\n\nHidden completion endpoint: `nrip --__complete \u003ccontext\u003e \u003cprefix\u003e` where `\u003ccontext\u003e` is `cremate` or `resurrect`.\n\n### Zsh\n\n```zsh\n# ~/.zshrc\n_nrip_complete() {\n  local cur prev\n  cur=${words[-1]}\n  prev=${words[-2]}\n\n  if [[ $prev == \"-c\" || $prev == \"--cremate\" ]]; then\n    compadd -- ${(f)\"$(nrip --__complete cremate \"$cur\")\"}\n    return 0\n  elif [[ $prev == \"-r\" || $prev == \"--resurrect\" ]]; then\n    compadd -- ${(f)\"$(nrip --__complete resurrect \"$cur\")\"}\n    return 0\n  fi\n  return 1\n}\ncompdef _nrip_complete nrip\n```\n\n### Bash\n\n```bash\n# ~/.bashrc\n_nrip_complete() {\n  local cur prev\n  COMPREPLY=()\n  cur=\"${COMP_WORDS[COMP_CWORD]}\"\n  prev=\"${COMP_WORDS[COMP_CWORD-1]}\"\n\n  if [[ \"$prev\" == \"-c\" || \"$prev\" == \"--cremate\" ]]; then\n    mapfile -t COMPREPLY \u003c \u003c(nrip --__complete cremate \"$cur\")\n  elif [[ \"$prev\" == \"-r\" || \"$prev\" == \"--resurrect\" ]]; then\n    mapfile -t COMPREPLY \u003c \u003c(nrip --__complete resurrect \"$cur\")\n  fi\n}\ncomplete -F _nrip_complete nrip\n```\n\n---\n\n## Under the slab (how it works)\n\n* **Atomic move first** — attempt `rename(2)`; on cross‑device (`EXDEV`), use copy → swap → remove.\n* **Durability** — directory entries are synced to keep the graveyard from losing corpses on power loss.\n* **Index** — `index.json` tracks original/trashed paths, timestamps, and kind; guarded by a lock to prevent concurrent corruption.\n* **Journal** — `.journal` notes `PENDING/DONE` and `RESTORE_*` events for basic forensics.\n* **Symlinks** — preserved during recursive operations when applicable.\n\n\u003e **Security note** — NRip is a user‑space trash bin. It does **not** perform secure shredding.\n\n---\n\n## Roadmap of horrors (configuration)\n\nPlanned `~/.config/nrip/config.toml` keys:\n\n```toml\n# Change the graveyard location\ngraveyard_dir = \"/data/nrip/graveyard\"\n\n# Customize list format (order, fields, colors)\nlist.format = \"{id} {icon} {kind} {deleted_at} {age} {basename} {original_path}\"\n\n# FZF preview command used for interactive modes\nfzf.preview = \"ls -l --color=always {trashed_path} || tree -C {trashed_path}\"\n\n# Confirmation policy\nconfirm.resurrect = true\nconfirm.cremate_all = \"type-YES\"\n```\n\nKnobs to expect:\n\n* `graveyard_dir`\n* `list.format` / `list.time_format`\n* `fzf.preview` / `fzf.height`\n* `color = auto|always|never` (honors `NO_COLOR`)\n\n---\n\n## FAQ from beyond\n\n**What if the destination exists during resurrection?**  NRip refuses to overwrite; the living stay undisturbed.\n\n**Cross‑device moves?**  On `EXDEV`, NRip copies to a temp in the graveyard, syncs, swaps into place, removes the source.\n\n**Disable colors?**  Set `NO_COLOR=1` or pipe; NRip auto‑detects TTY.\n\n**Uninstall**\n\n* Cargo: `cargo uninstall nrip`\n* AUR: `yay -Rns nrip`\n* Optional: nuke `${XDG_DATA_HOME:-$HOME/.local/share}/nrip/`\n\n---\n\n## Contributing\n\nBefore opening a coffin—err, PR—please run `cargo fmt`, `cargo clippy -D warnings`, and `cargo test`.\n\n---\n\n## License\n\nDual‑licensed under **MIT** and **Apache‑2.0**. See `LICENSE*`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamtroulcode%2Fnrip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsamtroulcode%2Fnrip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsamtroulcode%2Fnrip/lists"}