#!/usr/bin/env bash # ===================== # Dotfiles Symlinking Script # ===================== # - Symlinks all dotfiles and app configs from the repo to $HOME and $HOME/.config # - Handles device-specific fragments for Hyprland, Waybar, etc. using $DOTFILES_DEVICE and $HOSTNAME # - Idempotent and safe to re-run # - To extend, add new fragment types to the fragment_types array below # ===================== mkdir -p "$HOME/.config" echo "Symlinking dotfiles..." # Get the dotfiles directory (parent of modules directory) SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" DOTFILES_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" # Symlink regular dotfiles (excluding .config directory) for file in $(find "$DOTFILES_DIR" -maxdepth 1 -name ".*"); do [ "$file" = "$DOTFILES_DIR/.git" ] && continue [ "$file" = "$DOTFILES_DIR/.github" ] && continue [ "$file" = "$DOTFILES_DIR/.vscode" ] && continue [ "$file" = "$DOTFILES_DIR/.config" ] && continue # Handle .config separately basefile="$(basename "$file")" if [ -f "$file" ] || [ -d "$file" ]; then ln -sf "$file" "$HOME/$basefile" echo "Linked $basefile" fi done # Symlink .config directory contents CONFIG_DIR="$DOTFILES_DIR/.config" if [ -d "$CONFIG_DIR" ]; then echo "Symlinking .config contents..." for item in "$CONFIG_DIR"/*; do [ -e "$item" ] || continue baseitem="$(basename "$item")" target_dir="$HOME/.config/$baseitem" # Remove only if it's a symlink or a directory we manage if [ -L "$target_dir" ]; then rm "$target_dir" elif [ -d "$target_dir" ] && [ ! -L "$target_dir" ]; then # Only remove if the directory is empty or matches our repo if [ -z "$(ls -A "$target_dir" 2>/dev/null)" ]; then rm -rf "$target_dir" else echo "Warning: $target_dir is a non-empty directory. Not removed." fi fi ln -sf "$item" "$target_dir" echo "Linked .config/$baseitem" done # ===================== # Device-specific symlinks for Hyprland and Waybar # ===================== # This section handles device-specific config fragments for Hyprland, Waybar, etc. # Uses $DOTFILES_DEVICE (set by setup.sh) and $HOSTNAME for profile-specific fragments. # To add new device types (e.g., tablet, server), update host-profiles.conf and add fragments. # To add new fragment types, extend the fragment_types array below. # Format: "source_fragment_path:target_symlink_path" # Example: fragment_types=( # "hypr/includes/monitors-$HOSTNAME.conf:hypr/includes/monitors.conf" # "hypr/includes/hypridle-$DOTFILES_DEVICE.conf:hypr/hypridle.conf" # "waybar/config-$DOTFILES_DEVICE:waybar/config" # ) if [ -z "$DOTFILES_DEVICE" ]; then echo "ERROR: DOTFILES_DEVICE environment variable not set. Run setup.sh to detect device profile." exit 1 fi HOSTNAME=$(hostname) # Device-specific fragments to symlink (source:target) fragment_types=( "hypr/includes/monitors-$HOSTNAME.conf:hypr/includes/monitors.conf" # Monitor layout per host "hypr/includes/hypridle-$DOTFILES_DEVICE.conf:hypr/hypridle.conf" # Idle config per device type "waybar/config-$DOTFILES_DEVICE:waybar/config" # Waybar config per device type ) # Symlink each device-specific fragment for fragment in "${fragment_types[@]}"; do src="${CONFIG_DIR}/${fragment%%:*}" tgt="${CONFIG_DIR}/${fragment##*:}" if [ -f "$src" ]; then ln -sf "$src" "$tgt" echo "Linked $(basename "$src") as $(basename "$tgt")" else echo "Warning: Device-specific fragment missing: $src" # To troubleshoot, ensure the fragment exists for your device/host fi done # ===================== # End device-specific symlinking # ===================== fi echo "=====================" echo "Dotfiles symlinking complete!" echo "=====================" # Symlink .local/bin scripts LOCAL_BIN_REPO="$DOTFILES_DIR/.local/bin" LOCAL_BIN_HOME="$HOME/.local/bin" if [ -d "$LOCAL_BIN_REPO" ]; then mkdir -p "$LOCAL_BIN_HOME" echo "Symlinking .local/bin scripts..." for script in "$LOCAL_BIN_REPO"/*; do [ -e "$script" ] || continue base_script="$(basename "$script")" ln -sf "$script" "$LOCAL_BIN_HOME/$base_script" echo "Linked .local/bin/$base_script" done fi