diff --git a/README.md b/README.md index 0888b2a..0516527 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This repository provides a comprehensive `.bashrc` configuration along with supp ## Table of Contents - [Installation](#installation) +- [Switching Color Palettes](#switching-color-palettes) - [Uninstallation](#uninstallation) - [Configuration Files](#configuration-files) - [.bashrc](#bashrc) @@ -35,7 +36,9 @@ The `setup.sh` script automates the installation process by: - Installing Bash 5 with Homebrew on macOS - Adding Homebrew Bash to `/etc/shells` and setting it as the default login shell on macOS - Installing dependencies (bash-completion, neovim, starship, fzf, zoxide) -- Installing the MesloLGS Nerd Font required for the prompt when available +- Installing Starship and JetBrainsMono Nerd Font on Linux +- Selecting JetBrainsMono Nerd Font in Ptyxis or GNOME Terminal when available +- Installing the MesloLGS Nerd Font required for the prompt on macOS when available - Linking configuration files from `~/.local/share/mybash` to your home directory - Linking the fastfetch config to `~/.config/fastfetch/config.jsonc` - Ensuring `~/.bash_profile` initializes Homebrew on macOS @@ -51,6 +54,20 @@ bash --version `$SHELL` should point to the Homebrew Bash path, such as `/opt/homebrew/bin/bash` on Apple Silicon or `/usr/local/bin/bash` on Intel Macs. On Linux, ensure you have the required permissions and a supported package manager. +## Switching Color Palettes + +Use `starship-theme` to recolor the prompt without changing its layout: + +```bash +starship-theme # interactive picker +starship-theme fedora # apply a palette directly +starship-theme list # list available palettes +``` + +Available palettes include Ubuntu, Claude, Arch, Fedora, Debian, Mint, Manjaro, Pop!_OS, Kali, Gentoo, Dracula, and the original Nord theme. + +![Starship color palettes](assets/palettes.png) + ## Uninstallation To uninstall the `.bashrc` configuration, run: @@ -59,13 +76,18 @@ To uninstall the `.bashrc` configuration, run: cd mybash chmod +x uninstall.sh ./uninstall.sh +./uninstall.sh --keep-deps ``` +Use `--keep-deps` to remove the mybash configuration while retaining installed software and fonts. + The `uninstall.sh` script reverses the installation process by: - Removing installed dependencies - Uninstalling fonts - Removing symbolic links to configuration files +- Restoring the `.bashrc` backup created during installation +- Restoring previous Ptyxis or GNOME Terminal font settings - Deleting the `~/.local/share/mybash` directory - Cleaning up additional utilities like `starship`, `fzf`, and `zoxide` diff --git a/assets/palettes.png b/assets/palettes.png new file mode 100644 index 0000000..a7e4b6b Binary files /dev/null and b/assets/palettes.png differ diff --git a/setup.sh b/setup.sh index 3a050f5..bcf1345 100755 --- a/setup.sh +++ b/setup.sh @@ -5,6 +5,9 @@ set -eu SCRIPT_DIR=$(unset CDPATH && cd -- "$(dirname -- "$0")" && pwd -P) OS_NAME=$(uname -s 2>/dev/null || echo unknown) MYBASHDIR="$HOME/.local/share/mybash" +NERD_FONT_FAMILY="JetBrainsMono Nerd Font" +NERD_FONT_SIZE=12 +NERD_FONT_URL="https://github.com/ryanoasis/nerd-fonts/releases/latest/download/JetBrainsMono.tar.xz" if command -v tput >/dev/null 2>&1 && [ -t 1 ]; then RC=$(tput sgr0) @@ -138,24 +141,24 @@ ensure_homebrew_bash_macos() { install_dependencies_linux() { if command_exists nala; then - sudo_cmd nala install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide + sudo_cmd nala install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide curl fontconfig tar xz-utils elif command_exists apt-get; then sudo_cmd apt-get update - sudo_cmd apt-get install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide + sudo_cmd apt-get install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide curl fontconfig tar xz-utils elif command_exists dnf; then - sudo_cmd dnf install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide + sudo_cmd dnf install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide curl fontconfig tar xz elif command_exists yum; then - sudo_cmd yum install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide + sudo_cmd yum install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide curl fontconfig tar xz elif command_exists pacman; then - sudo_cmd pacman -S --needed bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide + sudo_cmd pacman -S --needed bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide curl fontconfig tar xz elif command_exists zypper; then - sudo_cmd zypper install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide + sudo_cmd zypper install -y bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide curl fontconfig tar xz elif command_exists emerge; then - sudo_cmd emerge --ask=n app-shells/bash-completion sys-apps/bat app-text/tree app-text/multitail app-misc/fastfetch app-editors/neovim app-misc/trash-cli app-shells/fzf app-shells/zoxide + sudo_cmd emerge --ask=n app-shells/bash-completion sys-apps/bat app-text/tree app-text/multitail app-misc/fastfetch app-editors/neovim app-misc/trash-cli app-shells/fzf app-shells/zoxide net-misc/curl media-libs/fontconfig app-arch/tar app-arch/xz-utils elif command_exists xbps-install; then - sudo_cmd xbps-install -Sy bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide + sudo_cmd xbps-install -Sy bash-completion bat tree multitail fastfetch neovim trash-cli fzf zoxide curl fontconfig tar xz elif command_exists nix-env; then - nix-env -iA nixpkgs.bash-completion nixpkgs.bat nixpkgs.tree nixpkgs.multitail nixpkgs.fastfetch nixpkgs.neovim nixpkgs.trash-cli nixpkgs.fzf nixpkgs.zoxide + nix-env -iA nixpkgs.bash-completion nixpkgs.bat nixpkgs.tree nixpkgs.multitail nixpkgs.fastfetch nixpkgs.neovim nixpkgs.trash-cli nixpkgs.fzf nixpkgs.zoxide nixpkgs.curl nixpkgs.fontconfig nixpkgs.gnutar nixpkgs.xz else print_colored "$RED" "Can't find a supported package manager." return 1 @@ -177,6 +180,122 @@ install_dependencies() { esac } +install_starship_linux() { + [ "$OS_NAME" = Linux ] || return 0 + + if command_exists starship; then + return 0 + fi + + print_colored "$YELLOW" "Installing Starship..." + mkdir -p "$HOME/.local/bin" + starship_installer=$(mktemp) + if ! curl -fsSL https://starship.rs/install.sh -o "$starship_installer"; then + rm -f "$starship_installer" + print_colored "$RED" "Failed to download the Starship installer." + return 1 + fi + if ! sh "$starship_installer" -y -b "$HOME/.local/bin"; then + rm -f "$starship_installer" + print_colored "$RED" "Starship installation failed." + return 1 + fi + rm -f "$starship_installer" +} + +install_nerd_font_linux() { + [ "$OS_NAME" = Linux ] || return 0 + + if fc-list 2>/dev/null | grep -qi "$NERD_FONT_FAMILY"; then + return 0 + fi + + print_colored "$YELLOW" "Installing $NERD_FONT_FAMILY..." + font_temp_dir=$(mktemp -d) + font_archive="$font_temp_dir/JetBrainsMono.tar.xz" + font_unpack_dir="$font_temp_dir/unpacked" + font_dir="$HOME/.local/share/fonts/JetBrainsMonoNerdFont" + mkdir -p "$font_unpack_dir" "$font_dir" + + if ! curl -fsSL "$NERD_FONT_URL" -o "$font_archive"; then + rm -rf "$font_temp_dir" + print_colored "$RED" "Failed to download $NERD_FONT_FAMILY." + return 1 + fi + if ! tar -xJf "$font_archive" -C "$font_unpack_dir"; then + rm -rf "$font_temp_dir" + print_colored "$RED" "Failed to extract $NERD_FONT_FAMILY." + return 1 + fi + + find "$font_unpack_dir" -type f -name 'JetBrainsMonoNerdFont-*.ttf' -exec cp {} "$font_dir"/ \; + font_found= + for font_file in "$font_dir"/*.ttf; do + if [ -f "$font_file" ]; then + font_found=1 + break + fi + done + rm -rf "$font_temp_dir" + + if [ -z "$font_found" ]; then + print_colored "$RED" "No standard JetBrainsMono Nerd Font files were found in the archive." + return 1 + fi + + fc-cache -f >/dev/null 2>&1 + print_colored "$GREEN" "$NERD_FONT_FAMILY installed." +} + +configure_terminal_font_linux() { + [ "$OS_NAME" = Linux ] || return 0 + + if ! command_exists gsettings; then + print_colored "$YELLOW" "Set your terminal font to '$NERD_FONT_FAMILY' manually." + return 0 + fi + + terminal_schemas=$(gsettings list-schemas 2>/dev/null || true) + terminal_configured=0 + + if printf '%s\n' "$terminal_schemas" | grep -q '^org.gnome.Ptyxis$'; then + ptyxis_backup="$MYBASHDIR/terminal-font-ptyxis.backup" + if [ ! -f "$ptyxis_backup" ]; then + { + printf 'use-system-font=%s\n' "$(gsettings get org.gnome.Ptyxis use-system-font)" + printf 'font-name=%s\n' "$(gsettings get org.gnome.Ptyxis font-name)" + } >"$ptyxis_backup" + fi + gsettings set org.gnome.Ptyxis use-system-font false + gsettings set org.gnome.Ptyxis font-name "$NERD_FONT_FAMILY $NERD_FONT_SIZE" + terminal_configured=1 + fi + + if printf '%s\n' "$terminal_schemas" | grep -q '^org.gnome.Terminal.ProfilesList$'; then + gnome_profile=$(gsettings get org.gnome.Terminal.ProfilesList default 2>/dev/null | tr -d "'") + if [ -n "$gnome_profile" ]; then + gnome_schema="org.gnome.Terminal.Legacy.Profile:/org/gnome/terminal/legacy/profiles:/:$gnome_profile/" + gnome_backup="$MYBASHDIR/terminal-font-gnome.backup" + if [ ! -f "$gnome_backup" ]; then + { + printf 'profile=%s\n' "$gnome_profile" + printf 'use-system-font=%s\n' "$(gsettings get "$gnome_schema" use-system-font)" + printf 'font=%s\n' "$(gsettings get "$gnome_schema" font)" + } >"$gnome_backup" + fi + gsettings set "$gnome_schema" use-system-font false + gsettings set "$gnome_schema" font "$NERD_FONT_FAMILY $NERD_FONT_SIZE" + terminal_configured=1 + fi + fi + + if [ "$terminal_configured" -eq 1 ]; then + print_colored "$GREEN" "Configured the terminal to use $NERD_FONT_FAMILY." + else + print_colored "$YELLOW" "Set your terminal font to '$NERD_FONT_FAMILY' manually." + fi +} + backup_existing() { target=$1 if [ -e "$target" ] || [ -L "$target" ]; then @@ -250,17 +369,22 @@ install_configs() { cp -p "$SCRIPT_DIR/README.md" "$MYBASHDIR/README.md" cp -p "$SCRIPT_DIR/setup.sh" "$MYBASHDIR/setup.sh" cp -p "$SCRIPT_DIR/uninstall.sh" "$MYBASHDIR/uninstall.sh" - chmod +x "$MYBASHDIR/setup.sh" "$MYBASHDIR/uninstall.sh" + cp -p "$SCRIPT_DIR/starship-theme" "$MYBASHDIR/starship-theme" + chmod +x "$MYBASHDIR/setup.sh" "$MYBASHDIR/uninstall.sh" "$MYBASHDIR/starship-theme" link_file "$MYBASHDIR/.bashrc" "$HOME/.bashrc" link_file "$MYBASHDIR/starship.toml" "$HOME/.config/starship.toml" link_file "$MYBASHDIR/config.jsonc" "$HOME/.config/fastfetch/config.jsonc" + link_file "$MYBASHDIR/starship-theme" "$HOME/.local/bin/starship-theme" ensure_homebrew_bash_macos ensure_bash_profile_brew_shellenv ensure_bash_profile_sources_bashrc } install_dependencies +install_starship_linux +install_nerd_font_linux install_configs +configure_terminal_font_linux print_colored "$GREEN" "Installation complete. Restart your shell or run: source ~/.bashrc" diff --git a/starship-theme b/starship-theme new file mode 100755 index 0000000..845b4af --- /dev/null +++ b/starship-theme @@ -0,0 +1,124 @@ +#!/usr/bin/env bash + +set -euo pipefail + +DEST="${STARSHIP_CONFIG:-$HOME/.config/starship.toml}" +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd -P)" + +SLOTS=(3B4252 434C5E 4C566A 86BBD8 06969A 33658A) + +declare -A THEMES=( + [ubuntu]="772953 E95420 77216F 5E2750 772953 E95420" + [nord]="3B4252 434C5E 4C566A 86BBD8 06969A 33658A" + [arch]="2E3B43 1793D1 0F5E8C 33A4DB 0C4A6E 1793D1" + [fedora]="2B3A67 3C6EB4 294172 51A2DA 1D2D52 3C6EB4" + [debian]="4A0E22 D70A53 A80030 E0467A 6E0024 D70A53" + [mint]="264A20 4E9A06 2E6B08 87CF3E 1C3817 4E9A06" + [manjaro]="123B22 16A085 0E7A5F 35BF5C 0C2D1A 16A085" + [popos]="2B3539 2C7A85 1F5A63 48B9C7 24414A FAA05A" + [claude]="2B2A28 C15F3C 8A4A30 D9A87E 6B4232 C15F3C" + [kali]="12233A 2777FF 17539E 4D8DFF 0E2A5E 2777FF" + [gentoo]="2E2A40 62548E 4A3F73 9B8AC4 39305C 62548E" + [dracula]="6272A4 BD93F9 FF79C6 8BE9FD 50FA7B BD93F9" +) + +ORDER=(ubuntu claude arch fedora debian mint manjaro popos kali gentoo dracula nord) + +error() { + printf 'starship-theme: %s\n' "$*" >&2 +} + +find_base() { + local candidate slot valid + local -a candidates=() + + if [[ -n ${STARSHIP_THEME_BASE:-} ]]; then + candidates+=("$STARSHIP_THEME_BASE") + fi + candidates+=( + "$SCRIPT_DIR/starship.toml" + "$HOME/.local/share/mybash/starship.toml" + ) + + for candidate in "${candidates[@]}"; do + [[ -f $candidate ]] || continue + valid=1 + for slot in "${SLOTS[@]}"; do + if ! grep -q "#$slot" "$candidate"; then + valid=0 + break + fi + done + if ((valid)); then + printf '%s\n' "$candidate" + return 0 + fi + done + + return 1 +} + +list_themes() { + local theme + printf 'Available palettes:\n' + for theme in "${ORDER[@]}"; do + printf ' %s\n' "$theme" + done +} + +apply_theme() { + local name=$1 base temp_file index + local -a colors sed_args + + if [[ -z ${THEMES[$name]+set} ]]; then + error "unknown palette: $name" + list_themes >&2 + return 1 + fi + + base=$(find_base) || { + error "no pristine mybash starship.toml was found" + return 1 + } + read -ra colors <<<"${THEMES[$name]}" + mkdir -p "$(dirname -- "$DEST")" + temp_file=$(mktemp "${DEST}.tmp.XXXXXX") + + for index in "${!SLOTS[@]}"; do + sed_args+=(-e "s/#${SLOTS[$index]}/#${colors[$index]}/g") + done + + if ! sed "${sed_args[@]}" "$base" >"$temp_file"; then + rm -f "$temp_file" + error "failed to build the $name palette" + return 1 + fi + mv -f "$temp_file" "$DEST" + printf 'Applied "%s" palette to %s\n' "$name" "$DEST" +} + +main() { + local choice=${1:-} + + case $choice in + list | -l | --list) + list_themes + ;; + "") + if command -v fzf >/dev/null 2>&1; then + choice=$(printf '%s\n' "${ORDER[@]}" | fzf --prompt='Pick a palette: ' --height=40% --reverse) || return 0 + else + printf 'Pick a palette:\n' + select choice in "${ORDER[@]}"; do + [[ -n $choice ]] && break + done + fi + [[ -n $choice ]] && apply_theme "$choice" + ;; + *) + apply_theme "$choice" + ;; + esac +} + +main "$@" diff --git a/uninstall.sh b/uninstall.sh index c917477..9c46b9a 100755 --- a/uninstall.sh +++ b/uninstall.sh @@ -86,16 +86,16 @@ uninstall_dependencies() { } uninstall_font() { - FONT_NAME="MesloLGS Nerd Font Mono" - FONT_DIR="$HOME/.local/share/fonts/$FONT_NAME" - - if [ -d "$FONT_DIR" ]; then - print_colored "$YELLOW" "Removing font: $FONT_NAME" - rm -rf "$FONT_DIR" - fc-cache -fv - print_colored "$GREEN" "Font removed: $FONT_NAME" - else - print_colored "$YELLOW" "Font not found: $FONT_NAME" + for FONT_DIR in \ + "$HOME/.local/share/fonts/JetBrainsMonoNerdFont" \ + "$HOME/.local/share/fonts/MesloLGS Nerd Font Mono"; do + if [ -d "$FONT_DIR" ]; then + print_colored "$YELLOW" "Removing font directory: $FONT_DIR" + rm -rf "$FONT_DIR" + fi + done + if command_exists fc-cache; then + fc-cache -f >/dev/null 2>&1 || true fi } @@ -131,11 +131,20 @@ remove_configs() { print_colored "$YELLOW" "Removing configuration files..." - # Remove .bashrc symlink and restore backup if it exists + # Remove the managed .bashrc symlink and restore the newest timestamped backup. if [ -L "$USER_HOME/.bashrc" ]; then rm "$USER_HOME/.bashrc" + BASHRC_BACKUP= if [ -f "$USER_HOME/.bashrc.bak" ]; then - mv "$USER_HOME/.bashrc.bak" "$USER_HOME/.bashrc" + BASHRC_BACKUP="$USER_HOME/.bashrc.bak" + fi + for BACKUP_CANDIDATE in "$USER_HOME"/.bashrc.bak.*; do + if [ -f "$BACKUP_CANDIDATE" ]; then + BASHRC_BACKUP=$BACKUP_CANDIDATE + fi + done + if [ -n "$BASHRC_BACKUP" ]; then + mv "$BASHRC_BACKUP" "$USER_HOME/.bashrc" print_colored "$GREEN" "Restored original .bashrc" fi fi @@ -145,10 +154,50 @@ remove_configs() { # Remove fastfetch config rm -f "$USER_HOME/.config/fastfetch/config.jsonc" + rm -f "$USER_HOME/.local/bin/starship-theme" print_colored "$GREEN" "Configuration files removed" } +restore_terminal_font() { + if ! command_exists gsettings; then + return 0 + fi + + FONT_BACKUP_DIR="$USER_HOME/.local/share/mybash" + PTYXIS_BACKUP="$FONT_BACKUP_DIR/terminal-font-ptyxis.backup" + GNOME_BACKUP="$FONT_BACKUP_DIR/terminal-font-gnome.backup" + + if [ -f "$PTYXIS_BACKUP" ]; then + while IFS='=' read -r FONT_KEY FONT_VALUE; do + case $FONT_KEY in + use-system-font | font-name) + gsettings set org.gnome.Ptyxis "$FONT_KEY" "$FONT_VALUE" 2>/dev/null || true + ;; + esac + done <"$PTYXIS_BACKUP" + print_colored "$GREEN" "Restored the previous Ptyxis font settings" + fi + + if [ -f "$GNOME_BACKUP" ]; then + GNOME_PROFILE= + while IFS='=' read -r FONT_KEY FONT_VALUE; do + case $FONT_KEY in + profile) + GNOME_PROFILE=$FONT_VALUE + ;; + use-system-font | font) + if [ -n "$GNOME_PROFILE" ]; then + GNOME_SCHEMA="org.gnome.Terminal.Legacy.Profile:/org/gnome/terminal/legacy/profiles:/:$GNOME_PROFILE/" + gsettings set "$GNOME_SCHEMA" "$FONT_KEY" "$FONT_VALUE" 2>/dev/null || true + fi + ;; + esac + done <"$GNOME_BACKUP" + print_colored "$GREEN" "Restored the previous GNOME Terminal font settings" + fi +} + remove_mybash_data() { if [ -d "$MYBASHDIR" ]; then print_colored "$YELLOW" "Removing mybash data directory..." @@ -157,14 +206,39 @@ remove_mybash_data() { fi } +# Argument parsing +KEEP_DEPS=0 +for ARG in "$@"; do + case $ARG in + --keep-deps) + KEEP_DEPS=1 + ;; + -h | --help) + printf '%s\n' "Usage: ./uninstall.sh [--keep-deps]" + printf '%s\n' "" + printf '%s\n' " --keep-deps Remove mybash configuration but keep installed software and fonts." + exit 0 + ;; + *) + printf 'Unknown option: %s\n' "$ARG" >&2 + exit 2 + ;; + esac +done + # Main execution -determine_package_manager -determine_sudo_command -uninstall_dependencies -uninstall_font -uninstall_starship_and_fzf -uninstall_zoxide +if [ "$KEEP_DEPS" -eq 0 ]; then + determine_package_manager + determine_sudo_command + uninstall_dependencies + uninstall_font + uninstall_starship_and_fzf + uninstall_zoxide +else + print_colored "$YELLOW" "Keeping installed software and fonts." +fi remove_configs +restore_terminal_font remove_mybash_data print_colored "$GREEN" "Uninstallation complete. Please restart your shell for changes to take effect."