You typed exit. The session is over. But before the cursor blinks its last blink, chpop pops the cap off a cold ASCII beer, lets the foam rise, and sends you off with a satisfying psst! / pop!
Every goodbye deserves a toast. One last animation. One last sip. Then you're free to go.
flowchart LR
A["`π€ You type
exit`"]
--> B["`πΊ chpop intercepts
via shell hook`"]
--> C["`π¨ Foam & fizz!
~2 s animation`"]
--> D["`π Real exit runs
session ends`"]
| Step | What happens |
|---|---|
| Intercepts | A shell function overrides exit, checks if chpop is installed, and calls it first. |
| Pops | The terminal enters the alternate screen, hides the cursor, and plays a short ASCII beer-bottle-opening animation (~2 s). Frames are embedded in the binary at compile time. |
| Fizz | Foam rises, gas escapes β then the terminal is restored cleanly. |
| Exits | The real built-in exit runs with your original arguments (exit code included). |
Press q, Esc, or Ctrl+C to skip the animation if you're in a real rush. The terminal is always restored cleanly β even on panic β thanks to RAII guards with a libc::tcsetattr safety net.
cargo build --release
ln -s "$(pwd)/target/release/chpop" ~/.local/bin/chpopDownload the latest package for your platform from the Releases page:
| Package | Platform |
|---|---|
.deb |
Debian / Ubuntu |
.rpm |
Fedora / RHEL |
.pkg.tar.zst |
Arch Linux |
.tar.gz |
macOS (x86_64 & Apple Silicon) |
sudo dpkg -i chpop_*.deb
# or if dependencies are missing:
sudo apt-get install -fsudo rpm -i chpop-*.rpmsudo pacman -U chpop-*.pkg.tar.zsttar xzf chpop-*-macos-*.tar.gz
mv chpop /usr/local/bin/ # or ~/.local/bin/Note: macOS Gatekeeper may block unsigned binaries. If prompted, go to System Settings β Privacy & Security and click Allow Anyway.
Add to ~/.bashrc:
# chpop: beer animation on terminal exit
exit() {
if command -v chpop >/dev/null 2>&1; then
chpop
fi
builtin exit "$@"
}Add to ~/.zshrc:
# chpop: beer animation on terminal exit
exit() {
if command -v chpop >/dev/null 2>&1; then
chpop
fi
builtin exit "$@"
}- The
exitfunction overrides the shell's built-in command. - Before ending the session,
chpopis invoked. builtin exitcalls the real built-inexit, forwarding all arguments (e.g. the exit code inexit 0).- If
chpopis not installed (command -vfails to find the binary), the step is skipped β nothing breaks.
Make sure you have Rust and Cargo installed, then:
cargo build --releaseThe build script (build.rs) auto-discovers assets/*/anim.json files and compiles all frame data into the binary. No manual configuration needed.
- Create a directory
assets/<name>/ - Add an
anim.jsonfile:{ "name": "<name>", "fps_ms": 400 } - Add frame files
frame_000.txt,frame_001.txt, β¦ cargo buildβ the animation is picked up automatically
chpop/
βββ Cargo.toml β runtime + build dependencies
βββ build.rs β auto-discovers assets/*/anim.json, generates frame arrays
βββ assets/
β βββ chpop/
β βββ anim.json β auto-generated metadata
β βββ frame_*.txt β ASCII art frames
βββ src/
βββ main.rs β entry point, SIGINT handler, animation launch
βββ terminal.rs β TerminalGuard (RAII alternate screen + raw mode + safety net)
βββ animation.rs β frame rendering, centring, early-exit support
If chpop made your last terminal seconds a little more fun, consider throwing some crypto-dust to keep the fridge stocked. Every satoshi, gwei, and piconero buys another round!
| Coin | Network | Address |
|---|---|---|
| Monero | XMR | 89tK9E9LbwdCsnnZGFMJzU7yBRGaQ7hfPTeNXWCe2LW3G7kCkJWswhb2ieBkHFrBs2JfdsmumQ3nY9obQ6fxb4HzHpTjCjd |
| Bitcoin | BTC | bc1qh0t2u7d7u0pl2yzmxuq80verhlfxuj0r29lfv7 |
| USDT | Polygon | 0xe1aAE089F1b0A3b2649017A7E7afa720877409C8 |
| USDC | Polygon | 0xe1aAE089F1b0A3b2649017A7E7afa720877409C8 |
| USDT | TRON | TMkxXPuxamSci19rSygy58QRjZ9vmLjqtu |
| Ethereum | Arbitrum | 0xe1aAE089F1b0A3b2649017A7E7afa720877409C8 |