#!/usr/bin/env bash set -euo pipefail REPO_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" BACKUP_DIR="${BACKUP_DIR:-$HOME/.dotfiles-backup/$(date +%Y%m%d-%H%M%S)}" ORIGINAL_HOME="/home/pascal" CONFIG_ITEMS=( hypr waybar wofi swaync kitty gtk-3.0 gtk-4.0 qt5ct qt6ct ) PACMAN_PACKAGES=( hyprland hyprpaper hyprlock waybar wofi swaync kitty nautilus ags brightnessctl playerctl wireplumber pipewire pipewire-pulse networkmanager bluez bluez-utils hyprshot grim slurp swappy wl-clipboard libnotify sshpass papirus-icon-theme qt5ct qt6ct starship python-gobject gtk3 gtk4 noto-fonts noto-fonts-emoji ttf-jetbrains-mono-nerd ) SKIP_PACKAGES=0 WITH_SDDM=0 NO_APPLY_THEME=0 usage() { printf '%s\n' \ "Usage: ./install.sh [--skip-packages] [--with-sddm] [--no-apply-theme]" \ "" \ " --skip-packages Only install dotfiles, do not install packages." \ " --with-sddm Install the bundled SDDM theme system-wide." \ " --no-apply-theme Do not run the Hypr theme script after copying." } for arg in "$@"; do case "$arg" in --skip-packages) SKIP_PACKAGES=1 ;; --with-sddm) WITH_SDDM=1 ;; --no-apply-theme) NO_APPLY_THEME=1 ;; -h|--help) usage; exit 0 ;; *) printf 'Unknown option: %s\n' "$arg" >&2; usage; exit 2 ;; esac done log() { printf '\033[1;32m==>\033[0m %s\n' "$1" } warn() { printf '\033[1;33mWARN:\033[0m %s\n' "$1" >&2 } have() { command -v "$1" >/dev/null 2>&1 } backup_path() { local target="$1" [[ -e "$target" || -L "$target" ]] || return 0 local relative="${target#"$HOME"/}" local backup="$BACKUP_DIR/$relative" mkdir -p "$(dirname "$backup")" cp -a "$target" "$backup" } install_path() { local source="$1" local target="$2" backup_path "$target" rm -rf "$target" mkdir -p "$(dirname "$target")" cp -a "$source" "$target" } install_packages() { if (( SKIP_PACKAGES )); then log "Skipping package installation." return fi if ! have pacman; then warn "pacman not found; skipping package installation." return fi log "Installing available pacman packages." local installable=() local missing=() local pkg for pkg in "${PACMAN_PACKAGES[@]}"; do if pacman -Si "$pkg" >/dev/null 2>&1; then installable+=("$pkg") else missing+=("$pkg") fi done if ((${#installable[@]})); then sudo pacman -S --needed "${installable[@]}" fi if ((${#missing[@]})); then if have paru; then log "Trying missing packages through paru: ${missing[*]}" paru -S --needed "${missing[@]}" || warn "Some optional AUR packages were not installed." elif have yay; then log "Trying missing packages through yay: ${missing[*]}" yay -S --needed "${missing[@]}" || warn "Some optional AUR packages were not installed." else warn "Missing from pacman and no paru/yay found: ${missing[*]}" fi fi } rewrite_home_paths() { log "Rewriting absolute home paths." local file while IFS= read -r -d '' file; do sed -i "s#${ORIGINAL_HOME}#${HOME}#g" "$file" done < <( find "$HOME/.config/hypr" "$HOME/.config/gtk-3.0" "$HOME/.config/gtk-4.0" \ "$HOME/.config/qt5ct" "$HOME/.config/qt6ct" \ -type f -print0 2>/dev/null ) } install_dotfiles() { log "Installing dotfiles with backup at $BACKUP_DIR." mkdir -p "$HOME/.config" local item for item in "${CONFIG_ITEMS[@]}"; do install_path "$REPO_DIR/config/$item" "$HOME/.config/$item" done install_path "$REPO_DIR/config/starship.toml" "$HOME/.config/starship.toml" install_path "$REPO_DIR/home/Bilder/Wallpaper" "$HOME/Bilder/Wallpaper" chmod +x "$HOME/.config/hypr"/Scripts/*.sh chmod +x "$HOME/.config/hypr"/Scripts/*.py chmod +x "$HOME/.config/waybar"/scripts/*.sh 2>/dev/null || true rewrite_home_paths } install_sddm() { (( WITH_SDDM )) || return 0 log "Installing SDDM theme." sudo mkdir -p /usr/share/sddm/themes /etc/sddm.conf.d sudo cp -a "$REPO_DIR/config/hypr/sddm-theme/pascal-hypr" /usr/share/sddm/themes/ sudo cp -a "$REPO_DIR/config/hypr/sddm-theme/sddm.conf" /etc/sddm.conf.d/10-pascal-hypr.conf } enable_services() { if have systemctl; then sudo systemctl enable --now NetworkManager.service >/dev/null 2>&1 || true sudo systemctl enable --now bluetooth.service >/dev/null 2>&1 || true fi } apply_theme() { (( NO_APPLY_THEME )) && return 0 local theme="$HOME/.config/hypr/Themes/rose-night.theme" [[ -f "$theme" ]] || theme="$HOME/.config/hypr/Themes/forest-neon.theme" [[ -f "$theme" ]] || return 0 log "Applying theme: $(basename "$theme")" "$HOME/.config/hypr/Scripts/theme-menu.sh" --apply "$theme" || warn "Theme apply failed; dotfiles are still installed." } main() { install_packages install_dotfiles install_sddm enable_services apply_theme log "Done. Start Hyprland or reload with: hyprctl reload" } main "$@"