diff --git a/cli/install.sh b/cli/install.sh index eaddfbc..4ca50fa 100755 --- a/cli/install.sh +++ b/cli/install.sh @@ -1,15 +1,39 @@ #!/usr/bin/env bash -# install.sh — installer for hypercar-colorscripts (v0.3.3) +# install.sh — installer for hypercar-colorscripts (v0.1.1) # -# Fixes: pokemon_mix now written as a proper JSON boolean (not a quoted -# string), matching the *bool schema the Go binary expects to unmarshal. +# Bug-fix release. Changes vs the previous public build: +# +# * ben10-colorscripts coexistence. Previously, installing hypercar +# after ben10 would leave both shell blocks active (double render). +# Now: +# - if a ben10-colorscripts shell block is already present, hypercar +# defers to it and skips writing its own render block (ben10's +# block already knows how to render both projects); +# - if only the ben10 binary is present (no ben10 block), hypercar's +# own render block includes ben10 in the mixing pool. +# +# * fastfetch styling: writes ~/.config/fastfetch/hypercar.jsonc +# automatically (Catppuccin+ vibrant gradient palette). Arrows now +# align perfectly (`type: name`, no icons — icons re-enabled by +# changing one field in the JSONC). Existing file is backed up. +# +# * chafa fallback: image still renders when fastfetch is not installed. +# +# * kitty logo-type detection fix (kitty-direct → kitty on older +# fastfetch builds). +# +# * macOS portability: `shuf` replaced with an awk one-liner, Ghostty +# detection via TERM_PROGRAM + TERM as well as GHOSTTY_RESOURCES_DIR. +# +# * Broader marker-deletion regex on reinstall; PATH dedupe. # # Flags: # --system binary -> /usr/local/bin (sudo) # --no-shell skip all .rc modifications # --yes / -y skip confirmations # --with-vintage include vintage cars even with --yes -# --no-mix don't mix pokemon even if pokemon-colorscripts is present +# --no-mix don't mix with other colorscripts (pokemon / ben10) +# --no-ff-config skip writing ~/.config/fastfetch/hypercar.jsonc # --uninstall forward to uninstall.sh set -uo pipefail @@ -21,16 +45,17 @@ warn() { echo -e "${YELLOW}⚠${NC} $*"; } fail() { echo -e "${RED}✗${NC} $*" >&2; exit 1; } fsize() { stat -c %s "$1" 2>/dev/null || stat -f %z "$1" 2>/dev/null || echo 0; } -SYSTEM_INSTALL=0; NO_SHELL=0; ASSUME_YES=0; WITH_VINTAGE=0; NO_MIX=0 +SYSTEM_INSTALL=0; NO_SHELL=0; ASSUME_YES=0; WITH_VINTAGE=0; NO_MIX=0; NO_FF_CONFIG=0 for arg in "$@"; do case "$arg" in - --system) SYSTEM_INSTALL=1 ;; - --no-shell) NO_SHELL=1 ;; - --yes|-y) ASSUME_YES=1 ;; - --with-vintage) WITH_VINTAGE=1 ;; - --no-mix) NO_MIX=1 ;; - --uninstall) exec "$(dirname "${BASH_SOURCE[0]}")/uninstall.sh" ;; - --help|-h) sed -n '2,/^set -uo/p' "$0" | sed 's/^# \?//'; exit 0 ;; + --system) SYSTEM_INSTALL=1 ;; + --no-shell) NO_SHELL=1 ;; + --yes|-y) ASSUME_YES=1 ;; + --with-vintage) WITH_VINTAGE=1 ;; + --no-mix) NO_MIX=1 ;; + --no-ff-config) NO_FF_CONFIG=1 ;; + --uninstall) exec "$(dirname "${BASH_SOURCE[0]}")/uninstall.sh" ;; + --help|-h) sed -n '2,/^set -uo/p' "$0" | sed 's/^# \?//'; exit 0 ;; esac done @@ -38,17 +63,19 @@ BINARY="hypercar-colorscripts" DATA_DIR="$HOME/.local/share/hypercar-colorscripts" CONFIG_DIR="$HOME/.config/hypercar-colorscripts" CONFIG_FILE="$CONFIG_DIR/config.json" +FF_CONFIG_DIR="$HOME/.config/fastfetch" +FF_CONFIG_FILE="$FF_CONFIG_DIR/hypercar.jsonc" SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" PROJECT_ROOT="$( cd "$SCRIPT_DIR/.." && pwd )" SRC_MANIFEST="$PROJECT_ROOT/manifest.json" SRC_ASSETS="$PROJECT_ROOT/assets" HELPER="$SCRIPT_DIR/_vintage_helper.py" -echo -e "${BLUE}═══ hypercar-colorscripts installer ═══${NC}" +echo -e "${BLUE}═══ hypercar-colorscripts installer (v0.1.1) ═══${NC}" -# 1. Prereqs -step "1/8 Prerequisites" -command -v chafa >/dev/null 2>&1 || fail "chafa required — sudo dnf install chafa" +# 1. Prereqs + detect other colorscripts projects +step "1/9 Prerequisites" +command -v chafa >/dev/null 2>&1 || fail "chafa required — sudo dnf install chafa (or: brew install chafa)" ok "chafa" PYTHON="$(command -v python3 || command -v python || true)" [[ -n "$PYTHON" ]] || fail "python required" @@ -61,13 +88,31 @@ if command -v pokemon-colorscripts >/dev/null 2>&1; then ok "pokemon-colorscripts detected at $(command -v pokemon-colorscripts)" fi -# 2. Build (always rebuild — Go caches internally, this is cheap) -step "2/8 Binary" +HAS_BEN10=0 +if command -v ben10-colorscripts >/dev/null 2>&1; then + HAS_BEN10=1 + ok "ben10-colorscripts detected at $(command -v ben10-colorscripts)" +fi + +# Detect which kitty logo type this fastfetch understands. +# `kitty-direct` is newer (~2024); older builds only know `kitty`. +KITTY_LOGO_TYPE="kitty-direct" +if command -v fastfetch >/dev/null 2>&1; then + if ! fastfetch --help-logo 2>/dev/null | grep -q 'kitty-direct'; then + KITTY_LOGO_TYPE="kitty" + fi + ok "fastfetch logo type: $KITTY_LOGO_TYPE" +else + warn "fastfetch not installed — image will still render via chafa; info card skipped" +fi + +# 2. Build +step "2/9 Binary" (cd "$SCRIPT_DIR" && make build) || fail "make build failed" ok "$SCRIPT_DIR/$BINARY" # 3. Source data -step "3/8 Source data" +step "3/9 Source data" [[ -f "$SRC_MANIFEST" ]] || fail "manifest.json missing" [[ -d "$SRC_ASSETS/images" ]] || fail "assets/images/ missing" eval "$($PYTHON "$HELPER" info "$SRC_MANIFEST")" || fail "helper info failed" @@ -75,11 +120,11 @@ VINTAGE_MB=$((VINTAGE_BYTES / 1024 / 1024)) ok "Source: $MODERN_COUNT modern + $VINTAGE_COUNT vintage cars (~${VINTAGE_MB} MB)" # 4. Rendering mode -step "4/8 Default rendering mode" +step "4/9 Default rendering mode" DEFAULT_MODE="auto" if [[ $ASSUME_YES -eq 0 ]]; then echo "How to render at terminal startup:" - echo " 1) auto — real image in Kitty/Ghostty/WezTerm, ANSI text elsewhere" + echo " 1) auto — real image in Kitty/Ghostty/WezTerm/iTerm2, ANSI text elsewhere" echo " 2) ansi — always pre-rendered text" read -rp "Choice [1]: " m case "${m:-1}" in 2) DEFAULT_MODE="ansi" ;; *) DEFAULT_MODE="auto" ;; esac @@ -87,7 +132,7 @@ fi ok "Mode: $DEFAULT_MODE" # 5. Vintage -step "5/8 Vintage cars" +step "5/9 Vintage cars" PREV_HAS_VINTAGE=0 if [[ -f "$DATA_DIR/manifest.json" ]]; then eval "$($PYTHON "$HELPER" status "$DATA_DIR")" @@ -105,33 +150,36 @@ if [[ $ASSUME_YES -eq 0 ]]; then fi fi -# 6. Pokemon mixing -step "6/8 Pokemon mixing" -POKEMON_MIX="false" -if [[ $HAS_POKEMON -eq 1 && $NO_MIX -eq 0 ]]; then +# 6. Mixing +step "6/9 Colorscripts mixing" +POKEMON_MIX="false" # config field name kept for backward-compat; controls all mixing now +if [[ $NO_MIX -eq 0 ]] && [[ $HAS_POKEMON -eq 1 || $HAS_BEN10 -eq 1 ]]; then + MIXERS="" + [[ $HAS_POKEMON -eq 1 ]] && MIXERS="${MIXERS:+$MIXERS + }pokemon" + [[ $HAS_BEN10 -eq 1 ]] && MIXERS="${MIXERS:+$MIXERS + }ben10" if [[ $ASSUME_YES -eq 1 ]]; then POKEMON_MIX="true" - ok "Pokemon mixing enabled (--yes)" + ok "Mixing enabled with: $MIXERS (--yes)" else - echo "pokemon-colorscripts is installed." - read -rp "Mix pokemon 50/50 with cars at terminal startup? [Y/n]: " ans + echo "Other colorscripts detected: $MIXERS" + read -rp "Mix them evenly with cars at terminal startup? [Y/n]: " ans if [[ "${ans:-Y}" =~ ^[Nn] ]]; then POKEMON_MIX="false" - ok "Pokemon mixing disabled (only cars will show)" + ok "Mixing disabled (only cars will show)" else POKEMON_MIX="true" - ok "Pokemon mixing enabled" + ok "Mixing enabled ($MIXERS + cars)" fi fi elif [[ $NO_MIX -eq 1 ]]; then - ok "Pokemon mixing disabled (--no-mix)" + ok "Mixing disabled (--no-mix)" else - ok "pokemon-colorscripts not installed — mixing not applicable" + ok "No other colorscripts installed — mixing not applicable" fi echo " (toggle later: hypercar-colorscripts --set-mix on|off)" # 7. Assets + config + binary -step "7/8 Install assets, config, binary" +step "7/9 Install assets, config, binary" mkdir -p "$DATA_DIR" if [[ $INCLUDE_VINTAGE -eq 1 ]]; then "$PYTHON" "$HELPER" install-all "$SRC_MANIFEST" "$SRC_ASSETS" "$DATA_DIR" || fail "install-all failed" @@ -140,8 +188,6 @@ else fi ok "Assets in $DATA_DIR" -# Note: pokemon_mix is written as an unquoted JSON boolean (true/false). -# Any other quoting will break unmarshaling in Go and revert to default (true). mkdir -p "$CONFIG_DIR" cat > "$CONFIG_FILE" < "$FF_CONFIG_FILE" <<'FF_JSONC_END' +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "padding": { "top": 1, "right": 3 } + }, + "display": { + "separator": " → ", + "color": { + "title": "1;38;5;51", + "separator": "38;5;146" + }, + "key": { + "width": 12, + "type": "string" + } + }, + "modules": [ + { "type": "custom", "format": "\u001b[38;5;51m╭─── \u001b[1;38;5;231mSYSTEM\u001b[22;38;5;51m ────────────────────────────╮\u001b[0m" }, + { "type": "title", "keyColor": "1;38;5;46" }, + { "type": "custom", "format": "\u001b[38;5;146m ────────────────────────────────────────\u001b[0m" }, + { "type": "os", "keyColor": "1;38;5;46" }, + { "type": "host", "keyColor": "1;38;5;82" }, + { "type": "kernel", "keyColor": "1;38;5;121" }, + { "type": "uptime", "keyColor": "1;38;5;51" }, + { "type": "packages", "keyColor": "1;38;5;45" }, + { "type": "shell", "keyColor": "1;38;5;39" }, + { "type": "terminal", "keyColor": "1;38;5;33" }, + { "type": "cpu", "keyColor": "1;38;5;99" }, + { "type": "memory", "keyColor": "1;38;5;141" }, + { "type": "disk", "keyColor": "1;38;5;183" }, + { "type": "custom", "format": "\u001b[38;5;51m╰────────────────────────────────────────╯\u001b[0m" } + ] +} +FF_JSONC_END + ok "Wrote $FF_CONFIG_FILE (vibrant gradient palette)" +fi + +# 9. Shell rc +step "9/9 Shell startup" [[ $NO_SHELL -eq 1 ]] && { warn "Skipped (--no-shell)"; exit 0; } detect_login_shell() { @@ -205,6 +300,34 @@ if [[ -n "$SECONDARY_RC" ]]; then fi fi +# Detect if ben10-colorscripts already owns the shell integration in ANY +# of the rc files we're about to touch. If so, we defer to it and skip +# writing hypercar's own render block (ben10's block already handles both +# projects via its coexistence logic). +BEN10_OWNS_SHELL=0 +for RC in "${RC_FILES[@]}"; do + if [[ -f "$RC" ]] && grep -qE '# >>> ben10-colorscripts.*>>>' "$RC" 2>/dev/null; then + BEN10_OWNS_SHELL=1 + break + fi +done + +if [[ $BEN10_OWNS_SHELL -eq 1 ]]; then + warn "ben10-colorscripts shell block detected" + echo " ben10's block already handles rendering hypercar alongside itself." + echo " Skipping hypercar shell-block write to avoid double-render." + echo " (If you want hypercar to own the block, first run ben10-colorscripts's" + echo " uninstall.sh to remove ben10's block, then re-run this installer.)" + echo + echo -e "${GREEN}═══ Done ═══${NC}" + [[ $INCLUDE_VINTAGE -eq 1 ]] && echo "Installed: $TOTAL_COUNT cars (modern + vintage)" || echo "Installed: $MODERN_COUNT cars" + echo "Mode: $DEFAULT_MODE Mixing: $POKEMON_MIX Shell integration: ben10-owned" + [[ $NO_FF_CONFIG -eq 0 ]] && echo "fastfetch styling: $FF_CONFIG_FILE" + echo + echo "Open a new terminal to see the changes." + exit 0 +fi + if [[ $ASSUME_YES -eq 0 ]]; then echo "Will modify: ${RC_FILES[*]}" read -rp "Proceed? [Y/n]: " ans @@ -217,8 +340,10 @@ for RC in "${RC_FILES[@]}"; do BACKUP="$RC.hypercar-backup-$(date +%Y%m%d-%H%M%S)" cp "$RC" "$BACKUP" - sed -i.tmp '/# >>> hypercar-colorscripts PATH >>>/,/# <<< hypercar-colorscripts PATH <<>> hypercar-colorscripts >>>/,/# <<< hypercar-colorscripts <<>> hypercar-colorscripts.*>>>/,/# <<< hypercar-colorscripts.*<< "$TMP" && mv "$TMP" "$RC" + if ! grep -qE "(\\$HOME|\\$\\{HOME\\}|~)/\\.local/bin" "$RC"; then TMP="$(mktemp)" { @@ -243,13 +378,16 @@ for RC in "${RC_FILES[@]}"; do fi BEFORE=$(fsize "$RC") + + # Write render block via single-quoted heredoc, then sed-substitute + # the @@HC_KITTY_TYPE@@ placeholder with the detected logo type. cat >> "$RC" <<'HC_BLOCK_END' # >>> hypercar-colorscripts >>> # Auto-installed by hypercar-colorscripts. Use uninstall.sh to remove. __HC_DATA="$HOME/.local/share/hypercar-colorscripts" -__HC_CFG="$HOME/.config/fastfetch/config-pokemon.jsonc" __HC_CONF="$HOME/.config/hypercar-colorscripts/config.json" +__HC_FF_CFG="$HOME/.config/fastfetch/hypercar.jsonc" __HC_MODE="auto" __HC_MIX="true" @@ -261,48 +399,107 @@ if [ -f "$__HC_CONF" ]; then unset __HC_TMP fi +# Use the hypercar fastfetch styling config if present; deleting it never +# breaks this block (fastfetch just falls back to its default output). +__HC_FF_ARGS=() +[ -f "$__HC_FF_CFG" ] && __HC_FF_ARGS=(-c "$__HC_FF_CFG") + +# Portable random-line picker (macOS has no `shuf` by default). +__hc_pick() { awk 'BEGIN{srand()} {a[NR]=$0} END{if(NR)print a[int(rand()*NR)+1]}'; } + +# Mixing target selection. We use explicit slot arithmetic instead of +# shell word-splitting on a pool string, because zsh (unlike bash) does +# not word-split unquoted variables by default — which would make the +# picker collapse to always picking "car". +__HC_TARGET="car" +if [ "$__HC_MIX" = "true" ]; then + __HC_HAS_POKEMON=0 + __HC_HAS_BEN10=0 + command -v pokemon-colorscripts >/dev/null 2>&1 && __HC_HAS_POKEMON=1 + command -v ben10-colorscripts >/dev/null 2>&1 && __HC_HAS_BEN10=1 + __HC_TOTAL=$(( 1 + __HC_HAS_POKEMON + __HC_HAS_BEN10 )) + __HC_ROLL=$(( RANDOM % __HC_TOTAL )) + # Slot 0 is always car; the installed siblings fill slots 1..N-1 + # in the order pokemon, then ben10. + if [ "$__HC_ROLL" -eq 0 ]; then + __HC_TARGET="car" + elif [ "$__HC_ROLL" -eq 1 ] && [ "$__HC_HAS_POKEMON" -eq 1 ]; then + __HC_TARGET="pokemon" + elif [ "$__HC_ROLL" -eq 1 ] && [ "$__HC_HAS_BEN10" -eq 1 ]; then + __HC_TARGET="ben10" + else + __HC_TARGET="ben10" + fi +fi + __HC_IMG_OK=0 -case "${TERM:-}" in xterm-kitty*) __HC_IMG_OK=1 ;; esac +case "${TERM:-}" in xterm-kitty*|xterm-ghostty*) __HC_IMG_OK=1 ;; esac [ -n "${KITTY_WINDOW_ID:-}" ] && __HC_IMG_OK=1 +[ "${TERM_PROGRAM:-}" = "ghostty" ] && __HC_IMG_OK=1 [ "${TERM_PROGRAM:-}" = "WezTerm" ] && __HC_IMG_OK=1 [ "${TERM_PROGRAM:-}" = "iTerm.app" ] && __HC_IMG_OK=1 [ -n "${GHOSTTY_RESOURCES_DIR:-}" ] && __HC_IMG_OK=1 [ "$__HC_MODE" = "ansi" ] && __HC_IMG_OK=0 -if [ "$__HC_MIX" = "true" ] && [ $(($RANDOM % 2)) -eq 0 ] && command -v pokemon-colorscripts >/dev/null 2>&1; then - if command -v fastfetch >/dev/null 2>&1 && [ -f "$__HC_CFG" ]; then +if [ "$__HC_TARGET" = "pokemon" ]; then + if command -v fastfetch >/dev/null 2>&1; then pokemon-colorscripts --no-title -s -r | \ - fastfetch -c "$__HC_CFG" --logo-type file-raw --logo-height 10 --logo-width 5 --logo - + fastfetch "${__HC_FF_ARGS[@]}" --logo-type file-raw --logo-height 10 --logo-width 5 --logo - else pokemon-colorscripts --no-title -s -r fi -elif [ "$__HC_IMG_OK" -eq 1 ] && command -v fastfetch >/dev/null 2>&1 && [ -f "$__HC_CFG" ]; then - __HC_IMG=$(ls "$__HC_DATA/assets/images/"*.png 2>/dev/null | shuf -n 1) - [ -n "$__HC_IMG" ] && \ - fastfetch -c "$__HC_CFG" --logo-type kitty --logo-height 10 --logo-width 25 --logo "$__HC_IMG" +elif [ "$__HC_TARGET" = "ben10" ]; then + if command -v fastfetch >/dev/null 2>&1; then + ben10-colorscripts --random 2>/dev/null | \ + fastfetch "${__HC_FF_ARGS[@]}" --logo-type file-raw --logo-height 10 --logo-width 5 --logo - + else + ben10-colorscripts --random 2>/dev/null || ben10-colorscripts + fi +elif [ "$__HC_IMG_OK" -eq 1 ]; then + # Car branch — image path (Kitty/Ghostty/WezTerm/iTerm2) + __HC_IMG=$(ls "$__HC_DATA/assets/images/"*.png 2>/dev/null | __hc_pick) + if [ -n "$__HC_IMG" ]; then + if command -v fastfetch >/dev/null 2>&1; then + fastfetch "${__HC_FF_ARGS[@]}" --logo-type @@HC_KITTY_TYPE@@ --logo-height 14 --logo-width 28 --logo "$__HC_IMG" + elif command -v chafa >/dev/null 2>&1; then + chafa --size 60x20 "$__HC_IMG" + fi + fi else - __HC_ANSI=$(ls "$__HC_DATA/assets/ansi/"*.txt 2>/dev/null | shuf -n 1) + # Car branch — ANSI fallback + __HC_ANSI=$(ls "$__HC_DATA/assets/ansi/"*.txt 2>/dev/null | __hc_pick) if [ -n "$__HC_ANSI" ]; then - if command -v fastfetch >/dev/null 2>&1 && [ -f "$__HC_CFG" ]; then - cat "$__HC_ANSI" | fastfetch -c "$__HC_CFG" --logo-type file-raw --logo-height 25 --logo-width 80 --logo - + if command -v fastfetch >/dev/null 2>&1; then + cat "$__HC_ANSI" | fastfetch "${__HC_FF_ARGS[@]}" --logo-type file-raw --logo-height 25 --logo-width 80 --logo - else cat "$__HC_ANSI" fi fi fi -unset __HC_DATA __HC_CFG __HC_CONF __HC_MODE __HC_MIX __HC_IMG_OK __HC_IMG __HC_ANSI +unset -f __hc_pick 2>/dev/null +unset __HC_DATA __HC_CONF __HC_FF_CFG __HC_FF_ARGS __HC_MODE __HC_MIX \ + __HC_TARGET __HC_HAS_POKEMON __HC_HAS_BEN10 __HC_TOTAL __HC_ROLL \ + __HC_IMG_OK __HC_IMG __HC_ANSI # <<< hypercar-colorscripts <<< HC_BLOCK_END + + # Substitute the kitty logo type placeholder + sed -i.tmp "s|@@HC_KITTY_TYPE@@|${KITTY_LOGO_TYPE}|g" "$RC" + rm -f "$RC.tmp" + AFTER=$(fsize "$RC") [[ $AFTER -gt $BEFORE ]] || fail "$RC didn't grow" grep -q '# >>> hypercar-colorscripts >>>' "$RC" || fail "$RC missing marker" + grep -q '@@HC_KITTY_TYPE@@' "$RC" && fail "placeholder substitution failed in $RC" ok "Block appended ($((AFTER - BEFORE)) bytes)" done echo echo -e "${GREEN}═══ Done ═══${NC}" [[ $INCLUDE_VINTAGE -eq 1 ]] && echo "Installed: $TOTAL_COUNT cars (modern + vintage)" || echo "Installed: $MODERN_COUNT cars" -echo "Mode: $DEFAULT_MODE Pokemon mix: $POKEMON_MIX" +echo "Mode: $DEFAULT_MODE Mixing: $POKEMON_MIX fastfetch logo-type: $KITTY_LOGO_TYPE" +[[ $NO_FF_CONFIG -eq 0 ]] && echo "fastfetch styling: $FF_CONFIG_FILE" +[[ $HAS_BEN10 -eq 1 ]] && echo "ben10-colorscripts: detected, included in mixing" echo echo "Toggle later:" echo " hypercar-colorscripts --set-mode auto|ansi" diff --git a/cli/uninstall.sh b/cli/uninstall.sh index 0d552fe..ff4f733 100755 --- a/cli/uninstall.sh +++ b/cli/uninstall.sh @@ -1,13 +1,23 @@ #!/usr/bin/env bash -# uninstall.sh — remove hypercar-colorscripts cleanly (v0.3.2) +# uninstall.sh — remove hypercar-colorscripts cleanly (v0.1.1) # -# Removed: completion file cleanup (shell completions feature dropped). -# Best-effort deletes any leftover completion files from previous versions -# so nobody ends up with stale files after upgrading. +# Changes from previous version: +# * Removes ~/.config/fastfetch/hypercar.jsonc (installed by v0.1.1). +# Backup made first, in case the user hand-tweaked it. +# * No prompts about pokemon-colorscripts or ben10-colorscripts — +# those are not our tools to touch. # -# Options: -# 1) Only hypercar-colorscripts (default) -# 2) Both hypercar + pokemon-colorscripts +# Behavior: +# * Removes hypercar binary from ~/.local/bin and /usr/local/bin. +# * Removes ~/.local/share/hypercar-colorscripts and ~/.config/hypercar-colorscripts. +# * Backs up and removes ~/.config/fastfetch/hypercar.jsonc. +# * Strips hypercar-managed blocks from ~/.zshrc, ~/.bashrc, ~/.profile +# (backups made first) using a broad marker-regex so legacy variants +# also get cleaned up. +# * Restores any pokemon-colorscripts line the installer commented out +# with the "# hypercar-installer-disabled:" prefix. +# * Leaves ben10-colorscripts's shell block completely untouched. +# * Cleans up stale completion files left by pre-v0.3.2 installs. set -uo pipefail @@ -17,29 +27,26 @@ warn() { echo -e "${YELLOW}⚠${NC} $*"; } DATA_DIR="$HOME/.local/share/hypercar-colorscripts" CONFIG_DIR="$HOME/.config/hypercar-colorscripts" +FF_CONFIG_FILE="$HOME/.config/fastfetch/hypercar.jsonc" BIN_USER="$HOME/.local/bin/hypercar-colorscripts" BIN_SYS="/usr/local/bin/hypercar-colorscripts" -echo -e "${BLUE}═══ hypercar-colorscripts uninstaller ═══${NC}" -echo -echo "What to uninstall?" -echo " 1) Only hypercar-colorscripts (default)" -echo " 2) Both hypercar AND pokemon-colorscripts" -read -rp "Choice [1]: " choice -choice="${choice:-1}" - +echo -e "${BLUE}═══ hypercar-colorscripts uninstaller (v0.1.1) ═══${NC}" echo echo -e "${YELLOW}Will remove:${NC}" echo " - $BIN_USER (if exists)" echo " - $BIN_SYS (if exists)" echo " - $DATA_DIR/" echo " - $CONFIG_DIR/" -echo " - hypercar blocks from ~/.zshrc AND ~/.bashrc (backups made)" -[[ "$choice" == "2" ]] && echo " - pokemon-colorscripts" +echo " - $FF_CONFIG_FILE (backup will be made first)" +echo " - hypercar blocks from ~/.zshrc, ~/.bashrc, ~/.profile (backups made)" +echo +echo "pokemon-colorscripts and ben10-colorscripts (if installed) will NOT be touched." +echo read -rp "Continue? [y/N]: " confirm [[ ! "${confirm:-N}" =~ ^[Yy]$ ]] && { echo "Aborted."; exit 0; } -# ─── Process each rc file ────────────────────── +# ─── Process each rc file ───────────────────────────────────────── for RC in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile"; do [[ -f "$RC" ]] || continue if ! grep -qE "hypercar-colorscripts|hypercar-installer-disabled" "$RC" 2>/dev/null; then @@ -51,36 +58,44 @@ for RC in "$HOME/.zshrc" "$HOME/.bashrc" "$HOME/.profile"; do echo echo "Cleaning $RC (backup: $BACKUP)" - sed -i.tmp '/# >>> hypercar-colorscripts PATH >>>/,/# <<< hypercar-colorscripts PATH <<>> hypercar-colorscripts >>>/,/# <<< hypercar-colorscripts <<>> hypercar-colorscripts.*>>>/,/# <<< hypercar-colorscripts.*<</dev/null || true rm -f "$RC.tmp" ok " Cleaned $RC" done -# ─── Binaries ────────────────────────────────── +# ─── Binaries ───────────────────────────────────────────────────── [[ -f "$BIN_USER" ]] && rm -f "$BIN_USER" && ok "Removed $BIN_USER" if [[ -f "$BIN_SYS" ]]; then if [[ -w "$BIN_SYS" ]]; then rm -f "$BIN_SYS"; else sudo rm -f "$BIN_SYS"; fi ok "Removed $BIN_SYS" fi -# ─── Data + config dirs ──────────────────────── +# ─── Data + config dirs ─────────────────────────────────────────── [[ -d "$DATA_DIR" ]] && rm -rf "$DATA_DIR" && ok "Removed $DATA_DIR" [[ -d "$CONFIG_DIR" ]] && rm -rf "$CONFIG_DIR" && ok "Removed $CONFIG_DIR" -# ─── Cleanup stale completion files from prior versions ──────── -# The completions feature was removed in v0.3.2. If a previous install -# left files behind, clean them up silently. +# ─── fastfetch styling config ───────────────────────────────────── +if [[ -f "$FF_CONFIG_FILE" ]]; then + FF_BACKUP="$FF_CONFIG_FILE.hypercar-uninstall-backup-$(date +%Y%m%d-%H%M%S)" + cp "$FF_CONFIG_FILE" "$FF_BACKUP" + rm -f "$FF_CONFIG_FILE" + ok "Removed $FF_CONFIG_FILE (backup: $FF_BACKUP)" +fi + +# ─── Cleanup stale completion files from prior versions ─────────── for f in "$HOME/.local/share/bash-completion/completions/hypercar-colorscripts" \ "$HOME/.local/share/zsh/site-functions/_hypercar-colorscripts" \ "$HOME/.config/fish/completions/hypercar-colorscripts.fish"; do @@ -90,30 +105,6 @@ for f in "$HOME/.local/share/bash-completion/completions/hypercar-colorscripts" fi done -# ─── Option 2: also uninstall pokemon-colorscripts ─ -if [[ "$choice" == "2" ]] && command -v pokemon-colorscripts >/dev/null 2>&1; then - echo - echo -e "${BLUE}Removing pokemon-colorscripts...${NC}" - P_PATH="$(command -v pokemon-colorscripts)" - if pip show pokemon-colorscripts >/dev/null 2>&1; then - pip uninstall -y pokemon-colorscripts || true - else - if [[ -w "$P_PATH" ]]; then rm -f "$P_PATH"; else sudo rm -f "$P_PATH"; fi - fi - for d in "$HOME/.local/share/pokemon-colorscripts" \ - "/usr/local/share/pokemon-colorscripts" \ - "/usr/share/pokemon-colorscripts" \ - "$HOME/.config/pokemon-colorscripts"; do - if [[ -d "$d" ]]; then - if [[ -w "$d" ]]; then rm -rf "$d"; else sudo rm -rf "$d"; fi - ok "Removed $d" - fi - done - for RC in "$HOME/.zshrc" "$HOME/.bashrc"; do - [[ -f "$RC" ]] && sed -i.tmp '/^pokemon-colorscripts/d' "$RC" && rm -f "$RC.tmp" - done -fi - echo echo -e "${GREEN}═══ Done ═══${NC}" echo "PATH exports and other config preserved."