From 9f54745832596dde0c47ff69e108ebedf8f19234 Mon Sep 17 00:00:00 2001 From: mk Date: Tue, 28 Jul 2026 04:32:38 +0300 Subject: [PATCH] modules: zsh+omz+plugins, nvm+node LTS, nvim-minimal config clone --- modules/30-shell-zsh.sh | 99 +++++++++++++++++++++++++++++++++++++++++ modules/35-nvm.sh | 31 +++++++++++++ modules/40-nvim.sh | 34 ++++++++++++++ 3 files changed, 164 insertions(+) create mode 100755 modules/30-shell-zsh.sh create mode 100755 modules/35-nvm.sh create mode 100755 modules/40-nvim.sh diff --git a/modules/30-shell-zsh.sh b/modules/30-shell-zsh.sh new file mode 100755 index 0000000..56fcf66 --- /dev/null +++ b/modules/30-shell-zsh.sh @@ -0,0 +1,99 @@ +#!/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 +} \ No newline at end of file diff --git a/modules/35-nvm.sh b/modules/35-nvm.sh new file mode 100755 index 0000000..4a373e4 --- /dev/null +++ b/modules/35-nvm.sh @@ -0,0 +1,31 @@ +#!/usr/bin/env bash +# 35-nvm — Node Version Manager + Node LTS. + +step_name="nvm" +step_desc="nvm into ~/.nvm, install Node LTS" +step_run="run_nvm" + +run_nvm() { + log "installing nvm" + export NVM_DIR="${NVM_DIR:-$HOME/.nvm}" + if [[ -s "$NVM_DIR/nvm.sh" ]]; then + ok "nvm already present at $NVM_DIR" + else + # fetch the install script at a pinned NVM version (update here to upgrade) + curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash \ + || { warn "nvm install failed"; return; } + ok "nvm installed to $NVM_DIR" + fi + + # shellcheck disable=SC1091 + source "$NVM_DIR/nvm.sh" + if command -v nvm >/dev/null 2>&1; then + log "installing Node LTS via nvm" + nvm install --lts || warn "nvm install --lts failed" + nvm use --lts 2>/dev/null || true + nvm alias default 'lts/*' 2>/dev/null || true + command -v node >/dev/null 2>&1 && ok "node $(node -v) active" + else + warn "nvm.sh sourced but nvm not available — check $NVM_DIR" + fi +} \ No newline at end of file diff --git a/modules/40-nvim.sh b/modules/40-nvim.sh new file mode 100755 index 0000000..1dceb30 --- /dev/null +++ b/modules/40-nvim.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +# 40-nvim — clone your nvim-minimal config from gitea to ~/.config/nvim. + +step_name="nvim" +step_desc="clone g.mk.fo/bootstrap/nvim-minimal -> ~/.config/nvim" +step_run="run_nvim" + +NVIM_REPO_URL="${NVIM_REPO_URL:-https://g.mk.fo/bootstrap/nvim-minimal.git}" + +run_nvim() { + log "installing nvim config" + command -v nvim >/dev/null 2>&1 || warn "nvim binary not found — install the packages step first" + + local target="${XDG_CONFIG_HOME:-$HOME/.config}/nvim" + if [[ -d "$target/.git" ]]; then + log "existing nvim config is a git repo — pulling" + git -C "$target" pull --ff-only || warn "could not pull existing nvim config" + ok "nvim config updated at $target" + return + fi + + if [[ -e "$target" ]]; then + local bak="${target}.bak.$(date +%Y%m%d-%H%M%S)" + mv "$target" "$bak" + warn "backed up existing $target -> $bak" + fi + + if git clone "$NVIM_REPO_URL" "$target"; then + ok "nvim config cloned to $target" + else + err "failed to clone $NVIM_REPO_URL" + return 1 + fi +} \ No newline at end of file