Files
owen 5c57ee20f7 Add Arch Wayland dotfiles: sway/waybar/kitty/nvim/zsh, idempotent installer
Auto-adapts sway workspace routing to however many monitors are
connected (laptop vs. desktop) instead of hardcoding output names.
2026-08-21 22:59:26 -05:00

120 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -Eeuo pipefail
DOTFILES_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
BACKUP_ROOT="${HOME}/.dotfiles-backup/$(date +%Y%m%d-%H%M%S)"
INSTALL_PACKAGES=true
DRY_RUN=false
PACKAGES=(
sway swaybg swaylock waybar wofi kitty jq curl btop
greetd greetd-tuigreet
zsh neovim git base-devel
grim slurp wl-clipboard mako libnotify brightnessctl playerctl
pipewire pipewire-pulse wireplumber pavucontrol
network-manager-applet polkit-gnome xdg-desktop-portal-wlr
noto-fonts noto-fonts-emoji ttf-jetbrains-mono-nerd
)
usage() {
cat <<'EOF'
Usage: ./install.sh [--no-packages] [--dry-run] [--help]
--no-packages Skip pacman package installation
--dry-run Print actions without changing anything
--help Show this help
EOF
}
log() { printf '\033[1;34m==>\033[0m %s\n' "$*"; }
run() {
if "$DRY_RUN"; then printf ' '; printf '%q ' "$@"; printf '\n';
else "$@"; fi
}
while (($#)); do
case "$1" in
--no-packages) INSTALL_PACKAGES=false ;;
--dry-run) DRY_RUN=true ;;
--help|-h) usage; exit 0 ;;
*) printf 'Unknown option: %s\n' "$1" >&2; usage >&2; exit 2 ;;
esac
shift
done
link_path() {
local source=$1 target=$2 relative backup
if [[ -L "$target" && "$(readlink -f -- "$target")" == "$(readlink -f -- "$source")" ]]; then
log "Already linked: $target"
return
fi
if [[ -e "$target" || -L "$target" ]]; then
relative=${target#"${HOME}/"}
backup="${BACKUP_ROOT}/${relative}"
log "Backing up $target -> $backup"
run mkdir -p -- "$(dirname -- "$backup")"
run mv -- "$target" "$backup"
fi
run mkdir -p -- "$(dirname -- "$target")"
log "Linking $target -> $source"
run ln -s -- "$source" "$target"
}
install_system_file() {
local source=$1 target=$2 relative backup
if [[ -r "$target" ]] && cmp -s -- "$source" "$target"; then
log "Already installed: $target"
return
fi
if [[ -e "$target" ]]; then
relative=${target#/}
backup="${BACKUP_ROOT}/${relative}"
log "Backing up $target -> $backup"
run mkdir -p -- "$(dirname -- "$backup")"
run sudo cp -- "$target" "$backup"
fi
log "Installing $target"
run sudo install -Dm644 -- "$source" "$target"
}
if "$INSTALL_PACKAGES"; then
command -v pacman >/dev/null || { echo 'pacman was not found; use --no-packages on non-Arch systems.' >&2; exit 1; }
log "Installing Arch packages"
run sudo pacman -Syu --needed "${PACKAGES[@]}"
if ! command -v yay >/dev/null; then
log "Installing yay from the AUR"
if "$DRY_RUN"; then
printf ' git clone https://aur.archlinux.org/yay.git <temporary-directory>/yay\n'
printf ' cd <temporary-directory>/yay && makepkg -si --noconfirm\n'
else
YAY_BUILD_DIR=$(mktemp -d)
git clone https://aur.archlinux.org/yay.git "$YAY_BUILD_DIR/yay"
(
cd "$YAY_BUILD_DIR/yay"
makepkg -si --noconfirm
)
rm -rf -- "$YAY_BUILD_DIR"
unset YAY_BUILD_DIR
fi
fi
install_system_file "$DOTFILES_DIR/system/greetd/config.toml" /etc/greetd/config.toml
log "Enabling greetd"
run sudo systemctl enable greetd.service
fi
for source in "$DOTFILES_DIR"/config/*; do
[[ -e "$source" ]] || continue
link_path "$source" "$HOME/.config/$(basename -- "$source")"
done
for source in "$DOTFILES_DIR"/home/.[!.]* "$DOTFILES_DIR"/home/..?*; do
[[ -e "$source" ]] || continue
link_path "$source" "$HOME/$(basename -- "$source")"
done
if [[ "${SHELL:-}" != */zsh ]]; then
log "Zsh is installed. Run 'chsh -s /bin/zsh' to make it your login shell."
fi
log "Installation complete. Reload Sway with Alt+Shift+r."