#!/usr/bin/env bash # 30-shell-zsh — zsh + oh-my-zsh + plugins, set as default shell, drop our config. step_name="shell-zsh" step_desc="zsh + oh-my-zsh + plugins, set default shell, ship config" step_run="run_zsh" ZSH="${ZSH:-$HOME/.oh-my-zsh}" ZSH_CUSTOM="${ZSH_CUSTOM:-$ZSH/custom}" ZDOTDIR_TARGET="${ZDOTDIR_TARGET:-$HOME/.config/zsh}" run_zsh() { log "installing zsh + oh-my-zsh" _install_zsh _install_omz _install_plugins _ship_config _set_default_shell ok "zsh ready — start it with: exec zsh" } _install_zsh() { if command -v zsh >/dev/null 2>&1; then ok "zsh already installed"; return; fi case "$DISTRO" in arch) sudo_ pacman -Sy --noconfirm --needed zsh ;; debian) sudo_ apt-get install -y zsh ;; esac } _install_omz() { if [[ -d "$ZSH/.git" ]]; then ok "oh-my-zsh already present"; return; fi # clone directly (skip the upstream installer so we keep .zshrc under our control) rm -rf "$ZSH" git clone --depth=1 https://github.com/ohmyzsh/ohmyzsh.git "$ZSH" ok "oh-my-zsh cloned to $ZSH" } _install_plugins() { mkdir -p "$ZSH_CUSTOM/plugins" _clone_plugin zsh-users/zsh-autosuggestions "$ZSH_CUSTOM/plugins/zsh-autosuggestions" _clone_plugin zsh-users/zsh-syntax-highlighting "$ZSH_CUSTOM/plugins/zsh-syntax-highlighting" _clone_plugin zsh-users/zsh-completions "$ZSH_CUSTOM/plugins/zsh-completions" _clone_plugin Aloofenlore/history-substring-search "$ZSH_CUSTOM/plugins/history-substring-search" _clone_plugin Aloof98/fzf-tab "$ZSH_CUSTOM/plugins/fzf-tab" } _clone_plugin() { # repo dest local repo="$1" dest="$2" if [[ -d "$dest/.git" ]]; then return; fi git clone --depth=1 "https://github.com/$repo.git" "$dest" \ || warn "failed to clone $repo" } _ship_config() { log "shipping zsh config to $ZDOTDIR_TARGET" mkdir -p "$ZDOTDIR_TARGET" local f local f for f in zshrc aliases.zsh functions.zsh path.zsh plugins.zsh; do local src="$BOOT_DIR/config/zsh/$f" [[ -f "$src" ]] || continue local dst="$ZDOTDIR_TARGET/$f" [[ -f "$dst" ]] && cp "$dst" "${dst}.bak.$(date +%Y%m%d-%H%M%S)" cp "$src" "$dst" done # aliases-extras.zsh is user-owned: only seed it if absent if [[ ! -f "$ZDOTDIR_TARGET/aliases-extras.zsh" ]]; then cp "$BOOT_DIR/config/zsh/aliases-extras.zsh" "$ZDOTDIR_TARGET/aliases-extras.zsh" fi # ~/.zshrc shim that loads our real config via ZDOTDIR (so omz $ZSH + plugins resolve) local shim="$HOME/.zshrc" if ! grep -q 'BOOTSTRAP ZDOTDIR' "$shim" 2>/dev/null; then cat >> "$shim" <<'EOF' # BOOTSTRAP ZDOTDIR — real config lives in ~/.config/zsh export ZDOTDIR="${ZDOTDIR:-$HOME/.config/zsh}" [[ -f "$ZDOTDIR/zshrc" ]] && source "$ZDOTDIR/zshrc" EOF fi ok "zsh config installed ($ZDOTDIR_TARGET) + ~/.zshrc shim" } _set_default_shell() { local zsh_bin; zsh_bin="$(command -v zsh || true)" [[ -z "$zsh_bin" ]] && { warn "zsh not on PATH — skipping chsh"; return; } # ensure listed in /etc/shells if ! grep -qx "$zsh_bin" /etc/shells 2>/dev/null; then echo "$zsh_bin" | sudo_ tee -a /etc/shells >/dev/null fi if [[ "$SHELL" != "$zsh_bin" ]] && [[ "$(getent passwd "$USER" | cut -d: -f7)" != "$zsh_bin" ]]; then if yn "Set zsh as default login shell for $USER?" y; then sudo_ chsh -s "$zsh_bin" "$USER" && ok "default shell set to zsh" else warn "zsh not set as default — run 'chsh -s $zsh_bin' later" fi else ok "zsh already your default shell" fi }